Is It Possible To Pass A Fragment In A Constructor?
Solution 1:
As curious says you don't want to be passing Fragments around (they have a 'link' to the activity which is a context and passing contexts is baaad)
You want to pass a small object that can help you call back from your Task to your Fragment.
I would also use an interface. Here's my example:
Fragment:
publicclassLoginFragmentextendsFragmentimplementsOnClickListener, OnLoginListener{
Button loginButton;
TextView loginErrorMsg;
privateProgressDialog progressDialog;
@OverridepublicvoidonAttach(Activity activity) {
super.onAttach(activity);
progressDialog = newProgressDialog(activity);
progressDialog.setMessage("Logging in...");
}
@OverridepublicViewonCreateView(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;
}
@OverridepublicvoidonClick(View v) {
switch(v.getId()){
case R.id.button:
Log.v("LoginF", "onclick");
progressDialog.show();
LoginTask loginTask = newLoginTask(this);
loginTask.execute();
break;
default:
break;
}
}
@OverridepublicvoidonLoginSuccess() {
progressDialog.dismiss();
// Yayy
}
@OverridepublicvoidonLoginFailure() {
progressDialog.dismiss();
// Boo
}
}
The ASyncTask:
publicclassLoginTaskextendsAsyncTask<String, Void, Integer> {
privatefinal OnLoginListener listener;
publicinterfaceOnLoginListener{
publicvoidonLoginSuccess();
publicvoidonLoginFailure();
}
publicLoginTask(OnLoginListener listener) {
this.listener = listener;
}
@Overrideprotected Integer doInBackground(String... params) {
try{
// Something
} catch (SomeException e){
listener.onLoginFailure();
}
returnnull;
}
@OverrideprotectedvoidonPostExecute(Integer result) {
super.onPostExecute(result);
listener.onLoginSuccess();
}
}
If you get your head around interfaces your world will open up and your code will look less like the amazon jungle and more like a well organised garden ;-)
Solution 2:
I suggest you use a Callback interface for this purpose. It is generally not a good idea to pass in UI-specific (actually, context-specific) objects to an AsyncTask.
Here's what I suggest. With this approach, you don't even need to pass in your Fragment
around.
Disclaimer: I have not actually tried running this code - just typed it off the top of my head. So it may not even compile - it is just intended to be a guide.
interfaceLoginCallback{
voidonLoginSuccess();
voidonLoginFailure();
}
//onCreate codeTextViewloginErrorMsg= (EditText)activity.findViewById(R.id.loginErrorMsg);
EditTextuserName= (EditText)activity.findViewById(R.id.emailEditText);
EditTextpasswordEdit= (EditText)activity.findViewById(R.id.passEditText);
LoginTaskloginTask=newLoginTask(newLoginCallback(){
@OverrideprotectedvoidonLoginSuccess(){
//Update UI
}
@OverrideprotectedvoidonLoginFailure(){
//Update UI
}
});
loginTask.execute();
//LoginTask code.publicclassLoginTaskextendsAsyncTask<String, Void, Integer> {
LoginCallback callback;
ProgressDialog progressDialog;
publicLoginTask(LoginCallback callback){
this.callback = callback;
@OverrideprotectedvoidonPreExecute(){
progressDialog = newProgressDialog(getActivity());
progressDialog.setMessage("Logging in...");
}
@Overrideprotected Integer doInBackground(String... params){
//Do you login logic here.
}
@OverrideprotectedvoidonPostExecute(Integer result) {
progressDialog.dismiss();
if(loginSuccess){
callback.onLoginSuccess();
} else {
callback.onLoginFailure();
}
}
}
}
Post a Comment for "Is It Possible To Pass A Fragment In A Constructor?"