其他分享
首页 > 其他分享> > 用树型模型管理App数字和红点提示(附Demo)

用树型模型管理App数字和红点提示(附Demo)

作者:互联网


我们平常接触到的大部分App,在收到新消息的时候一般都会以数字或红点的形式提示出来。比如在微信当中,当某位好友给我们发来新的聊天消息的时候,在相应的会话上就会有一个数字来表示未读消息的数目;再比如当微信朋友圈里有人发布新的内容时,朋友圈的入口就会出现一个红点,而当朋友圈里有人给我们点了赞,或者对我们发布的内容进行了评论的时候,朋友圈的入口就会显示一个数字。


但是,我们在试用一些新的App产品时,总会发现它们在数字和红点展示上存在各种各样的问题。比如,红点怎么点击也清除不掉;或者,发现有数字了,点进去却什么也没有;或者,点进去看到的数字和外面看到的不一样。


那这些问题到底是怎样产生的呢?


我猜测,问题产生的根源是:没有对数字和红点的展示逻辑做一个统一的抽象和管理,以至于各种数字和红点之间的关系错综复杂,牵一发而动全身。这样,在App的维护过程中,稍微有一点改动(比如增加几个数字或红点类型),出现问题的概率就很高。


本文会提出一个树型结构模型,来对数字和红点的层次结构进行统一管理,并会在文章最后给出一个可以运行的Android版的Demo程序,以供参考。


如果您现在手头正好有一部Android手机,那么您可以先扫描识别下面的二维码下载安装这个Demo,花几分钟看看它是否对您有用。注意:在微信中的正确操作步骤是,识别二维码后,点击右上角的“在浏览器中打开”,然后才能跳转到下载页面,最终完成下载(请在百度云的下载页面点击“普通下载”)。


图片


朴素的数字红点管理方式


为了讨论方便,我们首先对一般情况下数字和红点展示的需求做一个简单的整理,然后看看根据这样的需求最直观的实现方式可能是怎样的。



图片



图片


相信以上总结的几点,跟大多数App的展示逻辑大体类似。即使有一些差别,应该也不妨碍我们接下来的讨论。


好,现在我们就以上面App截图中的具体情形来考虑一下实现。“消息”Tab包含“收到的评论”、“收到的赞”和“系统消息”,其中评论和赞是数字,系统消息是红点。


我们单独考虑“消息”这个Tab上的数字红点展示逻辑,不难写出类似如下的代码(伪码):


图片


这段代码当然能实现需求,但是缺点也是很明显的。其中最关键的是,它要求在“消息”这个Tab上的展示逻辑要列举下面包含的所有子消息类型(评论、赞、系统消息),并且知道每个类型是数字还是红点。上面只是给出了两级页面的情况,如果出现三级页面甚至更多级呢?那么这些信息就要在各级页面上重复一遍。


这会造成维护和修改变得复杂。想象一下,在“消息”下面又增加了一个新的消息类型,或者某个类型的消息从数字展示变成红点展示了,甚至是某个类型的消息,从一个页面栈移动到了另一个页面栈了。所有这些情况,都要求更高层级的所有页面都对应进行修改。当一个App的消息类型越来越多,达到几十个的时候,可以想象这种修改是很容易出错的。


基于树型模型的数字红点管理方式


上面说的问题,我们在微爱App开发的初期也遇到过。后来,我们重新审视了App中红点和数字展示的结构,使用树型结构来看待它,让维护工作变得简单。


一个App的页面本身就是分级的,对于页面的访问路径本质上就是个树型结构。


图片

如上图所示,节点1代表第1级页面,这个页面下面包含三个更深一级(第2级)的页面入口,分别对应节点2,3,4。再深一级就到了终端页面,以绿色的方形节点表示。


这个树型的模型可以如下表述:



为了使得一个大类内的Badge Number能用一个类型区间来表达,我们在为类型分配值的时候,可以采取类似这样的方式:用一个int来表示Badge Number类型,而它的高16位用来表示大类。比如“消息”大类高16位是0x2的话,那么它包含的三种Badge Number类型(type)就可以这样分配:



这样,“消息”这一大类就可以用一个类型区间[(0x2 « 16) + 0x1, (0x2 « 16) + 0x3]来表达。


有了类型区间之后,我们重新看一下树型模型里面的中间节点。它们都可以用一个或多个类型区间来表示。它们的展示逻辑(是展示成数字,还是红点,还是隐藏),需要对所有子树的类型区间求和。具体求和过程是:



树型模型的代码实现


树型模型的实现,我们称为Badge Number Tree,本文提供了一个Android版的Demo实现,源码可以从GitHub下载:https://github.com/tielei/BadgeNumberTree 。


下面我们把关键部分分析一下。


Android版本的主要实现类为BadgeNumberTreeManager,它的关键代码如下(为了不影响我们理解主要逻辑,非关键代码在下面忽略了,没有贴出。如需查看请到GitHub下载源代码;下面代码请点击看大图):


图片


在这段代码中我们需要注意的点包括:



调用getTotalBadgeNumberOnParent的代码例子如下:


图片


关于实现上的一些补充说明



标签:数字,展示,Demo,App,Number,用树型,消息,Badge,页面
来源: https://blog.51cto.com/15049790/2562673