从getItemPosition更新ViewPager中的Fragment

3

我有一个屏幕,其中包含来自设计支持库的新TabLayout。 我还有一个ViewPager,用于显示Fragment。该Fragment根据所选的选项卡显示不同列表的视图。

应用程序接收到网络调用的响应后,我的活动使用由响应返回的数据更新ViewPager所属的FragmentPagerAdapter,我的情况下有3个列表。

在我的ViewPager中,我重写了onPageChangeListener()以检测何时选择了页面,然后使用新的选项卡位置调用了我的FragmentPagerAdapter。 我还调用notifyDataSet()以重新绘制视图。

我重写getItemPosition()方法以确定应将哪个列表传递给Fragment。 但是,我认为这不是正确的方法,因为getItemPosition正在发生大量的过度绘制。实际上,该方法正在使用相同的结果列表更新每个片段。 当滚动到下一个选项卡时,当前列表在下一个选项卡中可见,直到释放滚动,然后片段会以正确的列表重新绘制。

我的问题是,我是否采取了正确的方法来显示ViewPager Fragments中的列表? 还是我过于复杂化了? 我没有太多关于ViewPagers或FragmentPagerAdapters的经验,因此非常感谢任何意见。

我的代码如下。

添加Fragment(从onResume()调用)

private void addFragment() {

    mViewPager = (ViewPager) findViewById(R.id.viewpager);

    mMyPagerAdapter = new MyPagerAdapter(getSupportFragmentManager(),
            SampleActivity.this);

    mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(final int i, final float v, final int i2) {
        }
        @Override
        public void onPageSelected(final int i) {
            mMyPagerAdapter.updateTabPosition(i);
        }
        @Override
        public void onPageScrollStateChanged(final int i) {
        }
    });

    mViewPager.setAdapter(mMyPagerAdapter);
    mViewPager.setOffscreenPageLimit(1);

    mTabLayout = (TabLayout) findViewById(R.id.my_tab_layout);
    mTabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
    mTabLayout.setTabMode(TabLayout.MODE_FIXED);
    mTabLayout.setupWithViewPager(mViewPager);

    if (shouldMakeNetworkCall()) {
        getLists();
    }
}

ViewPager FragmentPagerAdapter类
public class MyFragment extends FragmentPagerAdapter {

private Context mContext;
final int PAGE_COUNT = 3;
private String tabTitles[] = new String[] { "One", "Two", "Three" };
private List<MyListType> mListOne;
private List<MyListType> mListTwo;
private List<MyListType> mListThree;
private int mTabPosition;

public MyPagerAdapter(FragmentManager fm, Context context) {
    super(fm);
    mContext = context;
}

@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            return MyFragment.newInstance(mListOne);
        case 1:
            return MyFragment.newInstance(mListTwo);
        case 2:
            return MyFragment.newInstance(mListThree);
        default:
            return null;
    }
}

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

@Override
public CharSequence getPageTitle(int position) {
    // Generate title based on item position
    return tabTitles[position];
}

@Override
public int getItemPosition(Object object) {
    if (object instanceof MyFragment) {

        switch (mTabPosition) {
            case 0:
                ((MyFragment) object).setupUI(mListOne);
                break;
            case 1:
                ((MyFragment) object).setupUI(mListTwo);
                break;
            case 2:
                ((MyFragment) object).setupUI(mListThree);
                break;
            default:
                break;
        }
    }
    return super.getItemPosition(object);
}


public void updateTabPosition(int tabPosition) {
    mTabPosition = tabPosition;
    notifyDataSetChanged();
}
}
1个回答

3

实际上,我认为你正在把这个问题复杂化了。

对我来说,最好的解决方案是针对 ViewPager 中的每个片段进行三次网络调用。让片段自己管理它们的调用,就像在单个片段 Activity 中所做的一样。这样,如果您想要适当的 UX,甚至可以在每个片段上显示和隐藏进度。我建议使用 Switcher 来实现

问题是,您能否进行单独的调用?因为如果不能,那么将进行三次相同的大型调用并不是最明智的选择。在第二种情况下,您可以让每个片段都带有旋转进度条,并让活动进行调用。对我来说,与 ViewPager 片段通信的首选解决方案是使用 事件。您只需在活动中进行调用,加载完成后,按照相应方式拆分数据并发送 3 个带有数据的事件,然后让每个片段响应这些事件。只需在 onAttach 方法中注册 EventBus,然后在 onDetach 方法中取消注册即可


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接