Android控件-TabLayout使⽤介绍
TabLayout
简述
TabLayout是Android support中的⼀个控件android.support.design.widget.TabLayout,Google在升级了AndroidX之后,将TabLayout迁移到material包下⾯去了le.android.material.tabs.TabLayout,原来的support下⾯的TabLayout从API 29开始就不再维护了。所以如果项⽬已经升级了AndroidX,建议直接使⽤后者。TabLayout⼀般结合ViewPager+Fragment的使⽤实现滑动的标签选择器。
⽐如新闻标签切换
看下TabLayout的继承关系,如下图
support包下⾯的
material包下⾯的
TabLayout继承的HorizontalScrollView,所以⽀持左右滑动,下⾯写的简单的例⼦看看效果。
简单⽰例
l
<?xml version="1.0" encoding="utf-8"?>
&straintlayout.widget.ConstraintLayout
android="schemas.android/apk/res/android"
layout_width="match_parent"
layout_height="match_parent"
app="schemas.android/apk/res-auto">
&le.android.material.tabs.TabLayout
id="@+id/tab_layout"
layout_width="match_parent"
layout_height="wrap_content"
layout_constraintTop_toTopOf="parent"
layout_constraintStart_toStartOf="parent"
tabTextColor="@color/colorPrimary"
tabSelectedTextColor="@color/colorPrimaryDark"
/>
<androidx.viewpager.widget.ViewPager
id="@+id/view_pager"
layout_width="match_parent"
layout_height="wrap_content"
layout_constraintTop_toBottomOf="@+id/tab_layout"
/>
</straintlayout.widget.ConstraintLayout>
ConstraintLayout 布局⾥⾯就⼀个TabLayout和⼀个ViewPager,tabSelectedTextColor和tabTextColor属性分别设置标签选中和未选中状态的⽂字颜⾊,其他属性后⾯介绍。
TabFragment.java
public class TabFragment extends Fragment {
public static TabFragment newInstance(String label){
Bundle args =new Bundle();
args.putString("label", label);
控件的使用TabFragment fragment =new TabFragment();
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment_tab, container,false);
}
@Override
public void onStart(){
String label =getArguments().getString("label");
TextView text =getView().findViewById(R.id.tv_bg);
text.setText(label);
text.b((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255)));
}
}
TabFragment中就⼀个TextView,通过给每⼀个Fragment中的TextView设置不同的text和背景颜⾊来区分当前是哪⼀个Fragment。Fragment的布局⽂件如下:
l
<?xml version="1.0" encoding="utf-8"?>
<TextView android="schemas.android/apk/res/android"
id="@+id/tv_bg"
layout_width="match_parent"
layout_height="match_parent"
gravity="center_horizontal"
paddingTop="100dp"
/>
TabActivity.java
public class TabActivity extends AppCompatActivity {
private String[] tabs ={"tab1","tab2","tab3"};
private List<TabFragment> tabFragmentList =new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState){
setContentView(R.layout.activity_tab);
TabLayout tabLayout =findViewById(R.id.tab_layout);
ViewPager viewPager =findViewById(R.id.view_pager);
//添加tab
for(int i =0; i < tabs.length; i++){
tabLayout.wTab().setText(tabs[i]));
tabFragmentList.wInstance(tabs[i]));
}
viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURREN T_FRAGMENT){
@NonNull
@Override
public Fragment getItem(int position){
(position);
}
@Override
public int getCount(){
return tabFragmentList.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position){
return tabs[position];
}
});
//设置TabLayout和ViewPager联动
tabLayout.setupWithViewPager(viewPager,false);
}
}
简单的3步:
1. 为TabLayout添加tab
2. 给ViewPager设置adapter
3. 设置TabLayout和ViewPager联动
看看运⾏结果:
好了,基本的功能已经实现了。这⾥有个需要注意的点:
就是在给ViewPager设置Adapter的时候,⼀定要重写getPageTitle(int position)⽅法,不然TabLayout中的标签是看不到的,即使在addTab时newTab().setText(tabs[i])也没⽤。原因很简单,是在tabLayout.
setupWithViewPager的时候,TabLayout中先将所有tabs remove了,然后取的PagerAdapter中的getPageTitle返回值添加的tab。看下源码
@ViewPager.DecorView
public class TabLayout extends HorizontalScrollView {
...
private void setupWithViewPager(
@Nullable final ViewPager viewPager,boolean autoRefresh,boolean implicitSetup){
if(viewPager !=null){
this.viewPager = viewPager;
...
final PagerAdapter adapter = Adapter();
if(adapter !=null){
// Now we'll populate ourselves from the pager adapter, adding an observer if
// autoRefresh is enabled
setPagerAdapter(adapter, autoRefresh);
}
...
}else{
// We've been given a null ViewPager so we need to clear out the internal state,
// listeners and observers
this.viewPager =null;
setPagerAdapter(null,false);
}
}
void setPagerAdapter(@Nullable final PagerAdapter adapter,final boolean addObserver){
...
// Finally make sure we reflect the new adapter
populateFromPagerAdapter();
}
void populateFromPagerAdapter(){
removeAllTabs();
if(pagerAdapter !=null){
final int adapterCount = Count();
for(int i =0; i < adapterCount; i++){
addTab(newTab().PageTitle(i)),false);
}
...
}
}
...
}
可以看到populateFromPagerAdapter⽅法中执⾏了removeAllTabs()⽅法,然后取PageTitle(i)⽅法返回值重新添加tab,所以记得重写getPageTitle⽅法。
除了在代码⾥⾯动态的添加tab,还可以直接在xml中进⾏添加TabItem。
&le.android.material.tabs.TabLayout
id="@+id/tab_layout"
layout_width="match_parent"
layout_height="40dp"
layout_constraintTop_toTopOf="parent"
layout_constraintStart_toStartOf="parent"
tabTextColor="@color/grey"
tabSelectedTextColor="@color/colorAccent"
>
&le.android.material.tabs.TabItem
layout_width="wrap_content"
layout_height="wrap_content"
text="tab1"/>
&le.android.material.tabs.TabItem
layout_width="wrap_content"
layout_height="wrap_content"
text="tab2"/>
</le.android.material.tabs.TabLayout>
TabLayout属性介绍
TabLayout有很多属性可以供我们使⽤,下⾯简单介绍⼏个。
tabIndicatorFullWidth
上⾯的运⾏结果可以看到指⽰器的整个宽度是充满屏幕的,有时项⽬需要指⽰器线条的宽度和⽂字得宽度⼀致,那么就可以设置tabIndicatorFullWidth属性为false,默认为true
tabRippleColor
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论