У меня проблема с фрагментами во ViewPager.В моем приложении у меня есть 4 вкладки, реализованные с FragmentStatePagerAdapter.Вот мой SectionsPageAdapter.java
public class SectionsPageAdapter extends FragmentStatePagerAdapter {
private String fragment0 = "";
private Fragment fragAt0;
private FragmentManager manager;
private String[] tabNames;
Context context;
public SectionsPageAdapter(FragmentManager fm, Context ctx, String lastFrag) {
super(fm);
context = ctx;
tabNames = ctx.getResources().getStringArray(R.array.tabs_name);
this.manager = fm;
this.listener = new fragmentChangeListener();
fragment0 = lastFrag;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return ActivityTypeFragment.newInstance(0);
case 1:
return EventsFragment.newInstance();
case 2:
return CalendarFragment.newInstance();
case 3:
if(fragAt0 == null){
switch(fragment0){
case "Chart":
fragAt0 = ChartFragment.newInstance(listener);
break;
case "Hour":
fragAt0 = HourChartFragment.newInstance(listener);
break;
case "Daily":
fragAt0 = DailyChartFragment.newInstance(listener);
break;
default:
fragAt0 = ChartFragment.newInstance(listener);
}
}
return fragAt0;
default:
return ActivityTypeFragment.newInstance(0);
}
}
@Override
public int getCount() {
return 4;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return tabNames[position];
}
@Override
public int getItemPosition(@NonNull Object object) {
if (object instanceof ChartFragment && fragAt0 instanceof DailyChartFragment
|| object instanceof HourChartFragment && fragAt0 instanceof DailyChartFragment)
{
return POSITION_NONE;
}
else if (object instanceof DailyChartFragment && fragAt0 instanceof ChartFragment
|| object instanceof HourChartFragment && fragAt0 instanceof ChartFragment){
return POSITION_NONE;
}
else if (object instanceof HourChartFragment && fragAt0 instanceof ChartFragment)
{
return POSITION_NONE;
}
else if (object instanceof ChartFragment && fragAt0 instanceof HourChartFragment
|| object instanceof DailyChartFragment && fragAt0 instanceof HourChartFragment)
{
return POSITION_NONE;
}
return POSITION_NONE;
}
public interface nextFragmentListener {
void fragment0Changed(String newFragmentIdentification, FragmentManager fragmentManager);
}
private nextFragmentListener listener;
private final class fragmentChangeListener implements nextFragmentListener {
@Override
public void fragment0Changed(String fragment, FragmentManager fm) {
fragment0 = fragment;
manager.beginTransaction().remove(fragAt0).commitNow();
switch (fragment) {
case "Chart":
fragAt0 = ChartFragment.newInstance(listener);
break;
case "Daily":
fragAt0 = DailyChartFragment.newInstance(listener);
break;
case "Hour":
fragAt0 = HourChartFragment.newInstance(listener);
break;
}
SectionsPageAdapter.this.notifyDataSetChanged();
}
}
public String getFragmentName()
{
return fragment0;
}
}
Так что на последней вкладке у меня есть фрагмент - ChartFragment, где у меня есть Spinner с вариантами выбора другого графика.И когда пользователь выбирает другую диаграмму, эта другая диаграмма перезагружается на этой вкладке, вызывая методgment0Changed, который есть в моем классе SectionsPageAdapter.Я нашел это решение в https://stackoverflow.com/a/27304530/1573414.
Вот моя функция onItemSelected, которая у меня есть в каждом фрагменте, который я хочу отображать на вкладке Диаграммы
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (view != null) {
String selectedMenu = ((TextView) view).getText().toString();
if (selectedMenu == getString(R.string.best_appealing_chart)) {
LoadBestAppealingChart();
} else if (selectedMenu == getString(R.string.hour_chart)) {
chartListener.fragment0Changed("Hour", getActivity().getSupportFragmentManager());
}
else
{
chartListener.fragment0Changed("Daily", getActivity().getSupportFragmentManager());
}
}
else {
LoadBestAppealingChart();
}
}
Итак, все работает нормально, пока яповернуть устройство, после чего выбор другого графика не работает.Приложение выдает исключение:
java.lang.IllegalStateException: Fragment host has been destroyed
at android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:2183)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2211)
at android.support.v4.app.BackStackRecord.commitNow(BackStackRecord.java:643).
Я прочитал статью https://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html,but, в моем случае у меня нет ни асинхронных методов, где я бы заменял фрагмент, ни вызова в методах жизненного цикла Activity.Я делаю транзакцию фрагмента в методе onSelectionChanged моего счетчика.Что я пробовал: использование commitNowAllowingStateLoss () не делает вещи лучше, оно просто не выдает исключение, фрагменты по-прежнему не перезагружаются;Передача параметра getSupportFragmentManager () в метод frag0Changed также не помогает, но при этом не возникает никаких исключений, даже если я использую простой метод commitNow ().Но помогает то, что после поворота я выбираю первую или вторую вкладку своего приложения, затем перехожу на четвертую вкладку (вкладка Диаграммы), после чего я могу без проблем переключать (перезагружать) свои фрагменты.Интересно, что переход на третью вкладку (вкладка «Календарь») тоже не помогает.После переключения на третью вкладку и возврата на четвертую вкладку фрагменты переключения по-прежнему не перезагружаются.