前言:TabLayout是sdk 22之后的新特性,TabLayout+ViewPager实现切换卡布局在很多应用上是比较广泛的,同时实现起来也比较简单,交互效果也很不错,今天和大家一起分享其基本用法,在开始使用的时候,可能会遇到不少的坑(反正我是踩到坑了。。。。。。)。
一 引入依赖库:在项目的build.gradle文件下添加库依赖
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
在这里需要注意的是,依赖库的版本需要与build文件中规定的一致(及与compileSdkVersion,targetSdkVersion保持一致,这里我使用的是compileSdkVersion 28,targetSdkVersion 28,所以版本号为28),否则会报错。
二 xml布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
tools:context=".TabActivity">
<!--分别设置顶部导航栏的属性-->
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="40dp"
app:tabIndicatorHeight="2dp"
app:tabIndicatorFullWidth="false"
app:tabMode="scrollable"
app:tabMinWidth="60dp"
app:tabPaddingStart="5dp"
app:tabPaddingEnd="5dp"
app:tabTextAppearance="@style/TabLayoutTextStyle"
/>
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:background="#ffffff" />
</LinearLayout>
在布局中可以分别设置tabLayout的属性:
app:tabIndicatorHeight 设置导航item底部导航条
app:tabIndicatorFullWidth false 设置item底部导航条不填满item宽度,而是与item的文字等宽, true 表示占满整个item,分别类似于wrap_content match_parent
app:tabMode=“scrollable” 表示当导航栏的数量一次显示不全时,可支持滑动(今日头条顶部导航条是比较典型的例子)
app:tabTextAppearance="@style/TabLayoutTextStyle"用于设置item字体的大小。tabLayout中只能通过这样的方式设置字体的尺寸,具体方法为:
1)在style.xml文件中设置style:
<style name="TabLayoutTextStyle">
<item name="android:textSize">@dimen/tab_layout_text_size</item>
</style>
2)dimen.xml文件中设置字体的尺寸:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="tab_layout_text_size">16dp</dimen>
</resources>
3)最后,在布局中通过app:tabTextAppearance属性引用style文件即可
关于tabLayou的其他属性,大家在使用的时候可以对应的设置即可。
三 Activity中使用:
public class TabActivity extends AppCompatActivity {
private List<String> mTitleList;
//这里在使用的时候,如果在导包的过程中与widget包下的TabLayout冲突时,可以直接声明包的全名(我遇到了这个问题,导包的时候总是提示我导入widget下的包,无论各种clean build还是解决不了问题,最后索性直接声明包的全名)
private android.support.design.widget.TabLayout mTabLayout;
private ViewPager mViewPager;
private TabAdapter mTabAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab);
initialize();
}
private void initialize() {
mTabLayout = findViewById(R.id.tab_layout);
mViewPager = findViewById(R.id.view_pager);
mTitleList = new ArrayList<>();
//设置导航的内容
mTitleList.add("推荐");
mTitleList.add("关注");
mTitleList.add("小视屏");
mTitleList.add("视屏");
mTitleList.add("热点");
mTitleList.add("北京");
mTitleList.add("娱乐");
mTitleList.add("NBA");
mTitleList.add("其他");
mTabAdapter = new TabAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mTabAdapter);
mTabAdapter.setList(mTitleList);
mTabLayout.setupWithViewPager(mViewPager);
}
}
这里有一个需要注意的问题就是导包,不要和widget包下TabLayout混淆。实在不行,直接声明全名。
四 FragmentPagerAdapter
由于这里使用的布局是viewPager+fragment的切换布局,因此使用的适配器为FragmentPagerAdapter:
public class TabAdapter extends FragmentPagerAdapter {
private List<String> mTitleList;
public TabAdapter(FragmentManager fm) {
super(fm);
this.mTitleList = new ArrayList<>();
}
public void setList(List<String> datas) {
this.mTitleList.clear();
this.mTitleList.addAll(datas);
notifyDataSetChanged();
}
@Override
public Fragment getItem(int i) {
ContentFragment fragment = new ContentFragment();
//通过这样的方式,向对应的fragmen中传递参数,在fragmeng同样通过Bundle接收参数,以区别不同的fragmeng加载不同的数据或者实现不同的逻辑
Bundle bundle = new Bundle();
bundle.putString("name", mTitleList.get(i));
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getCount() {
return mTitleList.size();
}
@Override
public CharSequence getPageTitle(int position) {
String plateName = mTitleList.get(position);
if (plateName == null) {
plateName = "";
} else if (plateName.length() > 15) {
plateName = plateName.substring(0, 15) + "...";
}
return plateName;
}
}
五 ContentFragment:
1.每一个itemTab对应的fragmeng内容
public class ContentFragment extends Fragment {
private String mTitle;
private View mRootView;
private TextView mTextView;
public ContentFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在这里通过Bundle接收参数
Bundle bundle = getArguments();
mTitle = bundle.getString("name");
if (mTitle == null) {
mTitle = "参数非法";
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_content, container, false);
initView(mRootView);
return mRootView;
}
private void initView(View rootView) {
mTextView = rootView.findViewById(R.id.tv);
mTextView.setText(mTitle);
}
}
2.fragment的xml布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ContentFragment">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"/>
</RelativeLayout>
至此,已完成了TabLayout作为顶部导航,viewPager+Fragmeng进行切换的基本布局。
六 效果图
六 总结
1.TabLayout是sdk 22之后的新特性,因此必须要在sdk 22以后才能使用;
2.在导包的时候,若与widget包下的TabLayout冲突时,可直接导入完整包名;
3.在添加依赖库的时候,需要保持与compileSdkVersion,targetSdkVersion版本一致;
4.tabItem字体的设置只能通过tabTextAppearance属性引用Style形式;
5.TabLayout与ViewPager通过 mTabLayout.setupWithViewPager(mViewPager)方法进行关联,也是TabLayout与ViewPager联系起来的核心方法。
由于本人水平有限,以上若存在问题,欢迎指出。