TabLayout+ViewPager 实现app底部Tab布局
前言
在谷歌发布Android Design Support Library之前,底部tab布局的实现方法有不少,我最初用的是LinearLayout,后来用过RadioGroup模拟、其它方法没有用过,虽然这些方法能达到效果,但个人一直觉得不爽。Google在2015的IO大会带来了全新的Android Design Support Library,里面包含了许多新控件,这些新控件有许多是把以前的一些第三方开源库官方化,实现起来更为方便。其中的TabLayout控件可以实现底部tab布局。
2016年4月9日更新一个问题:由于TabLayout继承自HorizontalScrollView,因此,无论如何布局,在TabLayout上滑动时,总会能滑出边界一小段距离,也就是说TabLayout不是完全固定的,是可以Scroll的,用代码设置一下就可以了:
// 禁止滚动,否则即便怎样,都可以滚动一小段,因为TabLayout继承自HorizontalScrollView;
tabLayout.setOnTouchListener { view, motionEvent -> true }
先看看效果:
[](/images/2016/04/Screenshot_2016-04-03-22-54-08.jpeg)
下面我们来看看怎么简单实现。
过程
TabLayout和ViewPager分别是属于design和v4包下的,所以先在app的build.gradle中添加以下依赖:
// version define;
buildscript {
versions['supportLib'] = '23.2.1'
}
dependencies {
compile "com.android.support:support-v4:$versions.supportLib"
compile "com.android.support:design:$versions.supportLib"
}
然后在主布局文件content_main.xml中添加布局控件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/rlContent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.test.MainActivity"
tools:showIn="@layout/activity_main"
>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentBottom="true"
android:background="@drawable/bg_bottom_tab"
app:tabGravity="fill"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
app:tabBackground="@android:color/transparent"
>
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/tabLayout"
android:scrollbars="none"
>
</android.support.v4.view.ViewPager>
</RelativeLayout>
用ViewPager和TabLayout来实现Bottom Tab布局,比以前的方法简单很多。
属性解释:
android:layout_alignParentBottom="true" //对齐底部,TabLayout就放置到底部了 android:background="@drawable/bg_bottom_tab" // 设置整个TabLayout的背景 app:tabGravity="fill" // 各个tab的gravity设置为fill app:tabIndicatorHeight="0dp" // tab底部指示条高度设置为0不显示 app:tabMode="fixed" // tabLayout中的tab不可滑动 app:tabBackground="@android:color/transparent" // 这是tabLayout中的每个tab的背景,这里设置为透明是避免点击时出现灰色背景
在代码中初始化布局,设置适配器:
// 各个tab item的标题文字
val titlesBottomTab by lazy {
resources.getStringArray(R.array.titleBottomTab)
}
// 各个tab item的背景drawable(用selector实现背景变化)
val bgTabs = listOf(R.drawable.bg_tab1, R.drawable.bg_tab2, R.drawable.bg_tab3, R.drawable.bg_tab4)
val homeFragments = listOf(Tab1Fragment.newInstance("", ""), Tab2Fragment.newInstance("", ""), Tab3Fragment.newInstance("", ""), Tab4Fragment.newInstance("", ""))
private fun initViews(){
viewPager.adapter = object : FragmentPagerAdapter(supportFragmentManager){
override fun getPageTitle(position: Int): CharSequence? = titlesBottomTab[position]
override fun getCount(): Int = titlesBottomTab.size
override fun getItem(position: Int): Fragment? = homeFragments[position]
}
tabLayout.setupWithViewPager(viewPager)
for (i in 0..bgTabs.lastIndex) {
val tmpView = layoutInflater.inflate(R.layout.bottom_tab_item, null)
tmpView.tabItemImage.background = resources.getDrawable(bgTabs[i])
tmpView.tabItemText.text = titlesBottomTab[i]
tabLayout.getTabAt(i)?.customView = tmpView
if (i == viewPager.currentItem) tmpView.isSelected = true
}
tabLayout.setOnTabSelectedListener(object :TabLayout.OnTabSelectedListener{
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabSelected(tab: TabLayout.Tab?) {
var idxSelectedTab = 0
for (i in 0..bgTabs.lastIndex) {
if (tab == tabLayout.getTabAt(i)){
idxSelectedTab = i
break
}
}
viewPager.currentItem = idxSelectedTab
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
}
自定义View设置到tab中,原生的那个图标和文字的比例实在是看不惯
<!--bottom_tab_item.xml->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/tabItemImage"
android:layout_width="36dp"
android:layout_height="36dp" />
<TextView
android:id="@+id/tabItemText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="@color/color_tab_item_text"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</LinearLayout>
文字的颜色变化也是用color selector实现的(@color/color_tab_item_text)
以上就是简单用TabLayout+ViewPager实现app底部Tab布局的整个过程。
参考: