TabLayout的高級使用


前言

前面介紹了TabLayout的基本屬性和基本的使用方法。我是傳送門

真實的業務場景中,很多的效果,原生的TabLayout,並不支持。例如下滑線短於文字的效果,底部導航欄效果,標簽文字選中是需要加粗效果等等。

所以我們需要使用TabLayout的自定義tab標簽。

先上圖。

先為急用的朋友上代碼,后面做講解

java類

import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.vp_all)
    ViewPager vpAll;
    @BindView(R.id.tab_custom)
    TabLayout tabCustom;

    //存放自定義tab標簽的列表
    List<View> customTabList = new ArrayList<>();
    //存放對應tab標簽的fragment頁面
    List<PageFragment> fgList = new ArrayList<>();
    //選中的自定義標簽,標記器。默認選中第一個。標記位是0;
    int indicator = 0;

    ViewPagerAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);//此處是用的是butterKnife框架,等同於findviewbyid獲取各個控件。
        initTabCustomAndViewPager();
        initListener();
    }

    /**
     * 初始化tab標簽和viewpager內容。
     */
    private void initTabCustomAndViewPager() {
        //初始化10個自定義tab標簽
        for (int i = 0; i < 10; i++) {
            final View tabView = getCustomTabView(this, "自定義" + i);
            customTabList.add(tabView);
            if (i==0){
                //設置默認第一個選中效果
                ((CheckBox) tabView.findViewById(R.id.cb_name)).setChecked(true);
                tabView.findViewById(R.id.cb_slide).setVisibility(View.VISIBLE);
            }
            tabCustom.addTab(tabCustom.newTab().setCustomView(tabView));
        }
        //初始化10個fragment頁面
        for (int i = 0; i < 10; i++) {
            fgList.add(PageFragment.newInstance("我是內容欄目" + i));
        }
        pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fgList);
        vpAll.setAdapter(pagerAdapter);
    }

    /**
     * 將viewpager和tabLayout之間的滑動事件和點擊事件關聯起來。
     * 此處不能使用tabLayout的setupWithViewPager()方法,否則會造成自定義view失效
     */
    private void initListener() {
        //添加關聯接口,此處不能用自帶的綁定方法,否則自定義view會失效
        vpAll.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i1) {
            }

            @Override
            public void onPageSelected(int i) {
                tabCustom.getTabAt(i).select();
            }

            @Override
            public void onPageScrollStateChanged(int i) {
            }
        });
        tabCustom.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //viewpager聯動
                vpAll.setCurrentItem(tab.getPosition());
                //將之前選中的tab標簽,設置為未選中狀態
                View oldView = customTabList.get(indicator);
                CheckBox oldCbName = (CheckBox) oldView.findViewById(R.id.cb_name);
                View oldCbSlide = oldView.findViewById(R.id.cb_slide);
                oldCbName.setChecked(false);
                oldCbSlide.setVisibility(View.INVISIBLE);
                //當前選中的tab標簽,設置為選中狀態。
                indicator = tab.getPosition();
                View newView = customTabList.get(indicator);
                CheckBox newCbName = (CheckBox) newView.findViewById(R.id.cb_name);
                View newCbSlide = newView.findViewById(R.id.cb_slide);
                newCbName.setChecked(true);
                newCbSlide.setVisibility(View.VISIBLE);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }
        });

    }

    /**
     * ViewPager的適配器。
     */
    class ViewPagerAdapter extends FragmentPagerAdapter {

        List<PageFragment> fragmentList;

        public ViewPagerAdapter(FragmentManager fm, List<PageFragment> fragmentList) {
            super(fm);
            this.fragmentList = fragmentList;
        }

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

        @Override
        public int getCount() {
            return fragmentList.size();
        }
    }

    /**
     * 獲取自定義Tab標簽的顯示的內容
     *
     * @param context
     * @param
     * @return
     */
    public static View getCustomTabView(Context context, String text) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_custom_tab, null);
        CheckBox tabText = (CheckBox) view.findViewById(R.id.cb_name);
        tabText.setText(text);
        return view;
    }
}

pageFragment的代碼和布局就不貼了。不想寫的朋友可以看上一篇:我是傳送門

布局文件

activity_main的布局文件

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.administrator.tablayoutdemo.MainActivity">
    <android.support.design.widget.TabLayout
        android:id="@+id/tab_custom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorHeight="0dp"
        app:tabMode="scrollable"
        />

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_all"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

自定義tab標簽的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:orientation="vertical"
    android:gravity="center"
    android:descendantFocusability="blocksDescendants">
    <CheckBox
        android:id="@+id/cb_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:button="@null"
        android:text=""
        android:textColor="@drawable/select_text_color"
        android:textSize="15sp"
        android:paddingTop="13dp"
        android:ellipsize="end"
        android:singleLine="true"
        android:maxEms="5"
        android:textStyle="bold"
        android:paddingBottom="13dp"
        android:clickable="false"
        />
    <View
        android:id="@+id/cb_slide"
        android:layout_width="20dp"
        android:layout_height="3dp"
        android:visibility="invisible"
        android:background="#ff4fbf86"/>

</LinearLayout>

色值文件select_text_color,放在drawable目錄下

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#ff4fbf86" android:state_checked="true"/>
    <item android:color="#BBBBBB" android:state_checked="false" />
</selector>

講解:

OK上完代碼,針對關鍵點在做一次說明

1、標簽在初始化的過程中,需要對第一個tab標簽提前進行選中狀態的初始化,否則可能會造成第一次啟動的時候,第一個標簽沒有出現選中狀態。

2、viewpager和TabLayout標簽進行聯動的時候,不可以使用TabLayout的setupWithViewPager()方法,而是要通過ViewPager的addOnPageChangeListener()和Tablayout的addOnTabSelectedListener()方法進行兩個控件之間的聯動效果。否則會造成自定義的CustomeTab被TabLayout默認生成的標簽覆蓋掉。

3、在布局文件中,需要將TabLayout的tabIndicatorHeight設為0。用來屏蔽掉控件自動生成的下滑線。

 

通過自定義的Tab標簽可以完全實現自己控制tab標簽的內容,這里就不展示tab標簽做為底部導航欄的效果了。原理都是一樣的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM