当前位置: 首页 > 知识库问答 >
问题:

如何在动作栏中制作一个带有通知数量的图标?[副本]

别子实
2023-03-14

我想让一个通知图标在动作栏内通知的数量。

例如(Google Adsence):

我在stackoverflow上找到了这个答案,但它没有完全回答我的问题,因为在本例中,它只是数字,而不是带有数字的图标:带有计数的Actionbar通知图标

共有1个答案

汪皓
2023-03-14

经过大量的尝试,几乎所有的资源,所以我转向博客;成功了。我想分享对我起作用的方法(Api>=13)。

让我们从它在代码中的使用方式开始:

 public boolean onCreateOptionsMenu(Menu menu) {
    //inflate menu
    getMenuInflater().inflate(R.menu.menu_my, menu);

    // Get the notifications MenuItem and LayerDrawable (layer-list)
    MenuItem item = menu.findItem(R.id.action_notifications);
    LayerDrawable icon = (LayerDrawable) item.getIcon();

    // Update LayerDrawable's BadgeDrawable
    Utils2.setBadgeCount(this, icon, 2);

    return true;
}

menu_my.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">
    <item
        android:id="@+id/action_notifications"
        android:icon="@drawable/ic_menu_notifications"
        android:title="Notifications"
        app:showAsAction="always" />
</menu>
public class BadgeDrawable extends Drawable {

    private float mTextSize;
    private Paint mBadgePaint;
    private Paint mTextPaint;
    private Rect mTxtRect = new Rect();

    private String mCount = "";
    private boolean mWillDraw = false;

    public BadgeDrawable(Context context) {
        //mTextSize = context.getResources().getDimension(R.dimen.badge_text_size);
        mTextSize = 12F;

        mBadgePaint = new Paint();
        mBadgePaint.setColor(Color.RED);
        mBadgePaint.setAntiAlias(true);
        mBadgePaint.setStyle(Paint.Style.FILL);

        mTextPaint = new Paint();
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

    @Override
    public void draw(Canvas canvas) {
        if (!mWillDraw) {
            return;
        }

        Rect bounds = getBounds();
        float width = bounds.right - bounds.left;
        float height = bounds.bottom - bounds.top;

        // Position the badge in the top-right quadrant of the icon.
        float radius = ((Math.min(width, height) / 2) - 1) / 2;
        float centerX = width - radius - 1;
        float centerY = radius + 1;

        // Draw badge circle.
        canvas.drawCircle(centerX, centerY, radius, mBadgePaint);

        // Draw badge count text inside the circle.
        mTextPaint.getTextBounds(mCount, 0, mCount.length(), mTxtRect);
        float textHeight = mTxtRect.bottom - mTxtRect.top;
        float textY = centerY + (textHeight / 2f);
        canvas.drawText(mCount, centerX, textY, mTextPaint);
    }

    /*
    Sets the count (i.e notifications) to display.
     */
    public void setCount(int count) {
        mCount = Integer.toString(count);

        // Only draw a badge if there are notifications.
        mWillDraw = count > 0;
        invalidateSelf();
    }

    @Override
    public void setAlpha(int alpha) {
        // do nothing
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        // do nothing
    }

    @Override
    public int getOpacity() {
        return PixelFormat.UNKNOWN;
    }
}
public class Utils2 {
    public static void setBadgeCount(Context context, LayerDrawable icon, int count) {

        BadgeDrawable badge;

        // Reuse drawable if possible
        Drawable reuse = icon.findDrawableByLayerId(R.id.ic_badge);
        if (reuse != null && reuse instanceof BadgeDrawable) {
            badge = (BadgeDrawable) reuse;
        } else {
            badge = new BadgeDrawable(context);
        }

        badge.setCount(count);
        icon.mutate();
        icon.setDrawableByLayerId(R.id.ic_badge, badge);
    }


}
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/ic_notification"
        android:drawable="@drawable/ice_skate"
        android:gravity="center" />

    <!-- set a place holder Drawable so android:drawable isn't null -->
    <item
        android:id="@+id/ic_badge"
        android:drawable="@drawable/ice_skate" />
</layer-list>

祝你好运!

 类似资料:
  • 我想用我自己的推送通知图标替换默认图标。 现在,应用程序将图标显示为白色框。

  • 我在某处读到,我们可以使用来隐藏状态栏中的图标,使其不被通知。但在android 8及以上版本中似乎行不通。 所以我使用了(根据文档将图标隐藏在状态栏中),但这对我并不起作用。 但很多应用程序在状态栏中不显示任何图标,而在通知抽屉中显示通知。

  • 问题内容: 是2D数组。我想要一个新变量,其值与数组相同。此外, 使用Y进行的任何其他操作都不应影响X的值。 在我看来使用起来很自然。但是它不适用于数组。如果我这样做,然后更改y,x也会更改。我发现问题可以这样解决: 但是它不适用于2D阵列。例如: 返回。如果我替换为,这也无济于事。 有人知道什么是正确且简单的方法吗? 问题答案: 尝试这个: 我不确定,也许就足够了。

  • 我有一个显示自定义通知的应用程序。问题是在Android5运行时,通知栏中的小图标显示为白色。我该怎么解决这个?

  • 问题内容: 我想对Python中的函数进行深拷贝。该 副本 模块是没有帮助的,根据文件,其中说: 该模块不复制诸如模块,方法,堆栈跟踪,堆栈框架,文件,套接字,窗口,数组或任何类似类型的类型。它通过不变地返回原始对象来“复制”函数和类(浅层和深层)。这与泡菜模块处理这些食物的方式兼容。 我的目标是使两个函数具有相同的实现,但具有不同的文档字符串。 那怎么办呢? 问题答案: FunctionType

  • 我正在读这本书:Flask Web developmen。下面是这本书在地址栏中添加图标的代码: 我的问题是:为什么它需要两个链接来添加一个图标。在HTML中,这个oneline就足以完成这个任务了。不是吗?