是否可以在构造函数中传递片段?

时间:2012-03-30 06:41:48

标签: android android-fragments

我正在尝试将Fragment传递给ASyncTask类,以便在任务完成后我可以更新片段中的一个或两个小部件。这就是我正在处理的事情:

public class LoginFragment extends Fragment {

    Button loginButton;
    TextView loginErrorMsg;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.loginfragment, container, false);
    }

    public OnClickListener loginListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.v("LoginF", "onclick");
            ProgressDialog progressDialog = new ProgressDialog(getActivity());
            progressDialog.setMessage("Logging in...");
            LoginTask loginTask = new LoginTask((Polling) getActivity(), progressDialog);
            loginTask.execute();
        }
    };

LoginTask:

public class LoginTask extends AsyncTask<String, Void, Integer> {

private ProgressDialog progressDialog;
private Polling activity;
private int id = -1;
private JSONParser jsonParser;
private static String loginURL = "http://davidjkelley.net/android_api/";
private static String registerURL = "http://davidjkelley.net/android_api/";
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";
TextView loginErrorMsg = (EditText)activity.findViewById(R.id.loginErrorMsg);
EditText userName = (EditText)activity.findViewById(R.id.emailEditText);
EditText passwordEdit = (EditText)activity.findViewById(R.id.passEditText);

public LoginTask(Polling activity, ProgressDialog progressDialog)
{
    this.activity = activity;
    this.progressDialog = progressDialog;
}

所以我想在LoginTask的构造函数中添加第三个参数,本质上是我的LoginFragment的一个实例。我的目标是更新TextView或在屏幕上显示Toast以澄清登录是成功还是失败:现在,用户无法告知登录是如何进行的。想法?

2 个答案:

答案 0 :(得分:4)

好奇地说你不想传递碎片(它们与活动的“链接”是一个上下文并且传递上下文是baaad)

您希望传递一个小对象,可以帮助您从任务回调到片段。

我也会使用界面。这是我的例子:

片段:

public class LoginFragment extends Fragment implements OnClickListener, OnLoginListener{

    Button loginButton;
    TextView loginErrorMsg;
    private ProgressDialog progressDialog;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        progressDialog = new ProgressDialog(activity);
        progressDialog.setMessage("Logging in...");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_login, container, false);

        loginButton = v.findViewById(R.id.button);
        loginButton.setOnClickListener(this);

        return v;

    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
        case R.id.button:
            Log.v("LoginF", "onclick");
            progressDialog.show();
            LoginTask loginTask = new LoginTask(this);
            loginTask.execute();
            break;
        default:
            break;
        }
    }

    @Override
    public void onLoginSuccess() {
        progressDialog.dismiss();
        // Yayy
    }

    @Override
    public void onLoginFailure() {
        progressDialog.dismiss();
        // Boo
    }
}

ASyncTask:

public class LoginTask extends AsyncTask<String, Void, Integer> {

    private final OnLoginListener listener;

    public interface OnLoginListener{
        public void onLoginSuccess();
        public void onLoginFailure();
    }

    public LoginTask(OnLoginListener listener) {
        this.listener = listener;
    }

    @Override
    protected Integer doInBackground(String... params) {
        try{
            // Something
        } catch (SomeException e){
            listener.onLoginFailure();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
        listener.onLoginSuccess();
    }

}

如果您了解界面,您的世界将会开放,您的代码将看起来不像亚马逊丛林,更像是一个组织良好的花园; - )

答案 1 :(得分:1)

我建议您使用Callback接口来实现此目的。将特定于UI的(实际上是特定于上下文的)对象传递给AsyncTask通常不是一个好主意。

这是我的建议。使用这种方法,您甚至不需要传递Fragment左右。

免责声明:我实际上没有尝试过运行此代码 - 只需将其输入我的脑海。所以它甚至可能无法编译 - 它只是作为指南。

interface LoginCallback{
    void onLoginSuccess();
    void onLoginFailure();
}


//onCreate code
TextView loginErrorMsg = (EditText)activity.findViewById(R.id.loginErrorMsg);
EditText userName = (EditText)activity.findViewById(R.id.emailEditText);
EditText passwordEdit = (EditText)activity.findViewById(R.id.passEditText);


LoginTask loginTask = new LoginTask(new LoginCallback(){
    @Override
    protected void onLoginSuccess(){
        //Update UI
    }

        @Override
    protected void onLoginFailure(){
        //Update UI
    }
});

loginTask.execute();



//LoginTask code.
public class LoginTask extends AsyncTask<String, Void, Integer> {
    LoginCallback callback;
    ProgressDialog progressDialog;

    public LoginTask(LoginCallback callback){
        this.callback = callback;


        @Override protected void onPreExecute(){
            progressDialog = new ProgressDialog(getActivity());
            progressDialog.setMessage("Logging in...");

        }

        @Override
        protected Integer doInBackground(String... params){
           //Do you login logic here.

        }

        @Override
        protected void onPostExecute(Integer result) {
           progressDialog.dismiss();
           if(loginSuccess){
                callback.onLoginSuccess();
           } else {
                callback.onLoginFailure();
           }
        }
    }
}