If anyone is interested, I believe I've found an adequate solution to my problem.
I created my FragmentPagerAdapter so that the first page is initialized normally, but the second page is merely a container that will initialize the fragment later.
public static class ContractDetailsPagerAdapter extends FragmentPagerAdapter {
int numFrags = 2;
public ContractDetailsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
String argObject = null;
switch (position) {
case 0:
fragment = new SectionsFragment();
argObject = SectionsFragment.ARG_OBJECT;
break;
case 1:
fragment = new DetailsFragmentContainer();
argObject = DetailsFragmentContainer.ARG_OBJECT;
break;
default:
Log.e("ContractDetailsPagerAdapter", "called getItem outofbounds");
return null;
}
Bundle bundle = new Bundle();
bundle.putInt(argObject, position+1);
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getCount() {
return numFrags;
}
}
In the FragmentPagerAdapter, SectionsFragment is a first fragment that has the 3 ListViews, and the DetailsFragmentContainer is merely a container that will initialize DetailsFragment later on.
public class DetailsFragmentContainer extends Fragment {
public static final String ARG_OBJECT = "details_fragment_container";
Bundle ids;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ids = getArguments();
View v = inflater.inflate(R.layout.fragments_container, container, false);
return v;
}
public void createDetailsFragment(int parentItemId) {
Fragment fragment = new DetailsFragment();
ids.putInt(Columns.COLUMN_PARENTITEMID, parentItemId);
fragment.setArguments(ids);
getChildFragmentManager().beginTransaction().add(R.id.fragments_frame, fragment).commit();
}
}
and the XML layout for the container:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragments_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
The parentitemid is what I needed to get later on when an item in the 3rd column is clicked from the SectionsFragment.
Then, using the accepted answer from How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically? , I adapted it slightly so that the ability to be swiped can be set.
public class SetSwipeableViewPager extends ViewPager {
boolean canSwipe = false;
public SetSwipeableViewPager(Context context) {
super(context);
}
public SetSwipeableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (!canSwipe) {
return false;
}
return super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!canSwipe) {
return false;
}
return super.onTouchEvent(event);
}
public void canSwipe(boolean swipeable) {
canSwipe = swipeable;
}
}
With this, we can simply set the ability to swipe to false when we are in the first page, and enable it when we leave.
First, we set a listener to check when we select the first page and disable swipe.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if (position == 0)
mViewPager.canSwipe(false);
}
});
When we select an item in the 3rd list, we create the DetailsFragment and put it in the DetailsFragmentContainer, set the current item to 1 so that the viewpager will show the 2nd page, and then reenable to swipe.
public void OnSection3Selected(long id) {
int parentItemId = ContractDetailsActivity.getItemId(id, getActivity());
...
((DetailsFragmentContainer) fragment).createDetailsFragment(parentItemId);
mViewPager.setCurrentItem(1);
mViewPager.canSwipe(true);
}
I hope this is helpful to someone!