I have an activity (MainActivity) that contains MasterFragment which contains a viewpager with FragmentA and FragmentB in portrait screen orientation.
In landscape mode the viewpager contains only FragmentA on left side of a split screen, with FragmentB on the right side.
So basically FragmentB is moved to the right of the viewpager in landscape mode.
Although FragmentB is only shown once in each rotation, two instances are created at the same time after rotation.
The problem is that FragmentB is in reality a map, and I need to prevent 2 instances to be created at the same time. I need the first instance to be destroyed before the next instance is created.
What happens is the FragmentStateManager recreates FragmentB when calling setContentView in MainActivity.
How do I prevent that?
One solution would be to use super.onCreate(null) in MainActivity, but that is clearly an overkill.
How can I prevent recreating fragments in ViewPager2?
Another solution would be to use the recreated fragment instance and move it from the viewpager to the framlayout and vice versa. How can I move it?
MasterFragment.java
public class MasterFragment extends Fragment
{
NewPagerAdapter mSectionsPagerAdapter;
ViewPager2 mViewPager;
boolean mSplitView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.masterfragment, container, false);
if (isLandScape())
{
mSplitView = true;
getChildFragmentManager().beginTransaction().replace(R.id.container, new FragmentB(), FragmentB.TAG).commit();
}
else if (isLandScape())
{
LinearLayout masterlayout = view.findViewById(R.id.masterlayout);
masterlayout.removeViewAt(1);
}
mViewPager = view.findViewById(R.id.pager);
mSectionsPagerAdapter = new NewPagerAdapter(getChildFragmentManager(), getLifecycle());
mViewPager.setOffscreenPageLimit(7);
mViewPager.setAdapter(mSectionsPagerAdapter);
return view;
}
public boolean isLandScape()
{
int orientation = getResources().getConfiguration().orientation;
return orientation == Configuration.ORIENTATION_LANDSCAPE;
}
public boolean backOnePage()
{
if(mViewPager == null)
return false;
int page = mViewPager.getCurrentItem();
if(page > 0)
{
mViewPager.setCurrentItem(page - 1);
return true;
}
return false;
}
public void viewFragmentB()
{
if(!mSplitView)
mViewPager.setCurrentItem(1);
}
public class NewPagerAdapter extends FragmentStateAdapter
{
public NewPagerAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle)
{
super(fragmentManager, lifecycle);
}
@NonNull
@Override
public Fragment createFragment(int position)
{
if(position == 0)
return new FragmentA();
return new FragmentB();
}
@Override
public int getItemCount()
{
return mSplitView ? 1 : 2;
}
}
}
masterfragment.xml (Portrait)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff000000"
android:orientation="vertical">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
/>
</LinearLayout>
masterfragment.xml (Landscape)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/masterlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:background="#ff000000">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="0.5"
/>
<FrameLayout
android:id="@+id/container"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="0.5"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends FragmentActivity
{
MasterFragment mMasterFragment;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
Fragment fragment = savedInstanceState != null
? getSupportFragmentManager().getFragment(savedInstanceState, "MasterFragment")
: null;
mMasterFragment = fragment instanceof MasterFragment
? (MasterFragment)fragment
: (MasterFragment)getSupportFragmentManager().findFragmentById(R.id.masterfragment);
}
@Override
public void onBackPressed()
{
if(mMasterFragment != null && mMasterFragment.backOnePage())
return;
super.finish();
}
}
FragmentA
public class FragmentA extends Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_home, container, false);
view.findViewById(R.id.title).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
MasterFragment.getInstance().viewFragmentB();
}
});
return view;
}
}
FragmentB
public class FragmentB extends Fragment
{
public static String TAG = "OrderFragment";
static int COUNTER;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_crew, container, false);
COUNTER++; // COUNTER BECOMES 2
return view;
}
@Override
public void onDestroy()
{
COUNTER--;
super.onDestroy();
}
}
main.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.mobile.MasterFragment"
android:id="@+id/masterfragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>