【问题标题】:Make Notification Large Icon Round使通知大图标圆形
【发布时间】:2015-02-02 15:03:52
【问题描述】:

我想将来自用户联系人的圆形头像显示为通知的大图标 - 就像在接收文本或邮件时一样。当我将大图标设置为该联系人的图像时,它会生成一个方形图标。

我正在寻找看起来像顶部图标(方形头像)的东西,看起来像电子邮件通知上的大图标(圆形头像):

如何让它圆?

【问题讨论】:

标签: android android-notifications android-5.0-lollipop avatar


【解决方案1】:

由于setLargeIcon() 接受Bitmap,您只需从源创建一个循环Bitmap

下面是Create a circle bitmap in Android的代码(我自己没试过)。

private Bitmap getCircleBitmap(Bitmap bitmap) {
    final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
            bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(output);

    final int color = Color.RED;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
    final RectF rectF = new RectF(rect);

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawOval(rectF, paint);

    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    bitmap.recycle();

    return output;
}

【讨论】:

  • 我认为这可能是这样做的方法。感谢您的链接,它确实有效。我将稍微修改一下代码。
  • 我在使用宽度大于高度或高度大于宽度的图像时遇到问题,它们显示为椭圆形而不是圆形。我怎么解决这个问题?有人遇到过这个问题吗?
【解决方案2】:

接受的答案要求输入位图是一个完美的正方形(相同的高度和宽度)。如果您的位图是矩形的,它将返回一个椭圆形。我已修改代码以接受任何形状的位图并返回以输入位图中间为中心的圆圈。

public static Bitmap getCircleBitmap(Bitmap bitmap) {
    Bitmap output;
    Rect srcRect, dstRect;
    float r;
    final int width = bitmap.getWidth();
    final int height = bitmap.getHeight();

    if (width > height){
        output = Bitmap.createBitmap(height, height, Bitmap.Config.ARGB_8888);
        int left = (width - height) / 2;
        int right = left + height;
        srcRect = new Rect(left, 0, right, height);
        dstRect = new Rect(0, 0, height, height);
        r = height / 2;
    }else{
        output = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
        int top = (height - width)/2;
        int bottom = top + width;
        srcRect = new Rect(0, top, width, bottom);
        dstRect = new Rect(0, 0, width, width);
        r = width / 2;
    }

    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawCircle(r, r, r, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, srcRect, dstRect, paint);

    bitmap.recycle();

    return output;
}

【讨论】:

  • java.lang.IllegalStateException: 无法打包回收的位图
  • 这是最好的答案(见完美平方问题)
【解决方案3】:

Egor 的回答效果很好。在此处发布代码以防链接消失:

private Bitmap getCircleBitmap(Bitmap bitmap) {
 final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
  bitmap.getHeight(), Bitmap.Config.ARGB_8888);
 final Canvas canvas = new Canvas(output);

 final int color = Color.RED;
 final Paint paint = new Paint();
 final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
 final RectF rectF = new RectF(rect);

 paint.setAntiAlias(true);
 canvas.drawARGB(0, 0, 0, 0);
 paint.setColor(color);
 canvas.drawOval(rectF, paint);

 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
 canvas.drawBitmap(bitmap, rect, rect, paint);

 bitmap.recycle();

 return output;
}

【讨论】:

  • 最好更新一个仅链接的答案。无论如何,感谢您的努力。 :)
  • @Sufian 谢谢布鲁斯。
  • 如果您使用它在通知上显示图像,需要删除bitmap.recycle()。在我的代码中,看起来像:.setLargeIcon(getCircleBitmap(Picasso.with(this.context).load(pictureUrl).get()))。希望对您有所帮助。
【解决方案4】:

我认为当输入位图是一个完美的正方形(相同的高度和宽度)并给出完美的圆形时,它会正常工作,但如果您的位图是矩形或宽度大于高度,则会产生问题。我已将代码修改为 kotlin 还为其添加了边框,只有您需要将输入作为位图

private fun getCircleBitmap(bitmap: Bitmap): Bitmap 

  {

    var srcRect: Rect

    var dstRect: Rect

    var r: Float

    var paint = Paint();

    var width: Int = bitmap.getWidth()

    var height: Int = bitmap.getHeight()

    var widthToGenerate = 100F

    var heightToGenerate = 100F

    var borderWidth: Float = 1.toFloat()

    var output: Bitmap

    var canvas: Canvas

    if (width > height) {

        output = Bitmap.createBitmap(widthToGenerate.toInt(), heightToGenerate.toInt(), Bitmap.Config.ARGB_8888);

        canvas = Canvas(output);
        val scale: Float = (widthToGenerate / width)


        var xTranslation = 0.0f
        var yTranslation: Float = (heightToGenerate - height * scale) / 2.0f;


        var transformation = Matrix();
        transformation.postTranslate(xTranslation, yTranslation)
        transformation.preScale(scale, scale)

        var color: Int = Color.WHITE
        paint.setAntiAlias(true)
        paint.setColor(color)

        canvas.drawBitmap(bitmap, transformation, paint)

    } else {
        output = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888)
        canvas = Canvas(output);
        var top: Int = (height - width) / 2
        var bottom: Int = top + width
        srcRect = Rect(0, top, width, bottom)
        dstRect = Rect(0, 0, width, width);
        r = (width / 2).toFloat()


        var color: Int = Color.GRAY
        paint.setAntiAlias(true)
        canvas.drawARGB(0, 0, 0, 0)
        paint.setColor(color)


        canvas.drawCircle(r + borderWidth, r + borderWidth, r + borderWidth, paint)
        canvas.drawCircle(r, r, r, paint)
        paint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.SRC_IN))

        canvas.drawBitmap(bitmap, srcRect, dstRect, paint)

        bitmap.recycle()
    }

    return output

}

notifiation_drawable.xml 边框文件

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="2.0"
android:useLevel="false" >
<solid android:color="@android:color/transparent" />
<stroke
    android:width="2dp"
    android:color="@android:color/darker_gray" />

</shape>

【讨论】:

    猜你喜欢
    • 2018-06-19
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多