【问题标题】:Viewpager in a fragment片段中的 Viewpager
【发布时间】:2014-04-15 06:08:02
【问题描述】:

在我的应用程序中,我希望有一个 Activity,它在左侧有一个带有列表的片段,在右侧有一个包含 viewpager 的片段(用于滑动不同的片段)。我的问题是会有嵌套的片段,因为包含 viewpager 的片段将包含可以滑动的不同片段。是否有解决方案让我可以在查看器旁边显示我的列表?

这是我的布局文件:

activity 的布局,其中包含一个带有列表的片段和一个带有 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>

使用 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>

包含 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)

【问题讨论】:

    标签: android android-fragments nested android-viewpager


    【解决方案1】:

    将第二个布局改为

    <?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>
    

    onCreateView你需要这个

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

    一个自定义的 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;
        }
    }
    

    我希望这对你有用。

    检查:Screen slide with ViewPager

    【讨论】:

    • 我想结束标签“”必须是“”?
    • 我还有一个问题,我必须在哪个类/方法中扩展布局?我已经发布了上面包含 viewpager 的片段
    • 我不完全确定,但在 Fragment 中的 onCreateView 中进行操作
    • 感谢您到目前为止的帮助。但是你确定这是正确的方法吗?因为我读到我必须使用 ChildFragmentManager 来处理嵌套片段。我在将选项卡添加到操作栏时也遇到问题,当我旋转屏幕并进入具有相同片段的另一个活动时,应用程序崩溃。我按照您的解释更改了代码,但仍然出现错误。几天来我一直在寻找这样做,但我从未见过一个很好的例子。我也是android(学校项目)的初学者,所以我不太擅长组合不同的sn-ps代码。
    • 检查我发布的链接并尝试这样做,就像教程中描述的那样。只需将 getSupportFragmentManager 更改为 getChildSupportFragmentManager()。这应该有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多