这是最后一篇写底部导航栏了,其实还有挺多方式可以实现的,在这里就不写了。
这次既然用到了TabLayout,那么就看一下它有哪些属性吧
其中我们主要用到的有:
tabIndicatorColor 指示线的颜色
tabIndicatorHeight 指示线的高度
tabSelectedTextColor Tab选中时的字体颜色
tabTextColor Tab正常情况下的字体颜色
tabMode 有两种模式
1.fixed 当tab数目不多,屏幕能全部显示出来时用这个模式,如下图:
2.scrollable 当tab数目超过屏幕所能显示的时候就用这个模式,设置了之后可以滑动。如下:
其实TabLayout主要是用头部作上图这种导航,不过也可以用作底部导航栏,其主要方式就是使用自定义View,使用如下方法:
setCustomView(View view)
先上一下滑动底部栏的效果吧,如下图:
同样地先准备图片资源,然后生成图片资源和文字的选择器,分别如下
图片资源选择器如下:
文字颜色选择器文件如下:
用到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));
}
}
}
}
底部栏就完成了,那么再实现一下顶部导航吧
效果如最开始的两张图,这里再上一张图吧:
也是先创建一个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地址