前言
桌面图标的角标,看着是个很简单的功能,就是在应用的右上角显示当前有几个未读消息;在网上查了资料之后,发现很多同行说,Android原生是没有此功能,平时使用的手机都有该功能,其实是国内手机厂商自己定制的桌面图标角标,且不同厂商之间,方案还不尽相同;但是此次我还是要看Android源生代码究竟是怎么显示应用有新的未读消息,此篇文章是以为记。
一
很直观,它是显示在应用的右上角的,那么我们要查看它,得先在代码中找到单个应用显示的类,根据上篇文章介绍,应用是在CellLayout平均分配的矩形中显示,可以先查看CellLayout的源码,在CellLayout的源码中,找到了下面的方法:
public boolean addViewToCellLayout(View child, int index, int childId, LayoutParams params,
boolean markCells) {
final LayoutParams lp = params;
// Hotseat icons - remove text
if (child instanceof BubbleTextView) {
BubbleTextView bubbleChild = (BubbleTextView) child;
bubbleChild.setTextVisibility(mContainerType != HOTSEAT);
}
child.setScaleX(mChildScale);
child.setScaleY(mChildScale);
// Generate an id for each view, this assumes we have at most 256x256 cells
// per workspace screen
if (lp.cellX >= 0 && lp.cellX <= mCountX - 1 && lp.cellY >= 0 && lp.cellY <= mCountY - 1) {
// If the horizontal or vertical span is set to -1, it is taken to
// mean that it spans the extent of the CellLayout
if (lp.cellHSpan < 0) lp.cellHSpan = mCountX;
if (lp.cellVSpan < 0) lp.cellVSpan = mCountY;
child.setId(childId);
if (LOGD) {
Log.d(TAG, "Adding view to ShortcutsAndWidgetsContainer: " + child);
}
mShortcutsAndWidgets.addView(child, index, lp);
if (markCells) markCellsAsOccupiedForView(child);
return true;
}
return false;
}
该方法是将子View添加到CellLayout中;而我们知道CellLayout中要么显示应用的快捷方式,要不显示桌面小部件,如果是Hotseat里么的CellLayout,那么它就只能显示应用的快捷方式,且不显示它的名称,从代码得知应用的快捷方式的类就是BubbleTextView。
// Hotseat icons - remove text
if (child instanceof BubbleTextView) {
BubbleTextView bubbleChild = (BubbleTextView) child;
bubbleChild.setTextVisibility(mContainerType != HOTSEAT);
}
在BubbleTextView源码中,确实有看到在该View的右上角画标记,但是没有发现有设置未读消息的代码,经过修改代码运行得知,此标记仅表示有新消息,但是没有消息的条数,具体修改代码如下:
protected void drawBadgeIfNecessary(Canvas canvas) {
//设置mBadgeScale以满足条件,画出右上角标记信息
mBadgeScale = 1.0f;
if (!mForceHideBadge && (hasBadge() || mBadgeScale > 0)) {
getIconBounds(mTempIconBounds);
mTempSpaceForBadgeOffset.set((getWidth() - mIconSize) / 2, getPaddingTop());
final int scrollX = getScrollX();
final int scrollY = getScrollY();
canvas.translate(scrollX, scrollY);
mBadgeRenderer.draw(canvas, mBadgeColor, mTempIconBounds, mBadgeScale,
mTempSpaceForBadgeOffset);
canvas.translate(-scrollX, -scrollY);
}
}