Android ViewPager 加载不正确的片段

Android ViewPager Loading incorrect fragments

所以我想在我的主导航栏下方添加一个选项卡栏和布局 activity。

我似乎无法让 ViewPager/TabLayout(不确定是哪个问题的原因,这是新手)来加载正确的片段。我已经阅读了大量文档并检查了超过 1 个教程以查看我是否正确地执行此操作并且看起来我正在做同样的事情......

我的 TabLayoutOnTabSelectedListener 正在看到选项卡正确更改,并且在 OnTabSelected 我正在调用 viewPager.setCurrentItem(tab.getPosition()) 尝试设置我的 viewpagers 项目,但它仍然不工作。第一次加载时,它会加载第一个和第二个选项卡(我可以通过片段 onCreate 方法发送的 API 请求看到),当我单击其他选项卡时,它始终加载错误的片段,有时甚至没有加载一个!

不确定这是否相关,但我在切换标签时收到此警告:

03-03 16:24:22.940 16967-16967/com.sampleapp.app W/FragmentManager: moveToState: Fragment state for BlankFragment3{efddbec #2 id=0x7f0c007b android:switcher:2131492987:2} not updated inline; expected state 3 found 2

我正在使用构建工具版本 23.0.2 和以下依赖项:

compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:support-v4:23.1.1'

这是我的主导航栏布局代码:

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar1"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar2"
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill"/>

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_input_add" />

</android.support.design.widget.CoordinatorLayout>

根据不止一个教程,这是我用于我的适配器的代码

public class TabsAdapter extends FragmentPagerAdapter{
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public TabsAdapter(FragmentManager fm) {
        super(fm);
    }

    public void addFrag(Fragment fragment, String title){
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

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

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

下面是我如何设置 viewpager 和 tablayout

MainActivity 的 onCreate:

    ViewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(mViewPager); // Method defined below

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
    tabLayout.setupWithViewPager(mViewPager);
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            mViewPager.setCurrentItem(tab.getPosition());
            Log.w("Tab Selection", String.valueOf(tab.getPosition()));
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

最后,我的 setupViewPager 方法:

private void setupViewPager(ViewPager viewPager) {
    TabsAdapter adapter = new TabsAdapter(getSupportFragmentManager());
    adapter.addFrag(new BlankFragment1(), "One");
    adapter.addFrag(new BlankFragment2(), "Two");
    adapter.addFrag(new BlankFragment3(), "Three");
    viewPager.setAdapter(adapter);
}

如果有人发现这有什么问题请告诉我,我这辈子都无法让这些该死的标签加载正确的片段。

提前致谢!

  1. 您不需要在两个列表视图中分开。尝试一次性完成 class

添加class

class FragmentHolder{
    Fragment fragment;
    String title;

    public FragmentHolder(Fragment fragmentm String title){
        this.fragment = fragment;
        this.title = title;
    }

}

并在适配器中

public class TabsAdapter extends FragmentPagerAdapter{
    private final List<FragmentHolder> mFragmentList = new ArrayList<>();


    public TabsAdapter(FragmentManager fm) {
        super(fm);
    }

    public void addFrag(FragmentHolder fragmentHolder){
        mFragmentList.add(fragmentHolder);
    }

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

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position).title;
    }
}

试试这个代码伙伴 :D

ViewPager 适配器

public class PageAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;

public PageAdapter(FragmentManager fm,int numTabs) {
    super(fm);
    this.mNumOfTabs = numTabs;
}

@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            RemindsTab remindsTab = new RemindsTab();
            return remindsTab;
        case 1:
            TasksTab tasksTab = new TasksTab();
            return tasksTab;
        case 2:
            QuicklyNotesTab quicklyNotesTab = new QuicklyNotesTab();
            return quicklyNotesTab;
        default:
            return null;
    }
}

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

以及我在 MainActivity 中用于这些选项卡的代码:

 final TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
    tabLayout.addTab(tabLayout.newTab().setText("Recordatorios"));
    tabLayout.addTab(tabLayout.newTab().setText("Tareas"));
    tabLayout.addTab(tabLayout.newTab().setText("Notas Rapidas"));
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

     final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
     final PagerAdapter adapter = new PageAdapter(getSupportFragmentManager(),tabLayout.getTabCount());
     viewPager.setAdapter(adapter);
     viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

希望你能解决你的问题:)

首先你得知道FragmentPageAdaper是怎么工作的。 FragmentPagerAdapter 在开始时实例化两个 (2) 片段,第一个索引 (0) 片段和第二个下一个索引 (1) 片段。 所以不要尝试与代码作斗争,只需根据默认的 FragmentPageAdapter 工作更改您的登录即可。

1) 在Activity

中添加这一行
viewPager.setOffscreenPageLimit("your number of fragment"); 

2) 将此添加到您的片段中,这样当用户在页面之间切换时您可以控制片段动作

  // pause  video and other list when user switch fragment pager
    public void setUserVisibleHint(boolean isVisibleToUser)
    {
        super.setUserVisibleHint(isVisibleToUser);
        if (this.isVisible())
        {
            if (!isVisibleToUser)   // If we are becoming invisible, then...
            {
                mPlayer.pause();

                final SharedPreferences.Editor editor= pref.edit();
                editor.putBoolean("PlayerPause", true);
                editor.putInt("videotime",mPlayer.getCurrentTimeMillis());
                editor.commit();
                Log.e("Video "," serUserVisibleHint not visible to User");//pause or stop video
            }

            if (isVisibleToUser) // If we are becoming visible, then...
            {

              Log.e("Video "," serUserVisibleHint Visible to User");  //play your video
            }
        }
    }

@Riptyde4,我所做的只是将 TabsAdapter 扩展的 class 从 FragmentPagerAdapter 更改为 FragmentStatePagerAdapter 允许检测 viewPager 中的不同状态变化。我这样做了,效果很好。