BadgeDrawable 是否不适用于 FrameLayout 中的视图,例如按钮、图像、文本视图等? [英] Does BadgeDrawable not work for views within a FrameLayout such as buttons, images, textviews etc.?

查看:31
本文介绍了BadgeDrawable 是否不适用于 FrameLayout 中的视图,例如按钮、图像、文本视图等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

私人乐趣 setFindShiftBadge(state: HomeState) {val findShiftsBadge = BadgeDrawable.create(this)home_framelayout.foreground = findShiftsBadgefindShiftsBadge.badgeGravity = BadgeDrawable.TOP_ENDfindShiftsBadge.backgroundColor = resources.getColor(R.color.colorWhite)findShiftsBadge.badgeTextColor = resources.getColor(R.color.colorPrimary)findShiftsBadge.number = state.availableShifts.size}

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

私人乐趣 setMyPostedShiftBadge(state: HomeState) {val userShiftsBadge:BadgeDrawable =bottom_navigation_view.getOrCreateBadge(R.id.bottom_navigation_my_posted_shifts_text)userShiftsBadge.number = state.userShifts.sizeuserShiftsBadge.backgroundColor = resources.getColor(R.color.colorPrimary)}

现在我明白第二个函数起作用了,因为徽章是在 BottomNavigationView 中设置的.具有讽刺意味的是,BottomNavigationView 扩展了 FrameLayout.在 Android 文档中:

I have this function in my main activity which doesn't display a badge:

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
 }

In the same activity, I have this function which displays a badge:

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

Now I understand that the second function works because the badge is set within a BottomNavigationView. Ironically, BottomNavigationView extends FrameLayout. In the Android Documentation: Add BadgeDrawable as a ViewOverlay to the desired anchor view using attachBadgeDrawable(BadgeDrawable, View, FrameLayout). Update the BadgeDrawable BadgeDrawable's coordinates (center and bounds) based on its anchor view using updateBadgeCoordinates(View, ViewGroup).

They say to use this code, For API 18+ (APIs supported by ViewOverlay) which I use in the first function that doesn't work:

 BadgeDrawable badgeDrawable = BadgeDrawable.create(context);
 BadgeUtils.attachBadgeDrawable(badgeDrawable, anchor, null);

I have also tried this solution but it didn't work either. I'm aware there are workarounds such as:

  1. Creating a drawable then setting that onto of the view you want
  2. Placing a TextView within that drawable that you then update with the number you want
  3. Toggle the visibility of the drawable when there are any numbers.

I am on implementation 'com.google.android.material:material:1.2.0-alpha04'

This seems dirty to me since I know that there is a better way to do this. I just can't seem to figure it out. What am I missing? Is this even possible? How have you been able to do this without having to write a workaround? Thanks for your time! Looking forward to learning from your questions and answers!! Have a fantastic day!

解决方案

BottomNavigationView.getOrCreateBadge() does not only assign the BadgeDrawable as foreground Drawable, it also sets the drawable bounds. Without this step, they stay at (0,0,0,0), so there is nothing to draw.

In order to set the bounds, let's introduce an extension function for 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)
}

Use this function with your BadgeDrawable for 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
}

这篇关于BadgeDrawable 是否不适用于 FrameLayout 中的视图,例如按钮、图像、文本视图等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆