I have view pager. My viewpager contains 3 fragments. In the first fragment I have an AsyncTask class. I parsed JSON with AsyncTask and I can show it in listview. (everything is ok)
I have one problem AsyncTask which I have in the first fragment does not finish when I go to the next fragments. When I am in the second fragment my AsyncTask is also running. How can I write code to cancel my AsyncTask when viewpager's page changed?
This is my source (this is the first fragment source; another fragment source is the same but the only difference is the Server Url):
public class StradaChefs1 extends Fragment {
public static CustomerStatistic stat;
private ConnectionDetector con;
private AlertDialogManager alert = new AlertDialogManager();
@SuppressLint("ClickableViewAccessibility")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.strada_chefs_1, container,
false);
stat = new CustomerStatistic();
con = new ConnectionDetector(getActivity());
if (!con.isConnectingToInternet()) {
alert.showAlertDialog(getActivity(),
"You have not internet connection");
} else {
stat.execute("my urlllllllll"); // geo
}
return rootView;
}
public class CustomerStatistic extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = ProgressDialog.show(getActivity(), "Please Wait... ",
"Loading... ");
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected String doInBackground(String... params) {
return Utils.getJSONString(params[0]);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONArray mainJson = new JSONArray(result);
String first = mainJson.getString(0);
JSONObject jobject = new JSONObject(first);
String image = jobject.getString("image");
String String_title = jobject.getString("title");
String String_name = jobject.getString("name");
String String_desc = jobject.getString("description");
String second = mainJson.getString(1);
} catch (JSONException e) {
e.printStackTrace();
}
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of HomeFragment");
super.onResume();
}
@Override
public void onStop() {
super.onStop();
if (stat != null && stat.equals(AsyncTask.Status.RUNNING)) {
stat.cancel(true);
Toast.makeText(getActivity(), "finished", Toast.LENGTH_SHORT)
.show();
}
}
}
This is a viewpager java code
public class TabbedActivity1 extends Fragment {
private StradaChefs1 mfragment1;
private StradaChefs2 mfragment2;
private StradaChefs3 mfragment3;
private StradaChefs4 mfragment4;
SectionsPagerAdapter mSe;
public static final String TAG = TabbedActivity1.class.getSimpleName();
ViewPager mViewPager;
private ArrayList<Fragment> fragmentList;
public static TabbedActivity1 newInstance() {
return new TabbedActivity1();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_item_one_1, container, false);
mSe=new SectionsPagerAdapter(getChildFragmentManager());
mViewPager = (ViewPager) v.findViewById(R.id.pager1);
CirclePageIndicator circle=(CirclePageIndicator)v.findViewById(R.id.circleindicator1);
mViewPager.setAdapter(mSe);
circle.setViewPager(mViewPager);
mfragment1 = new StradaChefs1();
mfragment2 = new StradaChefs2();
mfragment3 = new StradaChefs3();
mfragment4 = new StradaChefs4();
fragmentList = new ArrayList<Fragment>();
fragmentList.add(mfragment1);
fragmentList.add(mfragment2);
fragmentList.add(mfragment3);
fragmentList.add(mfragment4);
mViewPager.setPageTransformer(false, new PageTransformer() {
@Override
public void transformPage(View page, float position) {
page.setRotationY(position * -40);
}
});
return v;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return 4;
}
@Override
public CharSequence getPageTitle(int position) {
return null;
}
}
}
How can I solve this problem?
The FragmentPagerAdapter keeps additional fragments, besides the one shown, in resumed state, so you can't use onPause
and onResume
for starting/stopping the AsyncTask
. The solution is to implement a custom OnPageChangeListener
and create a new method for when the fragment is shown.
1) Create LifecycleManager
Interface The interface will have two methods and each ViewPager’s Fragment will implement it. These methods Are as follows:
public interface FragmentLifecycle {
public void onPauseFragment();
public void onResumeFragment();
}
2) Let each Fragment implement the interface
3) Implement interface methods in each fragment - in onPauseFragment
stop the AsyncTask
, in onResumeFragment
start it
4) Call interface methods on ViewPager page change You can set OnPageChangeListener on ViewPager and get callback each time when ViewPager shows another page
5) Implement OnPageChangeListener
to call your custom Lifecycle methods
Listener knows the new position and can call the interface method on new Fragment with the help of PagerAdapter
. I can here call onResumeFragment()
for new fragment and onPauseFragment()
on the current one.
I need to store also the current fragment’s position (initially the current position is equal to 0), since I don’t know whether the user scrolled from left to right or from right to left. See what I mean in code:
private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
int currentPosition = 0;
@Override
public void onPageSelected(int newPosition) {
FragmentLifecycle fragmentToShow = (FragmentLifecycle)pageAdapter.getItem(newPosition);
fragmentToShow.onResumeFragment();
FragmentLifecycle fragmentToHide = (FragmentLifecycle)pageAdapter.getItem(currentPosition);
fragmentToHide.onPauseFragment();
currentPosition = newPosition;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) { }
public void onPageScrollStateChanged(int arg0) { }
};
I didn't write the code. Full tutorial here