android.support.design.widget.TabLayout
中实现通知徽章。我已尽最大努力去实现,但没有成功。非常感谢任何帮助。
android.support.design.widget.TabLayout
中实现通知徽章。我已尽最大努力去实现,但没有成功。非常感谢任何帮助。
编辑:更新
随着最新版本的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
将尝试从应用了CustomView
的视图中获取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);
}
}
我建议您查看这个网站:
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;
}
}
private BadgeView badge;
Tab tab = tabLayout.getTabAt(position);
ImageView imageView = new ImageView(context);
tab.setCustomView(imageView);
badge = new BadgeView(context, imageView);
tabLayout.getTabAt(0).getOrCreateBadge().setNumber(10);
这是一个老问题,但现在更加简单了。 我使用Kotlin和AndroidX,使用下一个小部件作为TabLayout:
com.google.android.material.tabs.TabLayout
我的gradle应用程序文件中:
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
}
}
我不知道为什么以上答案对我都不起作用 :(
我有一个自己的解决方案,可以制作出和 WhatsApp 相同带有标记的选项卡 :)
首先,创建一个名为 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>
<?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>
第三个选项卡颜色选择器
<?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();
}
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;
}
如果我在回答这个问题时漏掉了什么,请联系我,我很乐意帮忙 :D
2022年的工作答案
你好,虽然我回答有点晚了,但是现在使用Material组件,您不必寻找任何自定义视图或第三方库。
我正在使用com.google.android.material.tabs.TabLayout
和androidx.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)
只需使用这个技巧:
BadgeView bv1 = new BadgeView(this, ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(0));
binding.tabLayout.getTabAt(0)?.orCreateBadge?.number = 5
在 Kotlin 中,可以正常工作:
if(list.isNotEmpty()) {
mTlSaved.getTabAt(0)?.orCreateBadge?.number = list.size
}