用Tab和ViewPager实现Swipe Views

在本文中,我们将实现一种Android的导航方式——Swipe Views。这是一种效果不错的展示多个Fragment的手法。我们不仅可以通过ActionBar下的Tab来切换Fragment,也可以直接在Fragment上左右滑动实现切换。具体效果如下图:

swipe_views
图片来源:Providing Descendant and Lateral Navigation

谷歌官方文档Creating Swipe Views with Tabs提供了详细教程和Demo,在这里我按照自己的理解再梳理一下。

要实现 Swipe Views,主要需要一下几个步骤:

  1. 主界面布局中添加ViewPager

  2. 创建FragmentPagerAdapter子类并添加Fragment

  3. 主Activity的onCreate里初始化ViewPager

  4. 主Activity的onCreate里初始化ActionBar并添加Tab

主界面布局中添加ViewPager

主Activity的布局activity_main.xml的内容:



    

其中我们添加了一个ViewPager,并给一个id:pager

创建FragmentPagerAdapter子类并添加Fragment

创建一个FragmentAdapter类,继承自FragmentPagerAdapter

public class FragmentAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int i) {
        Fragment fragment;
        if (i==0) {
            fragment = new PlaceholderFragment();
        }
        else {
            fragment = new Recordings();
        }
        return fragment;
    }

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

我们主要重载了getItemgetCount两个函数。

getItem中,函数参数为Tab对应的位置,在本例中我们只有两个FragmentPlaceholderFragmentRecordings。根据位置的不同选择创建不同的对象。

getCount中,返回我们添加Fragment的数量。

我这里的代码写得不是很好,在Fragment多的时候用一个容器类来装Fragment,然后通过容器类的方法来操作比较好。

主Activity的onCreate里初始化ViewPager

在前两节中我们创建了ViewPagerFragmentPagerAdapter,其中FragmentPagerAdapter包含了我们的Fragment。在本节中,我们要向ViewPager中添加FragmentPagerAdapter并对ViewPager初始化。

具体在主Activity的onCreate中:

fragmentAdapter = new FragmentAdapter(getSupportFragmentManager());
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(fragmentAdapter);
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
        getSupportActionBar().setSelectedNavigationItem(position);
    }
});

首先我们创建FragmentAdapter并添加到viewPager

之后,我们实现了viewPagersetOnPageChangeListener,每当viewPager的page改变时,我们就设置tab选择对应的分页。这主要实现Fragment左右滑动切换时,Tab一同联动。

主Activity的onCreate里初始化ActionBar并添加Tab

在上面的代码之后,我们接着来添加并设置Tab:

actionBar = getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setIcon(R.drawable.ic_launcher);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        // When the tab is selected, switch to the
        // corresponding page in the ViewPager.
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {

    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {

    }
};
actionBar.addTab(
        actionBar.newTab().setText("Record").setTabListener(tabListener));
actionBar.addTab(
        actionBar.newTab().setText("Recordings").setTabListener(tabListener));

我们通过setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);说明ActionBar带有Tab。

之后创建了tabListener,主要覆盖了onTabSelected方法,当Tab分页被点选的时候,让ViewPager联动。

之后我们向ActionBar添加了两个Tab:RecordRecordings

总结

至此我们就完成了 Swipe Views的设计。这种导航方式我很喜欢,在包含Fragment不多的应用里,通过这种方式切换,给人一种高效、美观的感觉。