徽章可绘制不显示
Badge Drawable not showing
为什么BadgeDrawable没有显示在任何地方?我正在尝试添加 MaterialCardView
、MaterialButton
等。它没有显示。有人知道如何解决这个问题吗?或者有相同的库来替换它?
代码如下:
val badgeDrawable = BadgeDrawable.create(holder.itemView.context)
badgeDrawable.number = 10
badgeDrawable.badgeGravity = BadgeDrawable.TOP_END
badgeDrawable.backgroundColor = holder.itemView.context.getColor(R.color.colorAccent)
holder.itemView.home_cardview.overlay.add(badgeDrawable)
badgeDrawable.updateBadgeCoordinates(holder.itemView.home_cardview, null)
这个方法也行不通:
BadgeUtils.attachBadgeDrawable(badgeDrawable, anchor, null);
顺便说一下,在新版本中 compatBadgeParent 是必填字段
验证您使用的版本,我正在使用:
com.google.android.material:material: 1.1.0-beta01
然后试试这个:
bottomNavigationView.getOrCreateBadge(R.id.menu_item_notifications).apply {
backgroundColor = resources.getColor(R.color.red)
badgeTextColor = resources.getColor(R.color.white)
maxCharacterCount = 3
number = 10 //should be change
isVisible = true
}
我遇到了同样的问题。
这可能是 Badge 库中的错误。
这是工作:
badgeDrawable = BadgeDrawable.create(frameLayoutContainer.getContext());
frameLayoutContainer.setForeground(badgeDrawable);
frameLayoutContainer.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
//
badgeDrawable.updateBadgeCoordinates(frameLayoutContainer, frameLayoutContainer);
});
frameLayoutContainer 是一个将 BadgeDrawable 设置为其前景的 FrameLayout。
这是 posted by @0X0nosugar on my 所以请去看看他的回答并给他点个赞。链接放在上面,谢谢!
BottomNavigationView.getOrCreateBadge()
不仅将 BadgeDrawable
指定为前景 Drawable,而且还设置了 drawable 边界。如果没有这一步,它们会停留在 (0,0,0,0),所以没有什么可画的。
为了设置bounds,给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)
}
将此函数与 FrameLayout 的 BadgeDrawable 一起使用:
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>
您可以使用以下布局将 BadgeDrawable
应用于 MaterialCardView
或 MaterialButton
:
<FrameLayout
android:id="@+id/layout"
android:clipChildren="false"
android:clipToPadding="false"
..>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
.../>
</FrameLayout>
那就用方法BadgeUtils.attachBadgeDrawable
.
例如 CardView
:
MaterialCardView cardview = findViewById(R.id.card);
cardview.setClipToOutline(false); //Important with a CardView
cardview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
BadgeDrawable badgeDrawable = BadgeDrawable.create(MainActivity.this);
badgeDrawable.setNumber(15);
BadgeUtils.attachBadgeDrawable(badgeDrawable, cardview, findViewById(R.id.layout));
cardview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
对于Button
:
<FrameLayout
android:id="@+id/layout"
android:clipChildren="false"
android:clipToPadding="false">
<com.google.android.material.button.MaterialButton
android:id="@+id/button"
../>
</FrameLayout>
然后是类似的代码:
button.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
BadgeDrawable badgeDrawable = BadgeDrawable.create(MainActivity.this);
badgeDrawable.setNumber(7);
badgeDrawable.setBackgroundColor(......);
badgeDrawable.setVerticalOffset(20);
badgeDrawable.setHorizontalOffset(15);
BadgeUtils.attachBadgeDrawable(badgeDrawable, button, findViewById(R.id.layout));
button.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
您可以在 Kotlin 中使用不带 FrameLayout 的以下函数:
视图 是您要放置通知徽章的组件!
@SuppressLint("UnsafeExperimentalUsageError")
private fun initBadge(view : View, nbrNotification : Int) {
if(nbrNotification == 0) return // Don't show the badge
view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
BadgeDrawable.create(requireContext()).apply {
number = nbrNotification
verticalOffset = 70
horizontalOffset = 70
//badgeDrawable.setBackgroundColor() #to change the background color
BadgeUtils.attachBadgeDrawable(this, view)
}
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
}
这里我实现了 BadgeDrawable
using BadgeUtils
和 xml 样式来在 Button 上添加徽章。
private fun setBadgeCount(count: Int) {
BadgeDrawable.createFromResource(this, R.xml.badge_style).apply {
number = count
BadgeUtils.attachBadgeDrawable(this, binding.buttonContact)
}
}
badge_style.xml:
<badge xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/Widget.MaterialComponents.Badge"
app:backgroundColor="#FF0000"
app:badgeTextColor="#FFFFFF"
app:horizontalOffset="6dp"
app:maxCharacterCount="2"
app:verticalOffset="8dp" />
输出:
参考:
为什么BadgeDrawable没有显示在任何地方?我正在尝试添加 MaterialCardView
、MaterialButton
等。它没有显示。有人知道如何解决这个问题吗?或者有相同的库来替换它?
代码如下:
val badgeDrawable = BadgeDrawable.create(holder.itemView.context)
badgeDrawable.number = 10
badgeDrawable.badgeGravity = BadgeDrawable.TOP_END
badgeDrawable.backgroundColor = holder.itemView.context.getColor(R.color.colorAccent)
holder.itemView.home_cardview.overlay.add(badgeDrawable)
badgeDrawable.updateBadgeCoordinates(holder.itemView.home_cardview, null)
这个方法也行不通:
BadgeUtils.attachBadgeDrawable(badgeDrawable, anchor, null);
顺便说一下,在新版本中 compatBadgeParent 是必填字段
验证您使用的版本,我正在使用:
com.google.android.material:material: 1.1.0-beta01
然后试试这个:
bottomNavigationView.getOrCreateBadge(R.id.menu_item_notifications).apply {
backgroundColor = resources.getColor(R.color.red)
badgeTextColor = resources.getColor(R.color.white)
maxCharacterCount = 3
number = 10 //should be change
isVisible = true
}
我遇到了同样的问题。 这可能是 Badge 库中的错误。 这是工作:
badgeDrawable = BadgeDrawable.create(frameLayoutContainer.getContext());
frameLayoutContainer.setForeground(badgeDrawable);
frameLayoutContainer.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
//
badgeDrawable.updateBadgeCoordinates(frameLayoutContainer, frameLayoutContainer);
});
frameLayoutContainer 是一个将 BadgeDrawable 设置为其前景的 FrameLayout。
这是
BottomNavigationView.getOrCreateBadge()
不仅将 BadgeDrawable
指定为前景 Drawable,而且还设置了 drawable 边界。如果没有这一步,它们会停留在 (0,0,0,0),所以没有什么可画的。
为了设置bounds,给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)
}
将此函数与 FrameLayout 的 BadgeDrawable 一起使用:
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>
您可以使用以下布局将 BadgeDrawable
应用于 MaterialCardView
或 MaterialButton
:
<FrameLayout
android:id="@+id/layout"
android:clipChildren="false"
android:clipToPadding="false"
..>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
.../>
</FrameLayout>
那就用方法BadgeUtils.attachBadgeDrawable
.
例如 CardView
:
MaterialCardView cardview = findViewById(R.id.card);
cardview.setClipToOutline(false); //Important with a CardView
cardview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
BadgeDrawable badgeDrawable = BadgeDrawable.create(MainActivity.this);
badgeDrawable.setNumber(15);
BadgeUtils.attachBadgeDrawable(badgeDrawable, cardview, findViewById(R.id.layout));
cardview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
对于Button
:
<FrameLayout
android:id="@+id/layout"
android:clipChildren="false"
android:clipToPadding="false">
<com.google.android.material.button.MaterialButton
android:id="@+id/button"
../>
</FrameLayout>
然后是类似的代码:
button.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
BadgeDrawable badgeDrawable = BadgeDrawable.create(MainActivity.this);
badgeDrawable.setNumber(7);
badgeDrawable.setBackgroundColor(......);
badgeDrawable.setVerticalOffset(20);
badgeDrawable.setHorizontalOffset(15);
BadgeUtils.attachBadgeDrawable(badgeDrawable, button, findViewById(R.id.layout));
button.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
您可以在 Kotlin 中使用不带 FrameLayout 的以下函数:
视图 是您要放置通知徽章的组件!
@SuppressLint("UnsafeExperimentalUsageError")
private fun initBadge(view : View, nbrNotification : Int) {
if(nbrNotification == 0) return // Don't show the badge
view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
BadgeDrawable.create(requireContext()).apply {
number = nbrNotification
verticalOffset = 70
horizontalOffset = 70
//badgeDrawable.setBackgroundColor() #to change the background color
BadgeUtils.attachBadgeDrawable(this, view)
}
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
}
这里我实现了 BadgeDrawable
using BadgeUtils
和 xml 样式来在 Button 上添加徽章。
private fun setBadgeCount(count: Int) {
BadgeDrawable.createFromResource(this, R.xml.badge_style).apply {
number = count
BadgeUtils.attachBadgeDrawable(this, binding.buttonContact)
}
}
badge_style.xml:
<badge xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/Widget.MaterialComponents.Badge"
app:backgroundColor="#FF0000"
app:badgeTextColor="#FFFFFF"
app:horizontalOffset="6dp"
app:maxCharacterCount="2"
app:verticalOffset="8dp" />
输出:
参考: