如何在NavigationView中设置徽章?

5

我使用来自design库的NavigationDrawer

compile 'com.android.support:design:24.0.0'

这里有XML

....

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main_second"
    app:menu="@menu/activity_third_drawer" />

....

我正在设置菜单的位置。

app:menu="@menu/activity_third_drawer"

这里有一个菜单的XML

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

<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_inbox"
        android:icon="@drawable/ic_mail_outline_white"
        android:title="@string/inbox" />
    <item
        android:id="@+id/nav_gallery"
        android:icon="@drawable/ic_close_24dp"
        android:title="@string/gallery" />
    <item
        android:id="@+id/nav_slideshow"
        android:icon="@drawable/ic_close_24dp"
        android:title="@string/slideshow" />
    <item
        android:id="@+id/nav_manage"
        android:icon="@drawable/ic_close_24dp"
        android:title="@string/tools" />
</group>

<item android:title="@string/about_app">
    <menu>
        <item
            android:id="@+id/nav_about"
            android:icon="@drawable/ic_close_24dp"
            android:title="@string/about1" />
    </menu>
</item>
</menu>

最终结果应该是这样的:

введите сюда описание изображения

但我需要当邮件到达收件箱时,它应该在NavigationDrawer中被标记。
像这样:

введите сюда описание изображения

有很多不同的库可以帮助解决这个问题,我选择了这个库
这个库可以在你想要的任何地方附加徽章,但是没有一个示例告诉你如何将其附加到<item>。最接近的示例是如何附加到XML
<com.readystatesoftware.viewbadger.BadgeView
            android:id="@+id/badge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="OK" />

但我仍然不知道如何将它附加到<item>

也许还有其他的解决方案可以做到这一点?

我已经尝试过这种方式。

View menuItemView = MenuItemCompat.getActionView(navigationView.getMenu().findItem(R.id.nav_inbox));
    BadgeView badge = new BadgeView(context, menuItemView);
    badge.setText("1");
    badge.show();

但每次我遇到 menuItemView = null 的情况。

然后我尝试了以下方法:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    View menuItemView = MenuItemCompat.getActionView(menu.findItem(R.id.nav_inbox));
    BadgeView badge = new BadgeView(context, menuItemView);
    badge.setText("1");
    badge.show();

    return super.onPrepareOptionsMenu(menu);
}

但它是相同的menuItemView = null

Debag

введите сюда описание изображения

我做错了什么?

编辑

我的NavigationView

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main_second"
    app:menu="@menu/activity_third_drawer" />

我的菜单

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<group android:checkableBehavior="single">

    <item
        android:id="@+id/nav_inbox"
        android:icon="@drawable/ic_inbox_checked"
        android:title="Inbox"
        app:actionLayout="@layout/badge" />

</group>

<item android:title="@string/about_app">
    <menu>
        <item
            android:id="@+id/nav_about"
            android:icon="@drawable/ic_close_24dp"
            android:title="@string/about1" />
    </menu>
</item>
</menu>

我的徽章

<?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="match_parent">

<TextView
    android:id="@+id/textMenuItemCount"
    android:layout_width="wrap_content"
    android:text="rrrr"
    android:layout_height="wrap_content"
    android:layout_alignParentEnd="true"
    android:textColor="@android:color/holo_blue_light"
    android:textStyle="bold"
    android:textSize="16sp"
    android:alpha="0.6"/>
</RelativeLayout>

这是我的代码

@Override
protected void onResume() {
    super.onResume();
    NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
    MenuItem item = navView.getMenu().findItem(R.id.nav_inbox);
    MenuItemCompat.setActionView(item, R.layout.badge);
    RelativeLayout notifCount = (RelativeLayout) MenuItemCompat.getActionView(item);
    TextView tv = (TextView) notifCount.findViewById(R.id.textMenuItemCount);

    String count = "4";
    if (count != null) {
        tv.setText(count);
    }else{
        tv.setText("");
        item.setEnabled(false);
    }
}

这是截图调试

enter image description here

这是我最终得到的结果

enter image description here

虽然没有错误,但在调试模式下一切正常,但我看不到任何徽章。

我做错了什么?


最终我使用了这个库 https://github.com/mikepenz/MaterialDrawer - Sirop4ik
1个回答

5
使用自定义布局来设置菜单项。
activity_layout.xml
<?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/myCoordinatorLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">


        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                />
        </android.support.design.widget.AppBarLayout>

        <android.support.v4.widget.DrawerLayout
            android:id="@+id/drawer_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:focusableInTouchMode="true">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="top">

                <android.support.v7.widget.RecyclerView
                    android:layout_height="match_parent"
                    android:layout_width="match_parent"
                    android:id="@+id/rv_venues"
                    android:layout_below="@+id/linearLayout" />

                <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/linearLayout"
                    android:gravity="right|end"
                    android:padding="0dp"
                    android:visibility="visible"
                    android:layout_alignParentRight="false">

                    <ImageButton
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:id="@+id/btnSearchVenues"
                        android:background="@drawable/custom_btn_overlay"
                        android:src="@drawable/ic_action_search"
                        android:layout_weight="1"
                        android:paddingRight="10dp"
                        android:paddingLeft="10dp" />

                    <ImageButton
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:id="@+id/btnSort"
                        android:background="@drawable/custom_btn_overlay"
                        android:src="@drawable/ic_action_filter"
                        android:layout_weight="1"
                        android:paddingLeft="10dp"
                        android:paddingRight="10dp" />

                    <ImageButton
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:id="@+id/btnMap"
                        android:background="@drawable/custom_btn_overlay"
                        android:src="@drawable/ic_dialog_map"
                        android:layout_weight="1"
                        android:paddingLeft="10dp"
                        android:paddingRight="10dp" />

                </LinearLayout>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/poweredBy"
                    android:id="@+id/textView9"
                    android:layout_alignParentBottom="true"
                    android:layout_alignParentLeft="true"
                    android:layout_alignParentStart="true"
                    android:textSize="8sp"
                    android:padding="2dp"
                    android:textStyle="bold"
                    android:textColor="#793f6edc" />

            </RelativeLayout>

            <android.support.design.widget.NavigationView
                android:id="@+id/navView"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_gravity="start"
                android:background="@android:color/white"
                app:headerLayout="@layout/nav_header"
                app:menu="@menu/menu_drawer" >
        </android.support.design.widget.NavigationView>


        </android.support.v4.widget.DrawerLayout>

    </LinearLayout>


        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/action_search"
            android:layout_gravity="bottom|right|end"
            android:layout_marginBottom="16dp"
            android:layout_marginRight="16dp"
            android:src="@drawable/pin_map"
            app:elevation="6dp"
            app:borderWidth="0dp"
            app:pressedTranslationZ="12dp"
            app:backgroundTint="@android:color/holo_green_light"
            app:rippleColor="@android:color/holo_green_dark"
            app:fabSize="normal"/>


    </android.support.design.widget.CoordinatorLayout>

menu_drawer.xml

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

        <group android:id="@+id/group_settings_id0">
        <item android:title="@string/btnFriends"
            android:id="@+id/nav_item_friends"
            android:actionLayout="@layout/navlist"
            android:icon="@drawable/ic_action_circles"/>

        <item android:title="@string/btnPhotos"
            android:id="@+id/nav_item_photos"
            android:actionLayout="@layout/navlist"
            android:icon="@drawable/ic_action_camera"/>

        <item android:title="@string/btnCheckins"
            android:id="@+id/nav_item_checkins"
            android:actionLayout="@layout/navlist"
            android:icon="@drawable/ic_action_location"/>
        </group>

        <group android:id="@+id/group_settings_id1">
            <item android:id="@+id/nav_item_find_people"
                android:title="@string/action_find_people"
                android:icon="@drawable/ic_action_search"/>
        </group>

        <group android:id="@+id/group_settings_id2">
            <item android:id="@+id/nav_item_about"
                android:title="@string/action_about"
                android:icon="@drawable/ic_action_info"/>
            <item android:id="@+id/nav_item_help"
                android:title="@string/action_help"
                android:icon="@android:drawable/ic_menu_help"/>
            <item android:id="@+id/nav_item_logout"
                android:title="@string/action_logout"
                android:icon="@drawable/ic_action_exit"/>
        </group>
   </menu>

badge.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="48dp"
    android:layout_height="fill_parent"
    android:layout_gravity="end"
    android:gravity="center">


    <TextView
        android:id="@+id/textMenuItemCount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:textColor="@android:color/black"
        android:textStyle="bold"
        android:textSize="16sp"
        android:alpha="0.6"/>

</RelativeLayout>

在你的Activity中:

在onCreate方法中:

mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mNavigationView = (NavigationView) findViewById(R.id.navView);


mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.app_name,
        R.string.app_name) {

    /**
     * Called when a drawer has settled in a completely closed state.
     */
    public void onDrawerClosed(View view) {
        super.onDrawerClosed(view);
        fab.show();
    }

    /**
     * Called when a drawer has settled in a completely open state.
     */
    public void onDrawerOpened(View drawerView) {
        super.onDrawerOpened(drawerView);
        fab.hide();
    }
};

mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();

//在任何时候想要更新徽章时调用

public void updateNavView(NavigationView navView, int resId, String count){
    MenuItem item = navView.getMenu().findItem(resId); //ex. R.id.nav_item_friends
        //MenuItemCompat.setActionView(item, R.layout.badge);
        RelativeLayout notifCount = (RelativeLayout) MenuItemCompat.getActionView(item);
        TextView tv = (TextView) notifCount.findViewById(R.id.textMenuItemCount);

        if (count != null) {
            tv.setText(count);
        }else{
            tv.setText("");
            item.setEnabled(false);
        }
}

结果如下:

enter image description here

最后它对我不起作用(( - Sirop4ik
你试过我的代码了吗?有什么结果或错误吗? - ugur
请问您能否编辑一下您的答案,将完整的badge.xml布局文件改为RelativeLayout?并且编辑您的activity-codesnippet以指定哪些方法包含哪些代码(例如:onCreate用于初始化,onResume用于刷新徽章)?此外,您在XML和代码中都设置了actionView,这应该是不必要的。 - arne.jans
1
@arne.jans 您是正确的!不需要再次使用setActionView,它应该可以正常工作。我编写了updateNavView方法,因此当徽章计数更改时,会触发事件来调用此方法(例如使用自定义侦听器或广播接收器)。 - ugur
1
谢谢您的更新!我还注意到您在android命名空间中使用了actionLayout属性。我认为它应该与app命名空间一起使用,以便在旧版Android上正确使用。 - arne.jans
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接