您的位置:首页 > 其它

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

2016-08-27 20:31 627 查看
这是最后一篇写底部导航栏了,其实还有挺多方式可以实现的,在这里就不写了。

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



其中我们主要用到的有:

tabIndicatorColor 指示线的颜色

tabIndicatorHeight 指示线的高度

tabSelectedTextColor Tab选中时的字体颜色

tabTextColor Tab正常情况下的字体颜色

tabMode 有两种模式

1.fixed 当tab数目不多,屏幕能全部显示出来时用这个模式,如下图:



2.scrollable 当tab数目超过屏幕所能显示的时候就用这个模式,设置了之后可以滑动。如下:



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

setCustomView(View view)


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



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

图片资源选择器如下:

<?xml version="1.0" encoding="utf-8"?>
<selector         xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/home_selected_32"/>
<item android:state_selected="false" android:drawable="@drawable/home_unselected_32"/>
</selector>


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

<?xml version="1.0" encoding="utf-8"?>
<selector     xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="@color/tab_selected"/>
<item android:state_selected="false" android:color="@color/tab_unselected"/>
</selector>


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

public class TabLayoutAdapter extends FragmentPagerAdapter {

private List<Fragment> 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<Fragment> 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;
}
}


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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:layout_height="0dp"
android:layout_width="match_parent"
android:id="@+id/vp_FindFragment_pager"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
<!--注意要把指示器高度设置0dp,即隐藏它-->
<android.support.design.widget.TabLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/tab_FindFragment_title"
app:tabSelectedTextColor="#66a"
app:tabIndicatorHeight="0dp"
android:background="#ffffff">
</android.support.design.widget.TabLayout>
</LinearLayout>


然后界面的实现,跟平常用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<Fragment> 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<Fragment> list_fragment;

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

public TabLayoutTopAdapter(FragmentManager fm, List<Fragment> 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];
}
}


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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/tab_FindFragment_title"
app:tabSelectedTextColor="#eb4f38"
app:tabIndicatorHeight="2dp"
android:background="#ffffff">
</android.support.design.widget.TabLayout>

<android.support.v4.view.ViewPager
android:layout_height="0dp"
android:layout_width="match_parent"
android:id="@+id/vp_FindFragment_pager"
android:layout_weight="1">
</android.support.v4.view.ViewPager>

</LinearLayout>


主布局代码如下:

public class TabLayoutTopActivity extends AppCompatActivity {

private TabLayout tabLayout;
private ViewPager viewPager;
private List<Fragment> 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地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: