徽章可绘制不显示

时间:2019-10-15 20:13:49

标签: android kotlin

为什么BadgeDrawable没有显示在任何地方?我正在尝试添加MaterialCardViewMaterialButton等。它没有显示。任何人都有解决此问题的想法?还是拥有与替换该库相同的库?

这里的代码:

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是必填字段

7 个答案:

答案 0 :(得分:1)

这是solution在我的@0X0nosugar上发布的question,所以请检查他的答案并给他竖起大拇指。上方的链接,谢谢!

BottomNavigationView.getOrCreateBadge()不仅将BadgeDrawable分配为前景可绘制对象,而且还设置可绘制对象边界。没有此步骤,它们将停留在(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
}

enter image description here

答案 1 :(得分:1)

您可以使用以下布局将BadgeDrawable应用于MaterialCardViewMaterialButton

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

enter image description here

对于 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);
        }
    });

enter image description here

答案 2 :(得分:1)

您可以在没有 FrameLayout 的情况下以 Kotlin 方式使用以下函数:

view 是您要放置通知徽章的组件!

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

答案 3 :(得分:0)

验证您使用的版本,我正在使用:

  

com.google.android.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
        }

答案 4 :(得分:0)

我遇到了同样的问题。 徽章库中的错误。 这是工作:

        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。

答案 5 :(得分:0)

    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>

答案 6 :(得分:0)

这里我实现了 BadgeDrawable 使用 BadgeUtils 和 xml 样式在按钮上添加徽章。

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" />

输出:

enter image description here

参考:

  1. https://material.io/develop/android/supporting/badge
  2. https://developer.android.com/reference/com/google/android/material/badge/package-summary