当前位置:主页 > android教程 > Android BadgeDrawable详解

Android涨姿势知识点之你没用过的BadgeDrawable

发布:2023-03-05 11:30:01 59


本站收集了一篇相关的编程文章,网友龙安民根据主题投稿了本篇教程内容,涉及到android、badgedrawable、android、红点提示、安卓图标红点通知、Android BadgeDrawable详解相关内容,已被804网友关注,下面的电子资料对本篇知识点有更加详尽的解释。

Android BadgeDrawable详解

1.前言

通常情况下,我们在做小红点效果的时候,会有两种选择:

自定义BadgeView,然后设置给目标Viewxml写一个View,然后设置shape

有的同学可能会想,能实现不就行了吗,是的,代码优不优雅的不重要,代码和人只要有一个能跑就行…

不过,今天来介绍一种不同的方式来实现小红点效果,或许会让你眼前一亮~

2.效果

3.简介

  • 用途:给View添加动态显示信息(小红点提示效果)
  • app主题需使用Theme.MaterialComponents.*
  • api 要求18+ 也就Android 4.3以上(api等级对应关系见文末)

4.实现拆解

4.1TabLayout

xml:

    

        

        

        

    

kotlin:

    private fun initTabLayout() {
        // 带数字小红点
        mBinding.tabLayout.getTabAt(0)?.let {
            it.orCreateBadge.apply {
                backgroundColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.red)
                badgeTextColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.white)
                number = 6
            }
        }

        // 不带数字小红点
        mBinding.tabLayout.getTabAt(1)?.let {
            it.orCreateBadge.apply {
                backgroundColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.red)
                badgeTextColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.white)
            }
        }
    }

4.2.TextView

xml:

    

kotlin:

    private fun initTextView() {
        // 在视图树变化
        mBinding.tvBadge.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                BadgeDrawable.create(this@BadgeDrawableActivity).apply {
                    badgeGravity = BadgeDrawable.TOP_END
                    number = 6
                    backgroundColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.colorPrimary)
                    isVisible = true
                    BadgeUtils.attachBadgeDrawable(this, mBinding.tvBadge)
                }
                mBinding.tvBadge.viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        })
    }

4.3.Button

xml:

    

        

    

kotlin:

    private fun initButton() {
        mBinding.mbBadge.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            @SuppressLint("UnsafeOptInUsageError")
            override fun onGlobalLayout() {
                BadgeDrawable.create(this@BadgeDrawableActivity).apply {
                    badgeGravity = BadgeDrawable.TOP_START
                    number = 6
                    backgroundColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.red)
                    // MaterialButton本身有间距,不设置为0dp的话,可以设置badge的偏移量
                    verticalOffset = 15
                    horizontalOffset = 10
                    BadgeUtils.attachBadgeDrawable(this, mBinding.mbBadge, mBinding.flBtn)
                }
                mBinding.mbBadge.viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        })
    }

关于MaterialButton的使用及解析可查看:Android MaterialButton使用详解,告别shape、selector

4.4.ImageView

xml:

    

        

    

kotlin:

    private fun initImageView() {
        mBinding.sivBadge.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            @SuppressLint("UnsafeOptInUsageError")
            override fun onGlobalLayout() {
                BadgeDrawable.create(this@BadgeDrawableActivity).apply {
                    badgeGravity = BadgeDrawable.TOP_END
                    number = 99999
                    // badge最多显示字符,默认999+ 是4个字符(带'+'号)
                    maxCharacterCount = 3
                    backgroundColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.red)
                    BadgeUtils.attachBadgeDrawable(this, mBinding.sivBadge, mBinding.flImg)
                }
                mBinding.sivBadge.viewTreeObserver.removeOnGlobalLayoutListener(this)
            }
        })
    }

关于ShapeableImageView的使用及解析可查看:Android ShapeableImageView使用详解,告别shape、三方库

4.5.BottomNavigationView

xml:

    

kotlin:

    private fun initNavigationView() {
        mBinding.navigationView.getOrCreateBadge(R.id.navigation_home).apply {
            backgroundColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.red)
            badgeTextColor = ContextCompat.getColor(this@BadgeDrawableActivity, R.color.white)
            number = 9999
        }
    }

TabLayout和BottomNavigationView源码中直接提供了创建BadgeDrawable的api,未提供的使用BadgeUtils

5.常用API整理

API描述
backgroundColor背景色
badgeTextColor文本颜色
alpha透明度
number显示的提示数字
maxCharacterCount最多显示字符数量(99+包括‘+’号)
badgeGravity显示位置
horizontalOffset水平方向偏移量
verticalOffset垂直方向偏移量
isVisible是否显示

6.源码解析

来一段最简单的代码示例看看:

BadgeDrawable.create(this@BadgeDrawableActivity).apply {
    // ...
    BadgeUtils.attachBadgeDrawable(this, mBinding.mbBadge, mBinding.flBtn)
}

不难发现,有两个关键点:

  • BadgeDrawable.create
  • BadgeUtils.attachBadgeDrawable

下面继续跟一下,看看源码里究竟是做了什么

6.1.BadgeDrawable.create

create实际调用的是构造方法:

  private BadgeDrawable(@NonNull Context context) {
    this.contextRef = new WeakReference<>(context);
    ThemeEnforcement.checkMaterialTheme(context);
    Resources res = context.getResources();
    badgeBounds = new Rect();
    shapeDrawable = new MaterialShapeDrawable();

    badgeRadius = res.getDimensionPixelSize(R.dimen.mtrl_badge_radius);
    badgeWidePadding = res.getDimensionPixelSize(R.dimen.mtrl_badge_long_text_horizontal_padding);
    badgeWithTextRadius = res.getDimensionPixelSize(R.dimen.mtrl_badge_with_text_radius);

    textDrawableHelper = new TextDrawableHelper(/* delegate= */ this);
    textDrawableHelper.getTextPaint().setTextAlign(Paint.Align.CENTER);
    this.savedState = new SavedState(context);
    setTextAppearanceResource(R.style.TextAppearance_MaterialComponents_Badge);
  }

构造方法里有这么一行:ThemeEnforcement.checkMaterialTheme(context); 检测Material主题,如果不是会直接抛出异常

  private static void checkTheme(
      @NonNull Context context, @NonNull int[] themeAttributes, String themeName) {
    if (!isTheme(context, themeAttributes)) {
      throw new IllegalArgumentException(
          "The style on this component requires your app theme to be "
              + themeName
              + " (or a descendant).");
    }
  }

这也是上面为什么说主题要使用Theme.MaterialComponents.*

然后创建了一个文本绘制帮助类,TextDrawableHelper

比如设置文本居中:textDrawableHelper.getTextPaint().setTextAlign(Paint.Align.CENTER);

其他的就是text属性的获取和设置,跟我们平时设置一毛一样,比较好理解。

绘制文本之后怎么显示出来呢?继续跟attachBadgeDrawable

6.2.BadgeUtils.attachBadgeDrawable

    public static void attachBadgeDrawable(@NonNull BadgeDrawable badgeDrawable, @NonNull View anchor, @Nullable FrameLayout customBadgeParent) {
        setBadgeDrawableBounds(badgeDrawable, anchor, customBadgeParent);
        if (badgeDrawable.getCustomBadgeParent() != null) {
            badgeDrawable.getCustomBadgeParent().setForeground(badgeDrawable);
        } else {
            if (USE_COMPAT_PARENT) {
                throw new IllegalArgumentException("Trying to reference null customBadgeParent");
            }
            anchor.getOverlay().add(badgeDrawable);
        }
    }

这里先是判断badgeDrawable.getCustomBadgeParent() != null,这个parent view的类型就是FrameLayout,不为空的情况下,层级前置。

为空的情况下先是判断了if (USE_COMPAT_PARENT),这里其实是对api level的判断

    static {
        USE_COMPAT_PARENT = VERSION.SDK_INT < 18;
    }

核心代码:

anchor.getOverlay().add(badgeDrawable);

如果有同学做过类似全局添加View的需求,这行代码就看着比较熟悉了。

ViewOverlay,视图叠加,也可以理解为浮层,在不影响子view的情况下,可以添加、删除View,这个api就是android 4.3加的,这也是为什么前面说api 要求18+。

ok,至此关于BadgeDrawable的使用和源码解析就介绍完了。

7.Github

https://github.com/yechaoa/MaterialDesign

8.相关文档

附:Android开发版本和API等级对应关系

Platform VersionAPI LevelVERSION_CODE
13.0(beta)  
12.032S_V2
12.031S
11.030R
10.029Q
9.028P
8.127O_MR1
8.026O
7.125N_MR1
7.024N
6.023M
5.122LOLLIPOP_MR1
5.021LOLLIPOP
4.4w20KITKAT_WATCH
4.419KITKAT
4.318JELLY_BEAN_MR2
4.217JELLY_BEAN_MR1
4.116JELLY_BEAN
4.0.315ICE_CREAM_SANDWICH_MR1
4.014ICE_CREAM_SANDWICH
3.213HONEYCOMB_MR2
3.112HONEYCOMB_MR1
3.011HONEYCOMB
2.3.3-2.3.410GINGERBREAD_MR1
2.3.0-2.3.29GINGERBREAD
2.28FROYO
2.17ECLAIR_MR1
2.0.16ECLAIR_0_1
2.05ECLAIR
1.64DONUT
1.53CUPCAKE
1.12BASE_1_1
1.01BASE

总结 

到此这篇关于Android涨姿势知识点之BadgeDrawable的文章就介绍到这了,更多相关Android BadgeDrawable详解内容请搜索码农之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持码农之家!


参考资料

相关文章

  • Android浅析viewBinding和DataBinding

    发布:2023-03-10

    这篇文章主要介绍了Android浅析viewBinding和DataBinding,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下


  • Android内置SQLite的使用详细介绍

    发布:2023-03-09

    这篇文章主要介绍了Android内置SQLite的使用详细介绍,文章通过文章展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下


  • Android实现读写USB串口数据

    发布:2023-03-10

    这篇文章主要为大家详细介绍了Android实现读写USB串口数据,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下


  • Android事件分发机制示例分析

    发布:2023-03-03

    在说事件分发之前,我们先想一个问题,在APP中我们点击一个View的时候,事件是如何传递到这个View的呢?其实这就是我理解的事件分发机制。即当手指点击屏幕时,事件传递到具体View的过程


  • Android ASM插桩探索实战详情

    发布:2023-03-04

    这篇文章主要介绍了Android ASM插桩探索实战详情,文章围绕主题展开详细的内容戒杀,具有一定的参考价值,需要的小伙伴可以参考一下


  • Android WebView预渲染介绍

    发布:2023-03-05

    这篇文章主要介绍了Android WebView预渲染介绍,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下


  • Android开发之AlertDialog实现弹出对话框

    发布:2023-03-11

    这篇文章主要为大家详细介绍了Android开发之AlertDialog实现弹出对话框,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下


  • Android开发实战闹钟项目

    发布:2023-03-07

    这篇文章主要介绍了Android开发实战闹钟项目,根据我们手机闹钟设计的一个闹钟APP,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下


网友讨论