BadgeDrawable 是否不适用于 FrameLayout 中的视图,例如按钮、图像、文本视图等?
Does BadgeDrawable not work for views within a FrameLayout such as buttons, images, textviews etc.?
我的主 activity 中有这个功能,它不显示徽章:
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
}
在同一个 activity 中,我有这个显示徽章的函数:
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)
}
现在我明白第二个函数起作用了,因为徽章是在 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);
我也试过这个,但也没用。我知道有一些解决方法,例如:
- 创建一个可绘制对象然后将其设置到您想要的视图上
- 在该可绘制对象中放置一个 TextView,然后用您想要的数字更新它
- 当有任何数字时切换可绘制对象的可见性。
我在implementation 'com.google.android.material:material:1.2.0-alpha04'
这对我来说似乎很脏,因为我知道有更好的方法来做到这一点。我就是想不通。我错过了什么?这可能吗?您是如何在不必编写变通方法的情况下做到这一点的?谢谢你的时间!期待从您的问题和答案中学习!!祝你有美好的一天!
BottomNavigationView.getOrCreateBadge()
不仅将 BadgeDrawable
指定为前景 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)
}
将此函数与您的 BadgeDrawable
一起用于 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 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>
我的主 activity 中有这个功能,它不显示徽章:
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
}
在同一个 activity 中,我有这个显示徽章的函数:
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)
}
现在我明白第二个函数起作用了,因为徽章是在 BottomNavigationView
中设置的。具有讽刺意味的是,BottomNavigationView
扩展了 FrameLayout
。在 Android 文档中:
使用 attachBadgeDrawable(BadgeDrawable, View, FrameLayout) 将 BadgeDrawable 作为 ViewOverlay 添加到所需的锚视图。
使用 updateBadgeCoordinates(View, ViewGroup).
他们说要使用这段代码,For API 18+ (APIs supported by ViewOverlay)
我在第一个不起作用的函数中使用了它:
BadgeDrawable badgeDrawable = BadgeDrawable.create(context);
BadgeUtils.attachBadgeDrawable(badgeDrawable, anchor, null);
我也试过这个
- 创建一个可绘制对象然后将其设置到您想要的视图上
- 在该可绘制对象中放置一个 TextView,然后用您想要的数字更新它
- 当有任何数字时切换可绘制对象的可见性。
我在implementation 'com.google.android.material:material:1.2.0-alpha04'
这对我来说似乎很脏,因为我知道有更好的方法来做到这一点。我就是想不通。我错过了什么?这可能吗?您是如何在不必编写变通方法的情况下做到这一点的?谢谢你的时间!期待从您的问题和答案中学习!!祝你有美好的一天!
BottomNavigationView.getOrCreateBadge()
不仅将 BadgeDrawable
指定为前景 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)
}
将此函数与您的 BadgeDrawable
一起用于 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 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>