欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android原生TabLayout使用的超全解析(看這篇就夠了)

 更新時(shí)間:2022年09月03日 08:51:42   作者:yechaoa  
現(xiàn)在很多app都有頂部可左右切換的導(dǎo)航欄,并且還帶動畫效果,要實(shí)現(xiàn)這種導(dǎo)航欄,可以使用Android原生的Tablayout也可以借助第三方框架實(shí)現(xiàn),這篇文章主要給大家介紹了關(guān)于Android原生TabLayout使用的相關(guān)資料,需要的朋友可以參考下

前言

為什么會有這篇文章呢,是因?yàn)橹瓣P(guān)于TabLayout的使用陸陸續(xù)續(xù)也寫了好幾篇了,感覺比較分散,且不成體系,寫這篇文章的目的就是希望能把各種效果的實(shí)現(xiàn)一次性講齊,所以也有了標(biāo)題的「看這篇就夠了」。

TabLayout作為導(dǎo)航組件來說,使用場景非常的多,也意味著要滿足各種各樣的需求。

在效果實(shí)現(xiàn)上,有同學(xué)會選擇自定義View來做,定制性高,但易用性、穩(wěn)定性、維護(hù)性不敢保證,使用官方組件能避免這些不確定性,一是開源,有很多大佬共建,會不停的迭代;二是經(jīng)過大型app驗(yàn)證,比如google play;有了這兩點(diǎn),基本可以放心大膽的使用官方組件了。

那可能有的同學(xué)又會說,道理我都懂,可是不滿足需求啊,只能自定義了。是的,早期的api確實(shí)不夠豐富,在某些需求的實(shí)現(xiàn)上顯得捉襟見肘,但是google也在不斷的迭代,目前為止,常見的樣式都能滿足。

效果圖

簡介

  • TabLayout:一個(gè)橫向可滑動的菜單導(dǎo)航ui組件
  • Tab:TabLayout中的item,可以通過newTab()創(chuàng)建
  • TabView:Tab的實(shí)例,是一個(gè)包含ImageView和TextView的線性布局
  • TabItem:一種特殊的“視圖”,在TabLayout中可以顯式聲明Tab

官方文檔

功能拆解

Material Design 組件最新正式版依賴:

implementation 'com.google.android.material:material:1.5.0'

1.基礎(chǔ)實(shí)現(xiàn)

1.1 xml動態(tài)寫法

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        app:tabIndicatorColor="@color/colorPrimary"
        app:tabMaxWidth="200dp"
        app:tabMinWidth="100dp"
        app:tabMode="fixed"
        app:tabSelectedTextColor="@color/colorPrimary"
        app:tabTextColor="@color/gray" />

只寫一個(gè)Layout,item可以配合ViewPager來生成。

1.2 xml靜態(tài)寫法

 <com.google.android.material.tabs.TabLayout
         android:layout_height="wrap_content"
         android:layout_width="match_parent">

     <com.google.android.material.tabs.TabItem
             android:text="@string/tab_text"/>

     <com.google.android.material.tabs.TabItem
             android:icon="@drawable/ic_android"/>

 </com.google.android.material.tabs.TabLayout>

屬于固定寫法,比如我們非常確定item有幾個(gè),可以通過TabItem顯式聲明。

1.3 kotlin/java代碼寫法

    val tab = mBinding.tabLayout7.newTab()
    tab.text = it.key
    //...
    mBinding.tabLayout7.addTab(tab)

這種情況適合Tab的數(shù)據(jù)是動態(tài)的,比如接口數(shù)據(jù)回來之后,再創(chuàng)建Tab并添加到TabLayout中。

2.添加圖標(biāo)

mBinding.tabLayout2.getTabAt(index)?.setIcon(R.mipmap.ic_launcher)

獲取Tab然后設(shè)置icon。

Tab內(nèi)部其實(shí)是一個(gè)TextViewImageView,添加圖標(biāo)就是給ImageView設(shè)置icon。

3.字體大小、加粗

通過app:tabTextAppearance給TabLayout設(shè)置文本樣式

    <com.google.android.material.tabs.TabLayout
		...
        app:tabTextAppearance="@style/MyTabLayout"
		/>

style:

    <style name="MyTabLayout">
        <item name="android:textSize">20sp</item>
        <item name="android:textStyle">bold</item>
        <item name="android:textAllCaps">false</item>
    </style>

比如這里設(shè)置了字體大小和加粗。

默認(rèn)字體大小14sp

<dimen name="design_tab_text_size">14sp</dimen>

4.去掉Tab長按提示文字

長按Tab時(shí)會有一個(gè)提示文字,類似Toast一樣。

    /**
     * 隱藏長按顯示文本
     */
    private fun hideToolTipText(tab: TabLayout.Tab) {
        // 取消長按事件
        tab.view.isLongClickable = false
        // api 26 以上 設(shè)置空text
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
            tab.view.tooltipText = ""
        }
    }

可以取消長按事件,在api26以上也可以設(shè)置提示文本為空。

5.去掉下劃線indicator

app:tabIndicatorHeight="0dp"

設(shè)置高度為0即可。

注意,單純設(shè)置tabIndicatorColor為透明,其實(shí)不準(zhǔn)確,默認(rèn)還是有2dp的,根本瞞不過射雞師的眼睛。

6.下劃線的樣式

通過app:tabIndicator可以設(shè)置自定義的樣式,比如通過shape設(shè)置圓角和寬度。

    <com.google.android.material.tabs.TabLayout
        ...
        app:tabIndicator="@drawable/shape_tab_indicator"
        app:tabIndicatorColor="@color/colorPrimary"
		/>

注意:Indicator的顏色在shape中設(shè)置是無效的,需要通過app:tabIndicatorColor設(shè)置才可以

shape:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:width="15dp"
        android:height="5dp"
        android:gravity="center">
        <shape>
            <corners android:radius="5dp" />
            <!--color無效,源碼用tabIndicatorColor-->
            <solid android:color="@color/colorPrimary" />
        </shape>
    </item>
</layer-list>

7.下劃線的寬度

默認(rèn)情況下,tabIndicator的寬度是填充整個(gè)Tab的,比如上圖中的第一個(gè),我們可以簡單的設(shè)置不填充,與文本對齊,即第二個(gè)效果

app:tabIndicatorFullWidth="false"

也可以像上一節(jié)那樣,通過shape自定義tabIndicator的寬度。

8.Tab分割線

  /** A {@link LinearLayout} containing {@link Tab} instances for use with {@link TabLayout}. */
  public final class TabView extends LinearLayout {
  }

通過源碼可以看到內(nèi)部實(shí)現(xiàn)TabView繼承至LinearLayout,我們知道LinearLayout是可以給子view設(shè)置分割線的,那我們就可以通過遍歷來添加分割線

        //設(shè)置 分割線
        for (index in 0..mBinding.tabLayout4.tabCount) {
            val linearLayout = mBinding.tabLayout4.getChildAt(index) as? LinearLayout
            linearLayout?.let {
                it.showDividers = LinearLayout.SHOW_DIVIDER_MIDDLE
                it.dividerDrawable = ContextCompat.getDrawable(this, R.drawable.shape_tab_divider)
                it.dividerPadding = 30
            }
        }

shape_tab_divider:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorPrimary" />
    <size android:width="1dp" android:height="10dp" />
</shape>

9.TabLayout樣式

上圖中的效果其實(shí)是TabLayout樣式+tabIndicator樣式形成的一個(gè)「整體」的效果。

TabLayout是兩邊半圓的一個(gè)長條,這個(gè)我們通過編寫shape設(shè)置給其背景即可實(shí)現(xiàn)。

shape_tab_bg:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="999dp" />
    <solid android:color="@color/colorPrimary" />
</shape>

這個(gè)效果的關(guān)鍵在于tabIndicator的高度與TabLayout的高度相同,所以二者高度設(shè)置一致即可。

shape_full_tab_indicator:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:gravity="center" android:top="0.5dp" android:bottom="0.5dp">
        <shape>
            <!-- 上下邊距合計(jì)1dp 高度減少1dp -->
            <size android:height="41dp" />
            <corners android:radius="999dp" />
            <solid android:color="@color/white" />
        </shape>
    </item>
</layer-list>

TabLayout:

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout6"
        android:layout_width="wrap_content"
        android:layout_height="42dp"
        android:layout_gravity="center"
        android:layout_marginTop="10dp"
        android:background="@drawable/shape_tab_bg"
        app:tabIndicator="@drawable/shape_full_tab_indicator"
        app:tabIndicatorColor="@color/white"
        app:tabIndicatorFullWidth="true"
        app:tabIndicatorHeight="42dp"
        app:tabMinWidth="96dp"
        app:tabMode="fixed"
        app:tabSelectedTextColor="@color/colorPrimary"
        app:tabTextColor="@color/black" />

10.Tab添加小紅點(diǎn)

添加小紅點(diǎn)的功能還是比較常見的,好在TabLayout也提供了這種能力,其實(shí)添加起來也非常簡單,難在未知。

可以設(shè)置帶數(shù)字的紅點(diǎn),也可以設(shè)置沒有數(shù)字單純的一個(gè)點(diǎn)。

通過getOrCreateBadge可以對紅點(diǎn)進(jìn)行簡單的配置:

        // 數(shù)字
        mBinding.tabLayout5.getTabAt(defaultIndex)?.let { tab ->
            tab.orCreateBadge.apply {
                backgroundColor = Color.RED
                maxCharacterCount = 3
                number = 99999
                badgeTextColor = Color.WHITE
            }
        }

        // 紅點(diǎn)
        mBinding.tabLayout5.getTabAt(1)?.let { tab ->
            tab.orCreateBadge.backgroundColor = ContextCompat.getColor(this, R.color.orange)
        }

getOrCreateBadge實(shí)際上是獲取或創(chuàng)建BadgeDrawable。

通過源碼發(fā)現(xiàn),BadgeDrawable除了TabLayout引用之外,還有NavigationBarItemView、NavigationBarMenuView、NavigationBarView,意味著它們也同樣具備著小紅點(diǎn)這種能力。其實(shí)別的view也是可以具備的。

關(guān)于小紅點(diǎn)這里就不展開了,非常推薦查看我之前寫的這篇:【漲姿勢】你沒用過的BadgeDrawable

11.獲取隱藏的Tab

上一節(jié)中我們實(shí)現(xiàn)了小紅點(diǎn)效果,那如果一屏顯示不夠的情況下,如何提示未展示的信息呢,比如上面我們?nèi)绾伟盐达@示的tab且有數(shù)字的Tab提示出來呢?常見的解決方案都是在尾部加一個(gè)紅點(diǎn)提示。

那么問題來了,如何判斷某一個(gè)Tab是否可見呢,翻看了源碼,可惜并沒有提供相應(yīng)的api,那只能我們自己實(shí)現(xiàn)了。

我們前面添加小紅點(diǎn)是根據(jù)Tab添加的,Tab內(nèi)部實(shí)現(xiàn)也是一個(gè)view,那view就可以判斷其是否可見。

    private fun isShowDot(): Boolean {
        var showIndex = 0
        var tipCount = 0
        companyMap.keys.forEachIndexed { index, _ ->
            mBinding.tabLayout7.getTabAt(index)?.let { tab ->
                val tabView = tab.view as LinearLayout
                val rect = Rect()
                val visible = tabView.getLocalVisibleRect(rect)
                // 可見范圍小于80%也在計(jì)算范圍之內(nèi),剩下20%寬度足夠紅點(diǎn)透出(可自定義)
                if (visible && rect.right > tab.view.width * 0.8) {
                    showIndex = index
                } else {
                    //if (index > showIndex) // 任意一個(gè)有count的tab隱藏就會顯示,比如第一個(gè)在滑動過程中會隱藏,也在計(jì)算范圍之內(nèi)
                    if (index > lastShowIndex) { // 只檢測右側(cè)隱藏且有count的tab 才在計(jì)算范圍之內(nèi)
                        tab.badge?.let { tipCount += it.number }
                    }
                }

            }
        }
        lastShowIndex = showIndex
        return tipCount > 0
    }

上面的方法中就是判斷是否需要顯示右側(cè)提示的小紅點(diǎn)。

計(jì)算規(guī)則:Tab不可見,且Tab上的紅點(diǎn)數(shù)字大于0的即在計(jì)算范圍之內(nèi)。

這里有一個(gè)優(yōu)化的點(diǎn),比如上圖中的“騰訊”Tab,它是可見的,但是紅點(diǎn)不可見,那么問題就來了,如果我們沒有提示到,是很容易產(chǎn)生客訴的,所以這里在計(jì)算的時(shí)候也加了一個(gè)條件,就是可見范圍小于80%也在計(jì)算范圍之內(nèi),剩下20%的寬度是足夠Tab上的紅點(diǎn)透出的(也可自定義)。

同時(shí)在TabLayout滑動的過程中也應(yīng)該加上判斷顯示的邏輯:

        // mBinding.tabLayout7.setOnScrollChangeListener() // min api 23 (6.0)
        // 適配 5.0  滑動過程中判斷右側(cè)小紅點(diǎn)是否需要顯示
        mBinding.tabLayout7.viewTreeObserver.addOnScrollChangedListener {
            mBinding.vArrowDot.visibility = if (isShowDot()) View.VISIBLE else View.INVISIBLE
        }

還有初始化時(shí)的判斷邏輯:

    override fun onResume() {
        super.onResume()
        // 初始化判斷右側(cè)小紅點(diǎn)是否需要顯示
        mBinding.tabLayout7.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                mBinding.vArrowDot.visibility = if (isShowDot()) View.VISIBLE else View.INVISIBLE
                mBinding.tabLayout7.viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        })
    }

12.Tab寬度自適應(yīng)

細(xì)心的同學(xué)會發(fā)現(xiàn),這個(gè)TabLayout的item左右間距都是一樣的,不管標(biāo)題是兩個(gè)字還是四個(gè)字的,左右間距都是相等的,而實(shí)際上的效果是兩個(gè)字的Tab要比四個(gè)字的Tab左右間距要大一些的,那這個(gè)效果是怎么實(shí)現(xiàn)的呢?

實(shí)際上是我們設(shè)置了tabMinWidth

app:tabMinWidth="50dp"

源碼中默認(rèn)的是:

  private int getTabMinWidth() {
    if (requestedTabMinWidth != INVALID_WIDTH) {
      // If we have been given a min width, use it
      return requestedTabMinWidth;
    }
    // Else, we'll use the default value
    return (mode == MODE_SCROLLABLE || mode == MODE_AUTO) ? scrollableTabMinWidth : 0;
  }
  • requestedTabMinWidth是根據(jù)xml設(shè)置獲取的。
  • 假如xml沒設(shè)置tabMinWidth的情況下,且tabMode是scrollable的情況下,會返回默認(rèn)配置,否則為0,即tabMode為fixed的情況。

系統(tǒng)默認(rèn)配置scrollableTabMinWidth:

<dimen name="design_tab_scrollable_min_width">72dp</dimen>

在兩個(gè)字和四個(gè)字的標(biāo)題都存在的情況下,兩個(gè)字用這個(gè)默認(rèn)寬度就會有多余的間距,所以會出現(xiàn)間距不均等的情況,通過設(shè)置覆蓋默認(rèn)即可解決。

13.自定義Item View

前面講到Tab內(nèi)部實(shí)現(xiàn)是一個(gè)View,那我們就可以通過官方提供api(setCustomView)來自定義這個(gè)view。

setCustomView的兩種方式:

  • public Tab setCustomView(@Nullable View view)
  • public Tab setCustomView(@LayoutRes int resId)

我們先編寫一個(gè)自定義的布局文件,布局文件比較簡單,一個(gè)LottieAnimationView和TextView。

再通過Tab添加進(jìn)去即可。

        val animMap = mapOf("party" to R.raw.anim_confetti, "pizza" to R.raw.anim_pizza, "apple" to R.raw.anim_apple)

        animMap.keys.forEach { s ->
            val tab = mBinding.tabLayout8.newTab()
            val view = LayoutInflater.from(this).inflate(R.layout.item_tab, null)
            val imageView = view.findViewById<LottieAnimationView>(R.id.lav_tab_img)
            val textView = view.findViewById<TextView>(R.id.tv_tab_text)
            imageView.setAnimation(animMap[s]!!)
            imageView.setColorFilter(Color.BLUE)
            textView.text = s
            tab.customView = view
            mBinding.tabLayout8.addTab(tab)
        }

14.使用Lottie

Lottie是一個(gè)可以在多平臺展示動畫的庫,相信很多同學(xué)都已經(jīng)用過了,就不詳細(xì)展開了,感興趣的可以查看Lottie官方文檔。

Lottie依賴:

implementation "com.airbnb.android:lottie:5.0.1"

上一節(jié)中我們實(shí)現(xiàn)了自定義TabLayout的Item View,在這個(gè)自定義的布局中,我們用LottieAnimationView來承載動畫的展示。

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/item_tab"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/lav_tab_img"
        android:layout_width="30dp"
        android:layout_height="30dp"
        app:lottie_colorFilter="@color/black"
        app:lottie_rawRes="@raw/anim_confetti" />

    <TextView
        android:id="@+id/tv_tab_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        android:textColor="@color/black"
        android:textSize="14sp" />

</androidx.appcompat.widget.LinearLayoutCompat>

添加的方式也在上一節(jié)中講過了,我們只需要控制好選中、未選中的狀態(tài)即可。

        mBinding.tabLayout8.addOnTabSelectedListener(object : OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                tab?.setSelected()
                tab?.let { mBinding.viewPager.currentItem = it.position }
            }

            override fun onTabUnselected(tab: TabLayout.Tab?) {
                tab?.setUnselected()
            }

            override fun onTabReselected(tab: TabLayout.Tab?) {

            }
        })

這里通過兩個(gè)擴(kuò)展方法分別處理不同的狀態(tài)。

選中狀態(tài),播放動畫并設(shè)置icon顏色

    /**
     * 選中狀態(tài)
     */
    fun TabLayout.Tab.setSelected() {
        this.customView?.let {
            val textView = it.findViewById<TextView>(R.id.tv_tab_text)
            val selectedColor = ContextCompat.getColor(this@TabLayoutActivity, R.color.colorPrimary)
            textView.setTextColor(selectedColor)

            val imageView = it.findViewById<LottieAnimationView>(R.id.lav_tab_img)
            if (!imageView.isAnimating) {
                imageView.playAnimation()
            }
            setLottieColor(imageView, true)
        }
    }

未選中狀態(tài),停止動畫并還原初始狀態(tài),然后設(shè)置icon顏色

    /**
     * 未選中狀態(tài)
     */
    fun TabLayout.Tab.setUnselected() {
        this.customView?.let {
            val textView = it.findViewById<TextView>(R.id.tv_tab_text)
            val unselectedColor = ContextCompat.getColor(this@TabLayoutActivity, R.color.black)
            textView.setTextColor(unselectedColor)

            val imageView = it.findViewById<LottieAnimationView>(R.id.lav_tab_img)
            if (imageView.isAnimating) {
                imageView.cancelAnimation()
                imageView.progress = 0f // 還原初始狀態(tài)
            }
            setLottieColor(imageView, false)
        }
    }

關(guān)于修改lottie icon的顏色,目前網(wǎng)上的答案參差不齊,還是源碼來的直接。

源碼:

    if (ta.hasValue(R.styleable.LottieAnimationView_lottie_colorFilter)) {
      int colorRes = ta.getResourceId(R.styleable.LottieAnimationView_lottie_colorFilter, -1);
      ColorStateList csl = AppCompatResources.getColorStateList(getContext(), colorRes);
      SimpleColorFilter filter = new SimpleColorFilter(csl.getDefaultColor());
      KeyPath keyPath = new KeyPath("**");
      LottieValueCallback<ColorFilter> callback = new LottieValueCallback<>(filter);
      addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback);
    }

所以直接借鑒即可:

    /**
     * set lottie icon color
     */
    private fun setLottieColor(imageView: LottieAnimationView?, isSelected: Boolean) {
        imageView?.let {
            val color = if (isSelected) R.color.colorPrimary else R.color.black
            val csl = AppCompatResources.getColorStateList(this@TabLayoutActivity, color)
            val filter = SimpleColorFilter(csl.defaultColor)
            val keyPath = KeyPath("**")
            val callback = LottieValueCallback<ColorFilter>(filter)
            it.addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback)
        }
    }

動畫文件的下載網(wǎng)站推薦: lordicon

15.關(guān)聯(lián)ViewPager

15.1 編寫FragmentPagerAdapter

    private inner class SimpleFragmentPagerAdapter constructor(fm: FragmentManager) :
        FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {

        private val tabTitles = arrayOf("Android", "Kotlin", "Flutter")
        private val fragment = arrayOf(Fragment1(), Fragment2(), Fragment3())

        override fun getItem(position: Int): Fragment {
            return fragment[position]
        }

        override fun getCount(): Int {
            return fragment.size
        }

        override fun getPageTitle(position: Int): CharSequence {
            return tabTitles[position]
        }
    }

15.2 給ViewPager設(shè)置Adapter

mBinding.viewPager.adapter = SimpleFragmentPagerAdapter(supportFragmentManager)

15.3 給TabLayout關(guān)聯(lián)ViewPager

mBinding.tabLayout1.setupWithViewPager(mBinding.viewPager)

以上即可把TabLayoutViewPager關(guān)聯(lián)起來,TabLayout的Tab也會由FragmentPagerAdapter中的標(biāo)題自動生成。

15.4 setupWithViewPager源碼分析

究竟是怎么關(guān)聯(lián)起來的呢?

下面是setupWithViewPager中的部分源碼:

        if (viewPager != null) {
            this.viewPager = viewPager;
            if (this.pageChangeListener == null) {
            	// 步驟1
                this.pageChangeListener = new TabLayout.TabLayoutOnPageChangeListener(this);
            }

            this.pageChangeListener.reset();
            viewPager.addOnPageChangeListener(this.pageChangeListener);
            // 步驟2
            this.currentVpSelectedListener = new TabLayout.ViewPagerOnTabSelectedListener(viewPager);
            // 步驟3
            this.addOnTabSelectedListener(this.currentVpSelectedListener);
            PagerAdapter adapter = viewPager.getAdapter();
            if (adapter != null) {
                this.setPagerAdapter(adapter, autoRefresh);
            }

            if (this.adapterChangeListener == null) {
                this.adapterChangeListener = new TabLayout.AdapterChangeListener();
            }

            this.adapterChangeListener.setAutoRefresh(autoRefresh);
            // 步驟4
            viewPager.addOnAdapterChangeListener(this.adapterChangeListener);
            this.setScrollPosition(viewPager.getCurrentItem(), 0.0F, true);
        }
  1. 先是創(chuàng)建了TabLayout.TabLayoutOnPageChangeListener,并設(shè)置給了viewPager.addOnPageChangeListener。
  2. 然后又創(chuàng)建了TabLayout.ViewPagerOnTabSelectedListener(viewPager),并傳入當(dāng)前viewPager,然后設(shè)置給了addOnTabSelectedListener。
  3. 所以,經(jīng)過這種你來我往的操作之后,設(shè)置TabLayout的選中下標(biāo)和設(shè)置ViewPager的選中下標(biāo),其實(shí)效果是一毛一樣的,因?yàn)槁?lián)動起來了…

另外,F(xiàn)ragmentPagerAdapter已經(jīng)廢棄了,官方推薦使用viewpager2FragmentStateAdapter 代替。

Deprecated Switch to androidx.viewpager2.widget.ViewPager2 and use androidx.viewpager2.adapter.FragmentStateAdapter instead.

16.常用API整理

16.1 TabLayout

API含義
backgroundTabLayout背景顏色
tabIndicator指示器(一般下劃線)
tabIndicatorColor指示器顏色
tabIndicatorHeight指示器高度,不顯示寫0dp
tabIndicatorFullWidth指示器寬度是否撐滿item
tabModetab顯示形式,1.auto自動,2.fixed固定寬度,3.scrollable可滑動
tabSelectedTextColortab選中文字顏色
tabTextColortab未選中文字顏色
tabRippleColortab點(diǎn)擊效果顏色
tabGravitytab對齊方式
tabTextAppearancetab文本樣式,可引用style
tabMaxWidthtab最大寬度
tabMinWidthtab最小寬度
setupWithViewPagertabLayout關(guān)聯(lián)ViewPager
addOnTabSelectedListenertab選中監(jiān)聽事件

16.2 TabLayout.Tab

API含義
setCustomView設(shè)置tab自定義view
setIcon設(shè)置tab icon
setText設(shè)置tab文本
getOrCreateBadge獲取或創(chuàng)建badge(小紅點(diǎn))
removeBadge移除badge(小紅點(diǎn))
select設(shè)置tab選中
isSelected獲取tab選中狀態(tài)

16.3 BadgeDrawable

API含義
setVisible設(shè)置顯示狀態(tài)
setBackgroundColor設(shè)置小紅點(diǎn)背景顏色
getBadgeTextColor設(shè)置小紅點(diǎn)文本顏色
setNumber設(shè)置小紅點(diǎn)顯示數(shù)量
clearNumber清除小紅點(diǎn)數(shù)量
setBadgeGravity設(shè)置小紅點(diǎn)位置對齊方式

https://github.com/yechaoa/MaterialDesign

最后

到此這篇關(guān)于Android原生TabLayout使用解析的文章就介紹到這了,更多相關(guān)Android原生TabLayout使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論