25

我想用android.support.design.widget.TabLayout. 我已经尽了最大的努力来实现它,但失败了。

任何帮助将不胜感激。

4

11 回答 11

40

编辑:更新

随着 的最新版本Material Components,Android 团队现在提供了一个官方BadgeDrawable用于TabLayout实现所要求的结果。它是 v1.1.0-alpha07 更新的一部分。https://github.com/material-components/material-components-android/releases/tag/1.1.0-alpha07

用法非常简单,可以按如下方式进行:

tabLayout.getTabAt(0).showBadge().setNumber(1);

查看材料组件演示应用程序中的集成: https ://github.com/material-components/material-components-android/commit/111cd001f5302bd6899f181ab7ccea2fd4002f63#diff-bf3e9a8a208f0ecab05088823fba99c4R239


旧答案

我尝试了上面提到的一些解决方案,但它们没有提供正确的结果。如果您仔细查看TabLayout实现,您会发现TabView将尝试从CustomViewif 应用中获取 textView 和 iconView。

因此,我没有做一些 hacky 的实现,而是想出了一个与原始布局相同的布局,TabView而是一个可以有徽章的附加视图。

因此,您将需要 badged_tab.xml 布局

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

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        android:layout_marginTop="4dp">

        <ImageView
            android:id="@android:id/icon"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:scaleType="centerInside" />

        <TextView
            android:id="@android:id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:gravity="center"
            android:maxLines="2" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/badgeCotainer"
        android:layout_width="wrap_content"
        android:layout_height="16dp"
        android:layout_marginStart="12dp"
        android:background="@drawable/notifications_background"
        android:gravity="center"
        android:minWidth="16dp"
        android:visibility="gone">

        <TextView
            android:id="@+id/badge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAlignment="center"
            android:textColor="#fff"
            android:textSize="10sp" />
    </LinearLayout>
</RelativeLayout>

还有某种通知背景:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/red" />
</shape>

以编程方式添加标签时,只需调用

tab.setCustomView(R.layout.badged_tab);

然后您可以随时通过以下方式显示/隐藏/设置徽章数量:

if(tab != null && tab.getCustomView() != null) {
    TextView b = (TextView) tab.getCustomView().findViewById(R.id.badge);
    if(b != null) {
        b.setText(notifications + "");
    }
    View v = tab.getCustomView().findViewById(R.id.badgeCotainer);
    if(v != null) {
        v.setVisibility(View.VISIBLE);
    }
}
于 2016-11-08T17:33:59.203 回答
16

我建议你看看这个网站:

https://guides.codepath.com/android/Google-Play-Style-Tabs-using-TabLayout#design-support-library

您可以使用此方法遍历不同的选项卡并将自定义视图设置为您想要的任何内容:

  // Iterate over all tabs and set the custom view
    for (int i = 0; i < tabLayout.getTabCount(); i++) {
        TabLayout.Tab tab = tabLayout.getTabAt(i);
        tab.setCustomView(pagerAdapter.getTabView(i));
    }

public View getTabView(int position) {
    // Given you have a custom layout in `res/layout/custom_tab.xml` with a TextView and ImageView
    View v = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
    TextView tv = (TextView) v.findViewById(R.id.textView);
    tv.setText(tabTitles[position]);
    ImageView img = (ImageView) v.findViewById(R.id.imgView);
    img.setImageResource(imageResId[position]);
    return v;
}

}
于 2015-09-22T09:13:32.530 回答
6

我对此的解决方案是使用https://github.com/jgilfelt/android-viewbadger并为每个选项卡设置自定义视图:

我的标签只有图标,所以我使用了 ImageView,但我相信您可以使用任何其他视图,请查看https://github.com/jgilfelt/android-viewbadger/blob/master/README.markdown

private BadgeView badge;

Tab tab = tabLayout.getTabAt(position);
ImageView imageView = new ImageView(context);
tab.setCustomView(imageView);
badge = new BadgeView(context, imageView);
于 2015-10-01T14:17:21.617 回答
5

这是一个古老的提示,但如今它变得更加简单。我使用 Kotlin,AndroidX,使用下一个小部件作为 TabLayout:

com.google.android.material.tabs.TabLayout

在我的 Gradel 应用程序文件中:

implementation 'com.google.android.material:material:1.1.0-alpha09'

要设置一个简单的徽章,只需写..

yourTabLayout?.getTabAt(currentTabPosition)?.apply{
                        orCreateBadge
                        badge?.isVisible = true
                    }

然后只需设置 isVisible = false 即可隐藏,如下所示:

private fun changeYourTabMethod(newTabPosition : Int) {
    // do some stuff and then hide the badge...
    yourTabLayout?.getTabAt(newTabPosition)?.apply{
        badge?.isVisible = false
    }
}
于 2019-09-06T19:05:47.810 回答
5

我会用这个:

  tabLayout.getTabAt(0).getOrCreateBadge().setNumber(10);
于 2020-01-13T03:54:09.727 回答
3

我不知道为什么,但以上答案都不适合我:(

我有我自己的解决方案,它将制作与带有该徽章的 whatsapp 相同的 tablayout :)

首先将自定义选项卡布局设置为 custom_tab

<?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="48dp"
android:padding="12dp">

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Calls"
        android:textColor="@drawable/tab_text_color_selector"
        android:textSize="@dimen/large_text" />

    <TextView
        android:id="@+id/tv_count"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_marginLeft="6dp"
        android:background="@drawable/badge_background"
        android:gravity="center"
        android:text="99"
        android:textColor="@color/colorPrimary"
        android:textSize="@dimen/medium_text" />

</LinearLayout>

</RelativeLayout>

第二个badge_background

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item xmlns:android="http://schemas.android.com/apk/res/android">
    <shape android:shape="oval">
        <solid android:color="@drawable/tab_text_color_selector" />
    </shape>
</item>
</layer-list>

第三个 tab_color_selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:color="@color/colorTextPrimary"android:state_selected="true" />
<item android:color="@color/colorAccent"/>
 </selector>

活动中的第四名

    viewPager = (ViewPager) findViewById(R.id.viewpager);
    viewPager.setOffscreenPageLimit(3);
    setupViewPager(viewPager);

    //Initializing the tablayout
    tabLayout = (TabLayout) findViewById(R.id.tablayout);
    tabLayout.setupWithViewPager(viewPager);

    try
    {
        setupTabIcons();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

五、定义 setupTabIcons 和 prepareTabView 方法

  private void setupTabIcons()
{

    for(int i=0;i<tabTitle.length;i++)
    {
        /*TabLayout.Tab tabitem = tabLayout.newTab();
        tabitem.setCustomView(prepareTabView(i));
        tabLayout.addTab(tabitem);*/

        tabLayout.getTabAt(i).setCustomView(prepareTabView(i));
    }
    }

 String[] tabTitle={"LOL!","LOL@","LOL#"};
int[] unreadCount={1,3,3};

private View prepareTabView(int pos) {
    View view = getLayoutInflater().inflate(R.layout.custom_tab,null);
    TextView tv_title = (TextView) view.findViewById(R.id.tv_title);
    TextView tv_count = (TextView) view.findViewById(R.id.tv_count);
    tv_title.setText(tabTitle[pos]);
    if(unreadCount[pos]>0)
    {
        tv_count.setVisibility(View.VISIBLE);
        tv_count.setText(""+unreadCount[pos]);
    }
    else
        tv_count.setVisibility(View.GONE);


    return view;
    }

我可能在回答这个问题时留下了一些东西,只要 ping 我,我很乐意提供帮助:D

于 2016-12-25T10:54:57.307 回答
0

在科特林,作品:

if(list.isNotEmpty()) {
    mTlSaved.getTabAt(0)?.orCreateBadge?.number = list.size
}
于 2021-05-20T19:10:54.667 回答
0

只需使用这个技巧:

BadgeView bv1 = new BadgeView(this, ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(0));
于 2015-12-06T23:24:47.037 回答
0

答案在2022 年工作

您好,我回答得有点晚了,但是到目前为止,使用 Material 组件,您不必寻找任何自定义视图或第三方库

我正在使用com.google.android.material.tabs.TabLayoutandroidx.viewpager2.widget.ViewPager2它工作正常

val requestsTab = viewBinding.tabLayout.getTabAt(2)
            val orCreateBadge = requestsTab?.orCreateBadge
            orCreateBadge?.number=10
            orCreateBadge?.backgroundColor = resources.getColor(R.color.blue,context?.theme)
            orCreateBadge?.badgeTextColor =  resources.getColor(R.color.white,context?.theme)

样本

于 2022-03-04T09:12:44.437 回答
-1

我建议对标签使用 CustomView。您可以使用徽章创建一个新视图并将其设置为您的选项卡。

tab.setCustomView(R.layout.badged_tab);
于 2019-03-06T13:25:24.637 回答
-8

也有简单的方法。只需在后面附加一个特殊字符。它看起来就像whatsapp一样。

➀ ➁ ➂ ➃ ➄ ➅ ➆ ➇ ➈ ➉ ➊ ➋ ➌ ➍ ➎ ➏ ➐ ➑ ➒ ➓</p>

tabLayout.addTab(tabLayout.newTab().setText("News " + ➊));
于 2015-10-19T03:39:18.883 回答