BadgeDrawable 是否不适用于 FrameLayout 中的视图,例如按钮、图像、文本视图等?

Pri*_*cap 4 android badge android-view android-drawable android-framelayout

我的主要活动中有此功能,但不显示徽章:

private fun setFindShiftBadge(state: HomeState) {
        val findShiftsBadge = BadgeDrawable.create(this)
        home_framelayout.foreground = findShiftsBadge
        findShiftsBadge.badgeGravity = BadgeDrawable.TOP_END
        findShiftsBadge.backgroundColor = resources.getColor(R.color.colorWhite)
        findShiftsBadge.badgeTextColor = resources.getColor(R.color.colorPrimary)
        findShiftsBadge.number = state.availableShifts.size
 }
Run Code Online (Sandbox Code Playgroud)

在同一个活动中,我有这个显示徽章的功能:

private fun setMyPostedShiftBadge(state: HomeState) {
    val userShiftsBadge: BadgeDrawable =
        bottom_navigation_view.getOrCreateBadge(R.id.bottom_navigation_my_posted_shifts_text)
    userShiftsBadge.number = state.userShifts.size
    userShiftsBadge.backgroundColor = resources.getColor(R.color.colorPrimary)
} 
Run Code Online (Sandbox Code Playgroud)

现在我明白第二个函数可以工作,因为徽章设置在BottomNavigationView. 具有讽刺意味的是,BottomNavigationView扩展FrameLayout。在 Android 文档中: 使用 attachBadgeDrawable(BadgeDrawable, View, FrameLayout) 将 BadgeDrawable 作为 ViewOverlay 添加到所需的锚视图。使用 updateBadgeCoordinates(View, ViewGroup) 根据锚视图更新 BadgeDrawable BadgeDrawable 的坐标(中心和边界)。

他们说要使用这段代码,For API 18+ (APIs supported by ViewOverlay)我在第一个不起作用的函数中使用了它:

 BadgeDrawable badgeDrawable = BadgeDrawable.create(context);
 BadgeUtils.attachBadgeDrawable(badgeDrawable, anchor, null);
Run Code Online (Sandbox Code Playgroud)

我也试过这个解决方案,但它也没有用。我知道有一些解决方法,例如:

  1. 创建一个 drawable 然后将其设置到您想要的视图上
  2. 在该 drawable 中放置一个 TextView,然后使用您想要的数字进行更新
  3. 当有任何数字时,切换可绘制对象的可见性。

我在 implementation 'com.google.android.material:material:1.2.0-alpha04'

这对我来说似乎很脏,因为我知道有更好的方法来做到这一点。我似乎无法弄清楚。我错过了什么?这甚至可能吗?您是如何在无需编写解决方法的情况下做到这一点的?谢谢你的时间!期待从您的问题和答案中学习!!拥有美好的一天!

0X0*_*gar 9

BottomNavigationView.getOrCreateBadge()不仅分配BadgeDrawableas foreground Drawable,还设置可绘制边界。没有这一步,它们停留在(0,0,0,0),所以没有什么可画的。

为了设置边界,让我们引入一个扩展函数 BadgeDrawable

/**
 * Inspired by BadgeUtils in com.google.android.material library
 *
 * Sets the bounds of a BadgeDrawable 
 */
private fun BadgeDrawable.setBoundsFor(@NonNull anchor: View, @NonNull parent: FrameLayout){
    val rect = Rect()
    parent.getDrawingRect(rect)
    this.setBounds(rect)
    this.updateBadgeCoordinates(anchor, parent)
}
Run Code Online (Sandbox Code Playgroud)

将此功能与您的BadgeDrawablefor 一起使用FrameLayout

private fun setFindShiftBadge(state: HomeState) {
    val findShiftsBadge = BadgeDrawable.create(this)
    // configure the badge drawable
    findShiftsBadge.badgeGravity = BadgeDrawable.TOP_END
    findShiftsBadge.backgroundColor = resources.getColor(R.color.colorWhite)
    findShiftsBadge.badgeTextColor = resources.getColor(R.color.colorPrimary)
    findShiftsBadge.number = state.availableShifts.size
    // set bounds inside which it will be drawn
    findShiftsBadge.setBoundsFor(btn_badge, home_framelayout)
    // assign as foreground drawable
    home_framelayout.foreground = findShiftsBadge
}
Run Code Online (Sandbox Code Playgroud)

截屏

  • 我真的很奇怪 Android 文档怎么这么无用。 (12认同)

Kev*_*uan 6

  BadgeDrawable badgeDrawable = BadgeDrawable.create(this);
badgeDrawable.setNumber(15);

FrameLayout frameLayout = findViewById(R.id.framelayout);

ImageView imageView = findViewById(R.id.iv_center);

//core code
frameLayout.setForeground(badgeDrawable);
frameLayout.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {


    //either of the following two lines of code  work
    //badgeDrawable.updateBadgeCoordinates(imageView, frameLayout);
    BadgeUtils.attachBadgeDrawable(badgeDrawable, imageView, frameLayout);
});





<FrameLayout
    android:id="@+id/framelayout"
    android:layout_width="150dp"
    android:layout_height="150dp">

    <ImageView
        android:layout_gravity="center"
        android:id="@+id/iv_center"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_beard" />
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)