一、TabLayout属性介绍
1改变选中字体的颜色
app:tabSelectedTextColor=”@android:color/holo_red_light”
2.改变未选中字体的颜色
app:tabTextColor=”@color/colorPrimary”
3.改变指示器下标的颜色
app:tabIndicatorColor=”@android:color/holo_red_light”
4.改变指示器下标的高度
app:tabIndicatorHeight=”4dp”
5.改变整个TabLayout的颜色
app:tabBackground=”color”//这里不能直接写RGB,需要@color/xx 或drawable
6.改变TabLayout内部字体大小
app:tabTextAppearance=”@style/TextAppearance.Design.Tab”//设置文字的外貌即颜色字体大小等,也可以自己新建style
<style
name="TextAppearance.Design.Tab" parent="TextAppearance.AppCompat.Button">
<item
name="android:textSize">@dimen/design_tab_text_size
</item>
<item
name="android:textColor">?android:textColorSecondary
</item>
<item
//字母是否大写
name="textAllCaps">true
</item>
</style>
7.添加tab
tabLayout.addTab(tabLayout.newTab().setText(“Tab1”).setIcon(R.mipmap.ic_launcher));
8.加入Padding
设置Tab内部的子控件的Padding:
app:tabPadding=”xxdp”
app:tabPaddingTop=”xxdp”
app:tabPaddingStart=”xxdp”
app:tabPaddingEnd=”xxdp”
app:tabPaddingBottom=”xxdp”
设置整个TabLayout的Padding:
app:paddingEnd=”xxdp”
app:paddingStart=”xxdp”
9.内容的显示模式
app:tabGravity=”center”//居中,如果是fill,则是充满
10.Tab的宽度限制
设置最大的tab宽度:
app:tabMaxWidth=”xxdp”
设置最小的tab宽度:
app:tabMinWidth=”xxdp”
11.Tab的“Margin”:TabLayout开始位置的偏移量:
app:tabContentStart=”100dp”
12.Tab的模式
app:tabMode=”scrollable”
app:tabMode=”fixed”
13。选中某项
tablayout.getTabAt(position).select()
二.TabLayout+ViewPager+Fragment
应用一:纯文本tab
布局文件
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.linwei.lw.tablayoutdemo.ui.activity.MainActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="@color/colorAccent"
app:tabIndicatorHeight="2dp"
app:tabMode="fixed"
app:tabSelectedTextColor="@color/colorAccent">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
</LinearLayout>
FragmentFactory
/**
* Fragment工厂类。
* Created by LW on 2017/4/20.
*/
public class FragmentFactory {
private static HashMap<Integer, BaseFragment> mBaseFragments = new HashMap<Integer, BaseFragment>();
public static BaseFragment createFragment(int pos) {
BaseFragment baseFragment = mBaseFragments.get(pos);
if (baseFragment == null) {
switch (pos) {
case 0:
baseFragment = new TopNewsFragment();//头条
break;
case 1:
baseFragment = new NewsFragment();//新闻
break;
case 2:
baseFragment = new EntertainmentFragment();//娱乐
break;
case 3:
baseFragment = new SportsFragment();//体育
break;
case 4:
baseFragment = new FinanceFragment();//财经
break;
case 5:
baseFragment = new ScienceFragment();//科技
break;
case 6:
baseFragment = new FashionFragment();//时尚
break;
}
mBaseFragments.put(pos, baseFragment);
}
return baseFragment;
}
}
BaseFragment
public abstract class BaseFragment extends Fragment {
protected Context mContent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContent = getContext();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return initView();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initData();
}
protected abstract void loadData();
protected abstract View initView();
}
NewsFragment
public class NewsFragment extends BaseFragment {
@Override
protected void loadData() {
Toast.makeText(mContent,"Fragment头条加载数据",Toast.LENGTH_SHORT).show();
}
@Override
protected View initView() {
TextView mtextView = new TextView(mContent);
mView.setGravity(Gravity.CENTER);
mView.setTextSize(18);
Bundle args = getArguments();
String title = args.getString("title");
mView.setText("Fragment"+title));
mView.setTextColor(Color.BLACK);
return mtextView ;
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="tab_short_Title">
<item>头条</item>
<item>新闻</item>
<item>娱乐</item>
<item>体育</item>
</string-array>
<string-array name="tab_long_Title">
<item>头条</item>
<item>新闻</item>
<item>娱乐</item>
<item>体育</item>
<item>财经</item>
<item>科技</item>
<item>时尚</item>
</string-array>
</resources>
public class TabActivity extends AppCompatActivity {
private TabLayout mTab;
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_short);
initView();
initData();
}
private void initData() {
ShortPagerAdapter adapter = new ShortPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(adapter);
mTab.setupWithViewPager(mViewPager);
}
private void initView() {
mTab = (TabLayout) findViewById(R.id.tab);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
}
private class ShortPagerAdapter extends FragmentPagerAdapter {
public String[] mTilte;
public ShortPagerAdapter(FragmentManager fm) {
super(fm);
mTilte = getResources().getStringArray(R.array.tab_short_Title);
}
@Override
public CharSequence getPageTitle(int position) {
return mTilte[position];
}
@Override
public BaseFragment getItem(int position) {
BaseFragment fragment = FragmentFactory.createFragment(position);
Bundle bundle=new Bundle();
bundle.putString("title",mTilte[position]);
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getCount() {
return mTilte.length;
}
}
}
效果图:
疑问 1:上述代码只是tablayout..setupWithViewPager(mViewPager),并重写了FragmentPagerAdapter 的getPageTitle()方法,没看见tabLayout.addTab()啊?这些tab怎么加进去的?
setupWithViewPager()方法
public void setupWithViewPager(@Nullable ViewPager viewPager) {
setupWithViewPager(viewPager, true);
}
public void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh) {
setupWithViewPager(viewPager, autoRefresh, false);
}
private void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh,
boolean implicitSetup) {
/........省略代码
if (viewPager != null) {
mViewPager = viewPager;
/........省略代码
final PagerAdapter adapter = viewPager.getAdapter();
//adapter不为 null,调用setPagerAdapter(adapter, autoRefresh);
if (adapter != null) {
// Now we'll populate ourselves from the pager adapter, adding an observer if
// autoRefresh is enabled
setPagerAdapter(adapter, autoRefresh);
/........省略代码
mSetupViewPagerImplicitly = implicitSetup;
}
adapter不为 null,调用setPagerAdapter(adapter, autoRefresh);
void setPagerAdapter(@Nullable final PagerAdapter adapter, final boolean addObserver) {
if (mPagerAdapter != null && mPagerAdapterObserver != null) {
// If we already have a PagerAdapter, unregister our observer
mPagerAdapter.unregisterDataSetObserver(mPagerAdapterObserver);
}
mPagerAdapter = adapter;
if (addObserver && adapter != null) {
// Register our observer on the new adapter
if (mPagerAdapterObserver == null) {
mPagerAdapterObserver = new PagerAdapterObserver();
}
adapter.registerDataSetObserver(mPagerAdapterObserver);
}
// 注意这里
populateFromPagerAdapter();
}
populateFromPagerAdapter()方法
void populateFromPagerAdapter() {
//去除所有tabs
removeAllTabs();
if (mPagerAdapter != null) {
final int adapterCount = mPagerAdapter.getCount();
for (int i = 0; i < adapterCount; i++) {
//添加tab并调用PagerAdapter的getPageTitle()方法设置tab的title
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));
}
}
}
}
小结:
- 在setupWithViewPager之前,用tabLayout.addTab()添加tab是没意义的,因为
setupWithViewPager()–>setPagerAdapter( )
–>populateFromPagerAdapter()–> removeAllTabs(),去除所有tab.
// –> 为调用的意思
void populateFromPagerAdapter() {
//去除所有tab
removeAllTabs();
//.......省略
}
- setupWithViewPager()在哪添加的tab
etupWithViewPager()–>setPagerAdapter( )
–>populateFromPagerAdapter()–>mPagerAdapter != null–>
addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), 添加tab并调用PagerAdapter的getPageTitle()方法设置tab的title
应用二:Tab图片显示或图片加文字。
方法一:
不重写getPageTitle()方法
tabLayout.setupWithViewPager(viewPager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
//设置图片选择器
Drawable drawable = getResources().
getDrawable(R.drawable.image_select);
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setIcon(drawable);//只显示图片
// 显示图片加文字用tab.setIcon(drawable).setText(title[i]);
}
方法二:
步骤一:
int[] imageNormal= {R.mipmap.pic1, R.mipmap.pic2, R.mipmap.pic3, R.mipmap.pic4,R.mipmap.pic5,R.mipmap.pic6,R.mipmap.pic7};
int[] imageSelect = {R.mipmap.pic_sel_1, R.mipmap.pic_sel_2, R.mipmap.pic_sel_3, R.mipmap.pic_sel_4, R.mipmap.pic_sel_5,
R.mipmap.pic_sel_6, R.mipmap.pic_sel_7};
步骤二:
@Override
public CharSequence getPageTitle(int position) {
//titles[position]为"",则只显示图片,titles[position]不为"",显示图片+文字
return getSpannableString(false,imageNormal[position], titles[position]);
}
@NonNull
private SpannableString getSpannableString(boolean isSelected,int imageId, String title) {
SpannableString spannableString=new SpannableString(" "+ title);
Drawable drawable= ContextCompat.getDrawable(MainActivity.this, imageId);
drawable.setBounds(0,0,drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
//注意ImageSpan的渲染问题 ,textAllCaps=true,会阻止ImageSpan的渲染
ImageSpan imageSpan=new ImageSpan(drawable);
spannableString.setSpan(imageSpan,0,1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (isSelected){
spannableString.setSpan(new ForegroundColorSpan(Color.RED), 1, source.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}else {
spannableString.setSpan(new ForegroundColorSpan(Color.BLACK), 1, source.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spannableString;
}
步骤三:
重点:修改app:tabTextAppearance设置的style中textAllCaps的值,textAllCaps=false;
因为TabLayout的textAllCaps属性默认值是true,会阻止ImageSpan的渲染,我们只需要将其重写为false即可.
这种方法设置选择器没效果,所以
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
updateTabStase(tab,imageSelect,title);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
updateTabStase(tab,imageNormol,title);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
@NonNull
private void updateTabStase(TabLayout.Tab tab, int[] imageIds, String[] titles) {
int position = tab.getPosition();
SpannableString spannableString = getSpannableString(tab.isSelected(),imageIds[position], titles[position]);
tab.setText(spannableString);
}
记住在addOnTabSelectedListener()后加上这句 tabLayout.getTabAt(0).setText(getSpannableString(true,imageSelect[0], titles[0]).select();
只显示图片
图片加文字
应用三:tab以自定义View形式展示
步骤一:不重写FragmentPagerAdapter的getPageTitle()方法。
步骤二:在FragmentPagerAdapter添加一个自定义方法getTabView()
View getTabView(int postiion){
View view= LayoutInflater.from(MainActivity.this).
inflate(R.layout.activity_main,null)
TextView title= view.findViewById(R.id.title);
ImageView image= view.findViewById(R.id.Image);
title.setText(title[postiion]);
image.setImageResource(imageIds[postiion]);
return view;
};
步骤三:在tablayout.setupWithViewPager()之后手动给tab设置CustomView。
tablayout.setupWithViewPager(mViewpager)
for (int i = 0; i < tabLayout.getChildCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(adapter.getTabView(i));
}
步骤四:tab状态切换改变CustomView状态,例如:颜色,图片等
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
{
@Override
public void onTabSelected(TabLayout.Tab tab) {
setTabSelectedState(tab);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
setTabUnSelectedState(tab);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
private void setTabSelectedState(TabLayout.Tab tab) {
View customView = tab.getCustomView();
TextView title= (TextView)customView.findViewById(R.id.title);
ImageView tabIcon = (ImageView) customView.findViewById(R.id.image);
title.setTextColor(ContextCompat.getColor(getActivity(), R.color.colorPrimary));
int position = tab.getPosition();
switch (position) {
case 0:
tabIcon.setImageResource(R.drawable.TopNews_Selected);
break;
case 1:
tabIcon.setImageResource(R.drawable.News_Selected);
break;
case 2:
tabIcon.setImageResource(R.drawable.Entertainment_Selected);
break;
case 3:
tabIcon.setImageResource(R.drawable.Sports_Selected);
break;
}
private void setTabUnSelectedState(TabLayout.Tab tab) {
View customView = tab.getCustomView();
TextView tabText = (TextView) customView.findViewById(R.id.tv_tab_text);
ImageView tabIcon = (ImageView) customView.findViewById(R.id.iv_tab_icon);
tabText.setTextColor(ContextCompat.getColor(getActivity(), R.color.black_1));
int position = tab.getPosition();
switch (position) {
case 0:
tabIcon.setImageResource(R.drawable.TopNews);
break;
case 1:
tabIcon.setImageResource(R.drawable.News);
break;
case 2:
tabIcon.setImageResource(R.drawable.Entertainment);
break;
case 3:
tabIcon.setImageResource(R.drawable.Sports);
break;
}
三.app:tabMode和app: tabGravity
(1)app:tabMode有两个值:fixed和scrollable。
(2)app:tabGravity有两个值:fill和center。
1)tabGravity=”fill”和tabMode=”fixed”
2)tabGravity=”center”和tabMode=”fixed”
3)tabGravity=”fill”和tabMode=”scrollable”
4)tabGravity=”center”和tabMode=”scrollable”