Как обрабатывать AsyncTask во фрагментах ActionBarActivity при использовании ViewPager?
Я использую ActionBarActivity для создания 5 вкладок. Я использовал ViewPager для пролистывания между 5 вкладками, используя SectionsPagerAdapter, который расширяет FragmentPagerAdapter. Каждая вкладка имеет фрагмент с асинхронной задачей, вызываемой в методе oncreateview. Когда я в одном фрагменте, асинктическая задача в другом фрагменте вызывается.
Я попытался использовать тост сообщения в методе oncreateview каждый фрагмент вместо asynctask. Но неправильные сообщения о тостах запускаются в неправильном фрагменте.
Создать код метода:
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager_exp);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position)
{
actionBar.setSelectedNavigationItem(position);
actionBar.setTitle(getHomePageTitle(position));
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++)
{
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(actionBar.newTab()
.setIcon(getPagedrawable(i))
.setTabListener(this));
}
// Код класса адаптера:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position)
{
case 0:
Fragment1 f1 = new Fragment1();
return f1;
case 1:
Fragment2 f2 = new Fragment2();
return f2;
case 2:
Fragment3 f3 = new Fragment3();
return f3;
case 3:
Fragment4 f4 = new Fragment4();
return f4;
case 4:
Fragment5 f5 = new Fragment5();
return f5;
}
return null;
}
@Override
public int getCount() {
// Show 5 total pages.
return 5;
}
}
Код класса Fragemnt:
public class F1 extends Fragment
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@SuppressLint("NewApi")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.f1,container, false);
Toast.makeText(getActivity(), "F1", Toast.LENGTH_SHORT).show();
return view;
}
}
4 ответа
FragmentPagerAdapter
сохраняет дополнительные фрагменты, кроме показанного, в возобновленном состоянии. Решение заключается в реализации пользовательских OnPageChangeListener
и создайте новый метод для того, когда фрагмент показан.
1) Создать LifecycleManager
Интерфейс Интерфейс будет иметь два метода и каждый ViewPager’s
Фрагмент это осуществит. Эти методы заключаются в следующем:
public interface FragmentLifecycle {
public void onPauseFragment();
public void onResumeFragment();
}
2) Пусть каждый Fragment
реализовать интерфейс Add iplements оператор для каждого объявления класса:
public class FragmentBlue extends Fragment implements FragmentLifecycle
public class FragmentGreen extends Fragment implements FragmentLifecycle
public class FragmentPink extends Fragment implements FragmentLifecycle
3) Реализовать интерфейсные методы в каждом фрагменте. Чтобы убедиться, что он действительно работает как положено, я просто запишу вызов метода и покажу Toast:
@Override
public void onPauseFragment() {
Log.i(TAG, "onPauseFragment()");
Toast.makeText(getActivity(), "onPauseFragment():" + TAG, Toast.LENGTH_SHORT).show();
}
@Override
public void onResumeFragment() {
Log.i(TAG, "onResumeFragment()");
Toast.makeText(getActivity(), "onResumeFragment():" + TAG, Toast.LENGTH_SHORT).show();
}
4) Вызовите методы интерфейса при изменении страницы ViewPager. Вы можете установить OnPageChangeListener для ViewPager и получать обратный вызов каждый раз, когда ViewPager показывает другую страницу:
pager.setOnPageChangeListener(pageChangeListener);
5) Реализуйте OnPageChangeListener для вызова ваших пользовательских методов жизненного цикла
Слушатель знает новую позицию и может вызвать интерфейсный метод для нового фрагмента с помощью PagerAdapter. Здесь я могу вызвать onResumeFragment() для нового фрагмента и onPauseFragment() для текущего.
Мне нужно также сохранить текущую позицию фрагмента (изначально текущая позиция равна 0), так как я не знаю, прокручивал ли пользователь слева направо или справа налево. Посмотрите, что я имею в виду в коде:
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) { }
};
Я не писал код. Полный учебник здесь: http://looksok.wordpress.com/2013/11/02/viewpager-with-detailed-fragment-lifecycle-onresumefragment-including-source-code/
ViewPager
создает представления для фрагментов, смежных с вашей текущей страницей. Это также дает вам возможность загрузить любые данные, необходимые для смежных фрагментов. Если вы используете AsyncTasks для загрузки данных, использование этой функции улучшит взаимодействие с пользователем. Но если вам нужно событие, когда определенная страница открывается с помощью ViewPager, решение LordRaydenMK будет работать.
Смотрите мой пост в следующей теме по использованию AsyncTasks в ViewPager:
Привет. Вы можете попробовать использовать тег каждого фрагмента и вызвать метод каждого фрагмента на странице Изменено.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
actionBar.setTitle(getHomePageTitle(position));
Fragment f = getFragrmentManager().findFragmentByTag(
"" + position);
if (f != null)
f.refresh();
}
});
и на
@Override
public Fragment getItem(int position) {
Fragment f=null;
switch (position)
{
case 0:
f = new Fragment1();
break;
case 1:
f = new Fragment2();
break;
case 2:
f = new Fragment3();
break;
case 3:
f = new Fragment4();
break;
case 4:
f = new Fragment5();
break;
}
f.setTag(""+position);
return f;
}
Использовать этот
viewPager.setOffscreenPageLimit(1); // the number of pages you want to load in background
а также ProgressDialogue
,