web-dev-qa-db-ja.com

Android whatsAppのような通知バッジのあるタブレイアウトタブ

Android.support.design.widget.TabLayoutで通知バッジを実装したい。私はそれを実装するために最善を尽くしましたが、失敗しました。

どんな助けでも大歓迎です。

17
Arjun sharma

これに対する私の解決策は、 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);
5
lucas_sales

編集:更新

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の実装を詳しく見ると、TabViewCustomViewからtextViewとiconViewを取得しようとしていることがわかります(適用されている場合)。

そのため、いくつかのハッキーな実装を行う代わりに、元の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);
    }
}
26
mikepenz

このウェブサイトをご覧になることをお勧めします。

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;
}

}
16
Simon

理由はわかりませんが、上記の答えはどれも私にとってはうまくいきませんでした:(

私はそのバッジで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>

第二に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>

3番目の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>

活動の4番目

    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();
    }

5番目の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;
    }

私はこの質問に答えるときに何かを残したかもしれません。

2
codepeaker

これは古い手がかりですが、最近ではずっと簡単です。次のウィジェットをTabLayoutとして使用して、Kotlin、AndroidXを使用しています。

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
    }
}
0
markomoreno

タブにはCustomViewを使用することをお勧めします。バッジ付きの新しいビューを作成し、それをタブに設定できます。

tab.setCustomView(R.layout.badged_tab);
0
Majid Khosravi

このトリックを使用してください:

BadgeView bv1 = new BadgeView(this, ((ViewGroup) tabLayout.getChildAt(0)).getChildAt(0));
0
Navidonline