3

I have a screen which has the new TabLayout from the design support library. I also have a ViewPager which is used to display a Fragment. This Fragment displays different lists of views depending on which tab is selected.

The app receives a response to a network call, my activity updates the FragmentPagerAdapter belonging to the ViewPager with the data returned by the response, in my case this is 3 lists.

In my ViewPager I override the onPageChangeListener() to detect when a page has been selected, and then I make a call to my FragmentPagerAdapter with the new tab position. I also call notifyDataSet() in order to redraw the view.

I override the getItemPosition() method to determine which list should be passed to the Fragment. However I don't think that this is the correct way to do it as their is a good deal of overdraw occurring from the getItemPosition. The method is actually updating each of the fragments with the same list of results. When scrolling to the next tab the current list is visible in the next tab until the scroll is release, then the fragment redraws with the correct list.

My question is am I taking the correct approach to displaying the lists in my ViewPager Fragments? Or am I seriously overcomplicating things? I don't have much experience with ViewPagers or FragmentPagerAdapters so any input would be greatly appreciated.

My code is as below.

Adding a fragment (called from 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();
    }
}

The ViewPager FragmentPagerAdapter class

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();
}
}
4

1 回答 1

3

实际上,我确实认为您使这件事复杂化了。

对我来说,最好的解决方案是进行 3 个网络调用,每个调用用于ViewPager. 让片段自己管理它们的调用,就像您对单个片段所做的那样Activity。这样,如果您想要正确的 UX,您甚至可以显示和隐藏每个片段的进度。我建议为此使用Switcher

问题是你能单独打电话吗?因为如果你不能,它会打同样的大电话 3 次,这不是最聪明的主意。在第二种情况下,您可以启动每个片段,并让进度旋转并让活动进行调用。对我来说,与ViewPager片段通信的首选解决方案是使用事件。您只需在活动中进行调用,并在加载后分别拆分数据并发送 3 个事件,其中包含数据,并让每个片段响应它们。只需注册到 EventBus 内部onAttach并在onDetach方法中取消注册

于 2015-07-29T13:54:35.883 回答