Backlight87
11/7/2017 - 9:21 AM

TabLayout使用

TabLayout简单使用

引进依赖: compile 'com.android.support:appcompat-v7:26.+' compile 'com.android.support:design:26.1.0'

布局:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <android.support.design.widget.TabLayout
        app:tabGravity="fill"
        app:tabIndicatorHeight="0dp"
        android:id="@+id/tl_layout_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMinWidth="130dp"
        app:tabMode="scrollable"
        ></android.support.design.widget.TabLayout>
</LinearLayout>

Avtivity:

public class TabLayoutText extends AppCompatActivity {
    private static final String TAG = "TabLayoutText";
    private TabLayout tabLayout;
    private List<String> stringsTitle = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tablayout_text_layout);
        tabLayout = findViewById(R.id.tl_layout_text);
        initData();
    }

    public void initData() {
        //在这边设置icon和text
        TabLayout.Tab tab1 = tabLayout.newTab();
        tab1.setText("个性推荐");
        stringsTitle.add("个性推荐");
        tab1.setIcon(R.drawable.fitst_tab);
        tabLayout.addTab(tab1);
        TabLayout.Tab tab2 = tabLayout.newTab();
        tab2.setText("歌单");
        stringsTitle.add("歌单");
        tab2.setIcon(R.drawable.two_tab);
        tabLayout.addTab(tab2);
        TabLayout.Tab tab3 = tabLayout.newTab();
        tab3.setText("主播电台");
        stringsTitle.add("主播电台");
        tab3.setIcon(R.drawable.fitst_tab);
        tabLayout.addTab(tab3);
        tabLayout.addTab(tabLayout.newTab().setText("排行榜").setIcon(R.drawable.two_tab));
        stringsTitle.add("排行榜");
        stringsTitle.add("排行榜");
        stringsTitle.add("排行榜");
        tabLayout.addTab(tabLayout.newTab().setText("排行榜").setIcon(R.drawable.two_tab));
        tabLayout.addTab(tabLayout.newTab().setText("排行榜").setIcon(R.drawable.two_tab));
        //在这里监听tablayout选中tab的事件
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabSelected: ");
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabSelected: ");
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabSelected: ");
            }
        });
    }
}

TabLayout基本属性:

  • app:tabBackground 设置Tabs的背景

例子:设为蓝色

  • app:tabGravity 为Tabs设置Gravity,有两个常量值,GRAVITY_CENTER,GRAVITY_FILL,app:tabGravity="center" 或者 app:tabGravity="fill" 值为center,Tabs就居中显示,fill 就充满TabLayout 。

这个只有tab加起来比屏幕宽度小的时候有用

  • app:tabIndicatorColor 设置指示器的颜色(默认情况下指示器的颜色为colorAccent)

  • app:tabIndicatorHeight 设置指示器的高度,Material Design 规范建议是2dp

  • app:tabMaxWidth 设置 Tab 的最大宽度

  • app:tabMinWidth 设置 Tab 的最小宽度

  • app:tabMode 设置Tabs的显示模式,有两个常量值,MODE_FIXED,MODE_SCROLLABLE。用法: app:tabMode="fixed" 或者 app:tabMode="scrollable" fixed 表示固定的Tab,scrollable 可滚动的Tab, Tab个数少的时候用 fixed,当Tab个数较多(大于四个或者5个)时用scrollable。 因为太少的话,使用scrollable右边会留空不好看。

  • app:tabPadding 这几个很简单设置Tab padding

app:tabPaddingTop

app:tabPaddingBottom

app:tabPaddingStart

app:tabPaddingEnd

  • app:tabSelectedTextColor 设置Tab选中后,文字显示的颜色

  • app:tabTextColor 设置Tab未选中,文字显示的颜色

  • tab选中问题:

如果是官方提供的tab,则去监听选中事件,重新设置icon或者文字

如果tab是自定义的view:

1、重写自定义view的:

@Override
public void setSelected(boolean selected) {
    super.setSelected(selected);
    // 更改文本颜色、图标、背景等等
}

2、通过drawable selector实现

Tab简单使用进阶——TabLayout+ViewPage+Fragment使用

XML布局:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <android.support.design.widget.TabLayout
        app:tabGravity="fill"
        app:tabBackground="@color/colorPrimary"
        app:tabIndicatorHeight="2dp"
        android:id="@+id/tl_layout_text"
        android:layout_width="match_parent"
        android:layout_height="110dp"
        app:tabMinWidth="130dp"
        app:tabMode="scrollable"
        ></android.support.design.widget.TabLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

    </android.support.v4.view.ViewPager>

</LinearLayout>

Activity代码:

public class TabLayoutText extends AppCompatActivity {
    private static final String TAG = "TabLayoutText";
    private TabLayout tabLayout;
    private ViewPager viewPager;
    private List<String> stringsTitle = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tablayout_text_layout);
        tabLayout = findViewById(R.id.tl_layout_text);
        viewPager = findViewById(R.id.view_pager);
        initData();
    }

    public void initData() {
        stringsTitle.add("个性推荐");
        stringsTitle.add("歌单");
        stringsTitle.add("主播电台");
        stringsTitle.add("排行榜");
        stringsTitle.add("排行榜");
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabSelected: ");
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabSelected: ");
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabSelected: ");
            }
        });
        List<Fragment> fragments = new ArrayList<>();
        TextFragment fragment1 = TextFragment.getInstance();
        fragments.add(fragment1);
        TextFragment fragment2 = TextFragment.getInstance();
        fragments.add(fragment2);
        TextFragment fragment3 = TextFragment.getInstance();
        fragments.add(fragment3);
        TextFragment fragment4 = TextFragment.getInstance();
        fragments.add(fragment4);
        TextFragment fragment5 = TextFragment.getInstance();
        fragments.add(fragment5);
        MyViewPageAdapter myViewPageAdapter = new MyViewPageAdapter(getSupportFragmentManager(), fragments, stringsTitle);
        viewPager.setAdapter(myViewPageAdapter);
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        tabLayout.setupWithViewPager(viewPager);
    }
}

适配器代码:

public class MyViewPageAdapter extends FragmentPagerAdapter {
    private List<Fragment> fragments;
    private List<String> stringsTitle;

    @Override
    public CharSequence getPageTitle(int position) {
        return stringsTitle.get(position);
    }

    public MyViewPageAdapter(FragmentManager fm, List<Fragment> fragments, List<String> stringsTitle) {
        super(fm);
        this.fragments = fragments;
        this.stringsTitle = stringsTitle;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments == null ? 0 : fragments.size();
    }
}


注意 :

如果你使用TabLayout+ViewPage 那么你在初始化TabLayout.settab是无效的,我们必须重写viewpage适配器里的getTitle返回的是tab的文字内容

Tip:

  • TabLayout+ViewPage如何使用自定义view或者官方set icon方法:

1、首先我们可以通过设置Tablayout的style来改变Tablayout的属性

<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
    <item name="tabMaxWidth">@dimen/tab_max_width</item>
    <item name="tabIndicatorColor">?attr/colorAccent</item>
    <item name="tabIndicatorHeight">2dp</item>
    <item name="tabPaddingStart">12dp</item>
    <item name="tabPaddingEnd">12dp</item>
    <item name="tabBackground">?attr/selectableItemBackground</item>
    <item name="tabTextAppearance">@style/MyCustomTabTextAppearance</item>
    <item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>
<style name="MyCustomTabTextAppearance" parent="TextAppearance.Design.Tab">
    <item name="android:textSize">14sp</item>
    <item name="android:textColor">?android:textColorSecondary</item>
    <item name="textAllCaps">true</item>
</style>

2、我们发现适配器的getTitle 返回一个CharSequence,因此我们这么写:

显示图片:

public CharSequence getPageTitle(int position) {
    Drawable drawable;
    switch (position) {
        case 0:
            drawable = ContextCompat.getDrawable(mContext, R.drawable.icon_weibo_timeline_public);
            break;
        case 1:
            drawable = ContextCompat.getDrawable(mContext, R.drawable.icon_weibo_timeline_friend);
            break;
        case 2:
            drawable = ContextCompat.getDrawable(mContext, R.drawable.icon_weibo_timeline_mine);
            break;
        default:
            drawable = ContextCompat.getDrawable(mContext, R.drawable.icon_weibo_timeline_public);
            break;
    }
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
    SpannableString spannableString = new SpannableString(" ");
    spannableString.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    return spannableString;
}

显示图文:

//在spannableString中追加文字
public CharSequence getPageTitle(int position) {
    Drawable drawable;
    String title;
    switch (position) {
        case 0:
            drawable = ContextCompat.getDrawable(mContext, R.drawable.icon_weibo_timeline_public);
            title = "广场";
            break;
        case 1:
            drawable = ContextCompat.getDrawable(mContext, R.drawable.icon_weibo_timeline_friend);
            title = "好友";
            break;
        case 2:
            drawable = ContextCompat.getDrawable(mContext, R.drawable.icon_weibo_timeline_mine);
            title = "我";
            break;
        default:
            drawable = ContextCompat.getDrawable(mContext, R.drawable.icon_weibo_timeline_public);
            title = "微博";
            break;
    }
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
    SpannableString spannableString = new SpannableString(" " + title);
    spannableString.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return spannableString;
}

注意:对于显示图片和显示图文:style中的 true要设置为false

显示自定义view:

//在活动的oncreate方法中
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mTimelineAdapter = new WeiboTimelineAdapter(mActvity, mActvity.getSupportFragmentManager());

    mViewPager.setAdapter(mTimelineAdapter);
    mTabLayout.setupWithViewPager(mViewPager);

    for (int i = 0; i < mTabLayout.getTabCount(); i++) {
        mTabLayout.getTabAt(i).setCustomView(mTimelineAdapter.getTabView(i));
    }
}

Tab简单使用进阶——Tab使用自定义view

XML布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="110dp">

    <ImageView
        android:id="@+id/image1"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_centerInParent="true"
        android:src="@drawable/dog" />

    <TextView
        android:id="@+id/text_view1"
        android:layout_below="@+id/image1"
        android:text="自定义布局"
        android:layout_margin="2dp"
        android:layout_width="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_height="wrap_content" />

</RelativeLayout>

自定义view代码:

public class MyCoustomView extends FrameLayout {
    private ImageView imageView;
    private TextView textView;

    public MyCoustomView(Context context) {
        super(context);
        init(context);
    }

    public MyCoustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        View view = View.inflate(context, R.layout.my_coustom_layout, this);
        imageView = view.findViewById(R.id.image1);
        textView = view.findViewById(R.id.text_view1);
    }

    public void setImageView(Drawable drawable) {
        imageView.setBackground(drawable);
    }

    public void setTextView(String text) {
        textView.setText(text);
    }
}

Tab使用自定义view

MyCoustomView myCoustomView = new MyCoustomView(this);
myCoustomView.setTextView("我是自定义view");
tabLayout.addTab((tabLayout.newTab().setCustomView(myCoustomView)));

注意事项: 自定义view的高度和tab的高度记得搭配,不然容易显示不完全自定义view的内容