ライブラリを使用せずに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
は無効にされていません:
バッジを使って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>
これがお役に立てば幸いです。
Material Components Library が提供する BottomNavigationView
を使用できます。
レイアウトに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
メソッドを使用します。
badge.setBadgeGravity(BadgeDrawable.BOTTOM_END);
@hrskrstxtCountまたはbadgeWrapper自体に高い標高を追加してみてください。 BottomNavigationView
は、画面上のビューよりも標高が高いようです。
BottomNavigationView
アイテムにバッジを表示するのに苦労しました。ユーザーが他のアイテムをクリックしたとき、または色合いで定義された同じ色になったとき(定義されていない場合はcolorPrimary)、ドローアブル自体の一部である私のバッジ(テキスト値なし)は灰色になりました。 BottomNavigationView
のメニュー項目の上にあるバッジ/カウンターの色付けで直面したのと同じ問題が発生すると思います。色合いの色がアイテム自体に適用され、MenuItem
の一部であるbadgeWrapperが色合いを取ります(あなたがあなたが私が推測したくない他のアイテムをタップします)。
ここで私の答えをチェックしてください: API 25で導入されたGoogleの公式BottomNavigationViewメニュー項目に通知バッジを表示する方法はありますか?
バッジにImageView
を使用しましたが、ImageViewの代わりにbadgeWrapperRelativeView
を使用できます。
BadgeDrawable を次のように使用します。
Integer amount = tabBadgeCountMap.get(tab);
BadgeDrawable badgeDrawable = bottomNavigationView.getOrCreateBadge(tabMenuResId);
badgeDrawable.setNumber(amount != null ? amount : 0);