TabLayout+ViewPager实现滑动底部导航栏

这是最后一篇写底部导航栏了,其实还有挺多方式可以实现的,在这里就不写了。


这次既然用到了TabLayout,那么就看一下它有哪些属性吧

TabLayout+ViewPager实现滑动底部导航栏_第1张图片

其中我们主要用到的有:

tabIndicatorColor 指示线的颜色
tabIndicatorHeight 指示线的高度
tabSelectedTextColor Tab选中时的字体颜色
tabTextColor Tab正常情况下的字体颜色

tabMode 有两种模式
1.fixed 当tab数目不多,屏幕能全部显示出来时用这个模式,如下图:
这里写图片描述
2.scrollable 当tab数目超过屏幕所能显示的时候就用这个模式,设置了之后可以滑动。如下:
TabLayout+ViewPager实现滑动底部导航栏_第2张图片

其实TabLayout主要是用头部作上图这种导航,不过也可以用作底部导航栏,其主要方式就是使用自定义View,使用如下方法:

setCustomView(View view)

先上一下滑动底部栏的效果吧,如下图:

TabLayout+ViewPager实现滑动底部导航栏_第3张图片

同样地先准备图片资源,然后生成图片资源和文字的选择器,分别如下


图片资源选择器如下:



  
  

文字颜色选择器文件如下:



  
  

用到ViewPager,那就先创建好一个Adapter,代码如下:

public class TabLayoutAdapter extends FragmentPagerAdapter {

private List list_fragment;

/**
 * 这些资源可以在这里定义,可以在Activity中通过构造方法传进来
 */
private int[] tabimgs = new int[]{
        R.drawable.home_selector_32,R.drawable.shopcar_selector_32,
        R.drawable.mine_selector_32
};
private String[] titles = new String[]{"首页","购物车","我的"};
private Context context;
public TabLayoutAdapter(FragmentManager fm,List list_fragment,Context context) {
    super(fm);
    this.list_fragment = list_fragment;
    this.context = context;
}
@Override
public Fragment getItem(int position) {
    return list_fragment.get(position);
}
@Override
public int getCount() {
    return list_fragment.size();
}

/**
 * 这个提示tab的自定义视图
 * @param position
 * @return
 */
public View getCustomView(int position) {
    View view = LayoutInflater.from(context).inflate(R.layout.tab_custom_view,null);
    ImageView img = (ImageView) view.findViewById(R.id.tab_img);
    TextView txtview = (TextView) view.findViewById(R.id.tab_text);
    img.setImageResource(tabimgs[position]);
    txtview.setText(titles[position]);
    return view;
}
}

然后为主界面创建一个布局,代码如下:









然后界面的实现,跟平常用ViewPager一样,就是通过TabLayout下面这个方法把TabLayout和ViewPager产生关系。

 setupWithViewPager(ViewPager viewPager);

主界面的代码跟之前的差不多了,代码如下:

public class TabLayoutBottomActivity extends AppCompatActivity {

private TabLayout tabLayout;
private ViewPager viewPager;
private Class[] fragments = new Class[]{
        HomeFragment.class, ShopCarFragment.class, MineFragment.class
};
private List fragmentlists = new ArrayList<>();
private TabLayoutAdapter mAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_tablayoutbttom);
    initView();
    initTabLayout();
}

private void initView() {
    tabLayout = (TabLayout) findViewById(R.id.tab_FindFragment_title);
    viewPager = (ViewPager) findViewById(R.id.vp_FindFragment_pager);
}

private void initTabLayout() {
    HomeFragment homefragment = new HomeFragment();
    ShopCarFragment shopcarfragment = new ShopCarFragment();
    MineFragment minefragment = new MineFragment();
    fragmentlists.add(homefragment);
    fragmentlists.add(shopcarfragment);
    fragmentlists.add(minefragment);
    mAdapter = new TabLayoutAdapter(getSupportFragmentManager(),fragmentlists,this);
    //设置TabLayout的模式
    tabLayout.setTabMode(TabLayout.MODE_FIXED);
    viewPager.setAdapter(mAdapter);
    tabLayout.setupWithViewPager(viewPager);
    for (int i = 0; i < tabLayout.getTabCount(); i++) {
        TabLayout.Tab tab = tabLayout.getTabAt(i);
        //为每个tab设置自定义视图,获取自定视图的方法写在Adapter里面
        //同样也可以直接写在Activity里面
        tab.setCustomView(mAdapter.getCustomView(i));
    }
}
}

这里有个方法值得注意一下,就是tabLayout.getTabCount(),这个方法用于获得Tab的个数,可是想了一下,我们并没有对TabLayout设置tab啊,那它怎么知道我们用了几个Tab呢?


通过查看TabLayout的源码发现它是凭借mPagerAdapter.getCount()来获取Adapter里面fragment的个数,然后为我们添加相应个数的Tab,找到TabLayout下面的这个方法:

 private void populateFromPagerAdapter() {
    removeAllTabs();
    if (mPagerAdapter != null) {
        final int adapterCount = mPagerAdapter.getCount();
        for (int i = 0; i < adapterCount; i++) {
            addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
        }

        // Make sure we reflect the currently set ViewPager item
        if (mViewPager != null && adapterCount > 0) {
            final int curItem = mViewPager.getCurrentItem();
            if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
                selectTab(getTabAt(curItem));
            }
        }
    }
}

底部栏就完成了,那么再实现一下顶部导航吧


效果如最开始的两张图,这里再上一张图吧:

TabLayout+ViewPager实现滑动底部导航栏_第4张图片

也是先创建一个Adapter,代码和上面那个差不多:

public class TabLayoutTopAdapter extends FragmentPagerAdapter {
private List list_fragment;

private String[] titles = new String[]{"首页","购物车","我的"};

public TabLayoutTopAdapter(FragmentManager fm, List list_fragment) {
    super(fm);
    this.list_fragment = list_fragment;
}

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

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

/**
 * 返回页面的标题 如果选择在Activity里面直接
 * 用for (int i = 0; i < tabLayout.getTabCount(); i++) {
    tabLayout.getTabAt(i).setText(titles[i]);
   }设置的话就不用重写这个方法
 * @param position
 * @return
 */
@Override
public CharSequence getPageTitle(int position) {
    return titles[position%titles.length];
}
}

先创建一个布局,代码如下:










主布局代码如下:

public class TabLayoutTopActivity extends AppCompatActivity {

private TabLayout tabLayout;
private ViewPager viewPager;
private List fragmentlists = new ArrayList<>();
private TabLayoutTopAdapter mAdapter;
private String[] titles = new String[]{"首页","购物车","我的"};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_tablayouttop);
    initView();
    initTab();
}

private void initTab() {
    HomeFragment homefragment = new HomeFragment();
    ShopCarFragment shopcarfragment = new ShopCarFragment();
    MineFragment minefragment = new MineFragment();
    fragmentlists.add(homefragment);
    fragmentlists.add(shopcarfragment);
    fragmentlists.add(minefragment);

    mAdapter = new TabLayoutTopAdapter(getSupportFragmentManager(),fragmentlists);
    //设置TabLayout的模式
    tabLayout.setTabMode(TabLayout.MODE_FIXED);
    viewPager.setAdapter(mAdapter);
    tabLayout.setupWithViewPager(viewPager);
    //如果在Adapter里面重写getPageTitle这个方法
    //下面这个循环为tab设置标题就可以不要了
    for (int i = 0; i < tabLayout.getTabCount(); i++) {
        tabLayout.getTabAt(i).setText(titles[i]);
    }
}
private void initView() {
    tabLayout = (TabLayout) findViewById(R.id.tab_FindFragment_title);
    viewPager = (ViewPager) findViewById(R.id.vp_FindFragment_pager);
}
}

项目github地址

你可能感兴趣的:(Android)