0

In my app I want to have an activity which has in landscape-layout at the left a fragment with a list, and at the right a fragment which contains a viewpager (to swipe different fragments). My problem is that there will be nested fragments, because the fragment which contains the viewpager will contain the different fragments which can be swiped. Is there a solution so I can display my list next to my viewpager?

Here are my layout files:

layout of activity which contains a fragment with a list, and a fragment with the viewpager.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false" >

    <fragment
        android:id="@+id/cafelijst"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        class="com.example.projectapp.cafezoeken.CafeLijstFragment" />

    <FrameLayout
        android:id="@+id/details"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

layout of fragment with the viewpager.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

Fragment which contains the viewpager.

import com.example.projectapp.R;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


/**
 * A placeholder fragment containing a simple view.
 */
public class CafeSwipeFragment extends Fragment implements ActionBar.TabListener {

    CafeDetailsPagerAdapter mPagerAdapter;
    ViewPager mViewPager;
    View mView;
    public static int index;
    ActionBar actionBar;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        mView = inflater.inflate(R.layout.fragment_cafe_details, container, false);

        mViewPager = (ViewPager) mView.findViewById(R.id.pager);
        mPagerAdapter = new CafeDetailsPagerAdapter(getFragmentManager());


        // Set up the action bar.
        actionBar = getActivity().getActionBar();

        for (int i = 0; i < mPagerAdapter.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
            // listener for when this tab is selected.
            actionBar.addTab(actionBar.newTab().setText(mPagerAdapter.getPageTitle(i)).setTabListener(this));
        }

        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                // When swiping between different app sections, select the corresponding tab.
                // We can also use ActionBar.Tab#select() to do this if we have a reference to the
                // Tab.
                actionBar.setSelectedNavigationItem(position);
            }
        });



        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                // When swiping between different app sections, select the corresponding tab.
                // We can also use ActionBar.Tab#select() to do this if we have a reference to the
                // Tab.
                actionBar.setSelectedNavigationItem(position);
            }
        });


        Handler handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {
                mViewPager.setAdapter(mPagerAdapter);     
            }
        });

        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        return mView; 
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

    }

    public static CafeSwipeFragment newInstance(int index) {
        CafeSwipeFragment f = new CafeSwipeFragment();

        CafeSwipeFragment.index = index;
        return f;
    }

    public int getShownIndex() {
        return index;
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        mViewPager.setCurrentItem(tab.getPosition());

    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }
}

04-15 00:06:09.325: E/AndroidRuntime(15335): FATAL EXCEPTION: main
04-15 00:06:09.325: E/AndroidRuntime(15335): java.lang.IllegalStateException: Can't change container ID of fragment InfoFragment{41a85050 #0 id=0x7f05005a android:switcher:2131034202:0}: was 2131034202 now 2131034203
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:407)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:429)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:421)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at com.example.projectapp.cafezoeken.infotab.InfoFragment.onCreateView(InfoFragment.java:22)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:442)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at com.example.projectapp.cafezoeken.CafeSwipeFragment$3.run(CafeSwipeFragment.java:75)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.os.Handler.handleCallback(Handler.java:615)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.os.Handler.dispatchMessage(Handler.java:92)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.os.Looper.loop(Looper.java:155)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at android.app.ActivityThread.main(ActivityThread.java:5520)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at java.lang.reflect.Method.invokeNative(Native Method)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at java.lang.reflect.Method.invoke(Method.java:511)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
04-15 00:06:09.325: E/AndroidRuntime(15335):    at dalvik.system.NativeStart.main(Native Method)
Stein
  • 31
  • 1
  • 9

1 Answers1

0

change the second layout to

<?xml version="1.0" encoding="UTF-8"?>
<android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
</android.support.v4.widget.ViewPager>

You need this in onCreateView

mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportChildFragmentManager());
mPager.setAdapter(mPagerAdapter);

A custom PageAdapter:

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    private ArrayList<Fragment> mMyFragments = new ArrayList<Fragment>();

    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
        //... add Fragments to mMyFragments
    }

    @Override
    public Fragment getItem(int position) {
        return mMyFragments.get(position); 
    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }
}

I hope this will work for you.

Check: Screen slide with ViewPager

speedy1034
  • 304
  • 2
  • 9
  • I suppose the ending tag "" must be ""? – Stein Apr 14 '14 at 20:45
  • I have another question, in which class/ method do I have to inflate the layout? I have posted the fragment which contains the viewpager above – Stein Apr 14 '14 at 21:01
  • I am not totally sure, but do it in `onCreateView` in the Fragment – speedy1034 Apr 14 '14 at 21:10
  • Thanks for the help so far. But are you sure that this is the right method? Because I read that I have to use ChildFragmentManager to deal with nested fragments. I I also have a problem when I add tabs to the actionbar, and when I rotate my screen and come in another activity with the same fragment, the app crashes. I changed my code as you explained me, but it still give errors. I have been looking to do this for days, but I never saw a good example. I am also a beginner in android (school project) so I am not that good in combining different snippets of code. – Stein Apr 14 '14 at 21:53
  • Check the link I posted and try to do it, like it is described in the tutorials. Just change the getSupportFragmentManager to getChildSupportFragmentManager(). This should work. – speedy1034 Apr 14 '14 at 21:58
  • I changed my post and included the most important things – speedy1034 Apr 14 '14 at 22:07