Android Kotlin中BadgeDrawable被视图裁剪显示异常问题求助
问题原因
- 你将
BadgeDrawable设置为FrameLayout的foreground,前景的绘制范围默认受容器自身边界约束,即使开启clipChildren也不会突破父布局自身的绘制区域。 - 自定义的
setBoundsFor方法手动将BadgeDrawable的绘制范围限制为父布局的drawingRect,进一步限制了角标的显示区域。 - 父布局
paddingEnd仅设置为9dp,多位数角标宽度超过预留空间后就会被裁剪。
修复方案
1. 调整布局参数
增大FrameLayout右侧padding,预留足够的角标显示空间,同时确保FrameLayout的上层父容器也开启clipChildren="false"和clipToPadding="false",避免上层容器裁剪角标:
<FrameLayout android:id="@+id/container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginEnd="24dp" android:clipChildren="false" android:clipToPadding="false" android:paddingStart="6dp" android:paddingTop="4dp" android:paddingEnd="20dp" <!-- 根据最多显示的角标位数调整,99+的场景设置20dp足够 --> android:paddingBottom="4dp" app:layout_constraintBottom_toBottomOf="@+id/xyz" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/xyz"> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="start" android:src="@drawable/ic_settings" tools:ignore="ContentDescription" /> </FrameLayout>
2. 修改角标添加逻辑
删除自定义的setBoundsFor方法,将角标添加到FrameLayout的overlay而非设置为前景,overlay的绘制范围不受容器边界约束:
fun addBadgeDrawable(count: Int, target: View, parent: FrameLayout, context: Context) { target.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { val badgeDrawable = BadgeDrawable.create(context) badgeDrawable.number = count badgeDrawable.badgeGravity = BadgeDrawable.TOP_END badgeDrawable.updateBadgeCoordinates(target, parent) // 可选:调整水平偏移,避免角标太靠外 // badgeDrawable.horizontalOffset = resources.getDimensionPixelOffset(R.dimen.badge_offset) parent.overlay.add(badgeDrawable) target.viewTreeObserver.removeOnGlobalLayoutListener(this) } }) }
调用逻辑保持不变即可:
addBadgeDrawable(10, binding.icon, binding.container, context)
内容的提问来源于stack exchange,提问作者Compose Learner
相关产品推荐
相关产品推荐

