我正在尝试在不使用任何库的情况下为BottomNavigationView
项添加徽章,但不知何故BottomNavigationView
未显示徽章(custom_view)
main_view.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.hrskrs.test.MainActivity">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="@color/colorPrimary"
app:itemIconTint="@color/colorAccent"
app:itemTextColor="@color/colorPrimaryDark"
app:menu="@menu/bottom_navigation_main" />
</RelativeLayout>
bottom_navigation_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item_test"
android:icon="@mipmap/ic_launcher"
android:title="action1"
app:showAsAction="always" />
<item
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:title="action2"
app:showAsAction="ifRoom" />
<item
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:title="action3"
app:showAsAction="ifRoom" />
</menu>
活动从AppCompatActivity
扩展:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu = bottomNavigationView.getMenu();
menu.clear();
getMenuInflater().inflate(R.menu.bottom_navigation_main, menu);
MenuItem item = menu.findItem(R.id.item_test);
item = MenuItemCompat.setActionView(item, R.layout.custom_view);
RelativeLayout badgeWrapper = (RelativeLayout) MenuItemCompat.getActionView(item);
TextView textView = (TextView) badgeWrapper.findViewById(R.id.txtCount);
textView.setText("99+");
return super.onCreateOptionsMenu(menu);
}
custom_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@android:style/Widget.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Notification Icon"
android:gravity="center"
android:src="@mipmap/ic_launcher" />
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/txtCount"
android:gravity="right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_badge"
android:text="55"
android:textColor="#ffffffff"
android:textSize="12sp" />
</RelativeLayout>
仅显示(badge) custom_view
它仅显示项目本身:
下面您可以从调试模式中看到访问的view
是正确的,并且正确设置。但不管怎样,BottomNavigationView
没有失效:
答案 0 :(得分:6)
我设法用徽章制作BottomNavigationView。这是我的代码(Kotlin)。
这是面板(继承自BottomNavigationView)
/** Bottom menu with badge */
class AdvancedBottomNavigationView(context: Context, attrs: AttributeSet) : BottomNavigationView(context, attrs) {
private companion object {
const val BADGE_MIN_WIDTH = 16 // [dp]
const val BADGE_MARGIN_TOP = 5 // [dp]
const val BADGE_MARGIN_LEFT = 15 // [dp]
}
@Inject internal lateinit var uiCalculator: UICalculatorInterface
private val bottomMenuView: BottomNavigationMenuView
init {
// Get access to internal menu
val field = BottomNavigationView::class.java.getDeclaredField("mMenuView")
field.isAccessible = true
bottomMenuView = field.get(this) as BottomNavigationMenuView
App.injections.presentationLayerComponent!!.inject(this)
@SuppressLint("CustomViewStyleable")
val a = context.obtainStyledAttributes(attrs, R.styleable.advanced_bottom_navigation_bar)
val badgeLayoutId = a.getResourceId(R.styleable.advanced_bottom_navigation_bar_badge_layout, -1)
a.recycle()
initBadges(badgeLayoutId)
}
/**
* [position] index of menu item */
fun setBadgeValue(position: Int, count: Int) {
val menuView = bottomMenuView
val menuItem = menuView.getChildAt(position) as BottomNavigationItemView
val badge = menuItem.findViewById(R.id.bottom_bar_badge)
val badgeText = menuItem.findViewById(R.id.bottom_bar_badge_text) as TextView
if (count > 0) {
badgeText.text = count.toString()
badge.visibility = View.VISIBLE
} else {
badge.visibility = View.GONE
}
}
/**
* Select menu item
* [position] index of menu item to select
*/
fun setSelected(position: Int) = bottomMenuView.getChildAt(position).performClick()
private fun initBadges(badgeLayoutId: Int) {
// Adding badges to each Item
val menuView = bottomMenuView
val totalItems = menuView.childCount
val oneItemAreaWidth = uiCalculator.getScreenSize(context).first / totalItems
val marginTop = uiCalculator.dpToPixels(context, BADGE_MARGIN_TOP)
val marginLeft = uiCalculator.dpToPixels(context, BADGE_MARGIN_LEFT)
for (i in 0 until totalItems) {
val menuItem = menuView.getChildAt(i) as BottomNavigationItemView
// Add badge to every item
val badge = View.inflate(context, badgeLayoutId, null) as FrameLayout
badge.visibility = View.GONE
badge.minimumWidth = uiCalculator.dpToPixels(context, BADGE_MIN_WIDTH)
val layoutParam = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
layoutParam.gravity = Gravity.START
layoutParam.setMargins(oneItemAreaWidth / 2 + marginLeft, marginTop, 0, 0)
menuItem.addView(badge, layoutParam)
}
}
}
它的attr.xml文件包含此组件的选项:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="advanced_bottom_navigation_bar">
<attr name="badge_layout" format="reference|integer" />
</declare-styleable>
</resources>
可绘制文件夹徽章的背景:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#ff0000" />
<corners android:radius="10dp" />
</shape>
</item>
</selector>
徽章本身:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="@+id/bottom_bar_badge"
android:layout_height="20dp"
android:layout_width="20dp"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/bcg_badge"
>
<TextView
android:id="@+id/bottom_bar_badge_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textSize="10sp"
android:textColor="@android:color/white"
xmlns:android="http://schemas.android.com/apk/res/android"
android:textAlignment="center"
android:layout_gravity="center"/>
</FrameLayout>
这是一个如何在代码中使用它的示例:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="su.ivcs.ucim.presentationLayer.userStories.mainScreen.view.MainActivity">
<su.ivcs.ucim.presentationLayer.common.advancedBottomNavigationView.AdvancedBottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="@android:color/white"
app:itemIconTint="@color/main_screen_tabs_menu_items"
app:itemTextColor="@color/main_screen_tabs_menu_items"
app:menu="@menu/main_screen_tabs_menu"
app:badge_layout = "@layout/common_badge"
app:layout_constraintTop_toBottomOf="@+id/fragmentsContainer"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
我希望这会对你有所帮助。
答案 1 :(得分:2)
您可以使用BottomNavigationView
提供的Material Components Library。
只需将jupyter kernelspec remove python2
添加到您的布局中即可:
BottomNavigationView
然后在您的代码中使用:
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_gravity="bottom"
app:menu="@menu/navigation_main"
../>
要更改徽标重力,请使用 int menuItemId = bottomNavigationView.getMenu().getItem(0).getItemId();
BadgeDrawable badge = bottomNavigationView.getOrCreateBadge(menuItemId);
badge.setNumber(2);
方法。
setBadgeGravity
答案 2 :(得分:1)
@hrskrs尝试在txtCount或badgeWrapper本身上添加更高的高程。
BottomNavigationView
似乎比屏幕上的视图具有更高的高度。
我努力在BottomNavigationView
物品上展示徽章。当用户点击其他项目或变成与色调中定义的相同颜色(如果未定义为colorPrimary)时,我的徽章(没有任何文本值)是drawable本身的一部分变为灰色。
我认为你会遇到BottomNavigationView
菜单项顶部的徽章/计数器着色所面临的同样问题,因为色调颜色将应用于项目本身,而badgeWrapper将成为MenuItem
的一部分将采取色调(当你点击任何其他你不想要的项目时我会变成灰色。)
我使用ImageView
作为徽章,但您可以使用badgeWrapper RelativeView
代替ImageView。
答案 3 :(得分:0)
像这样使用BadgeDrawable:
Integer amount = tabBadgeCountMap.get(tab);
BadgeDrawable badgeDrawable = bottomNavigationView.getOrCreateBadge(tabMenuResId);
badgeDrawable.setNumber(amount != null ? amount : 0);