将字符串转换为可绘制对象

10
我想要在状态栏中显示一个带有图标的通知 - 到目前为止还不错,但实际上我希望这个图标是一个包含3个字符的字符串。那么我的问题是:是否有一种方法将我的字符串转换为Drawable,以便在状态栏中显示它作为图标?编辑:我最近发现了一款类似的应用程序 - 电池指示器。它会在状态栏中显示当前电池电量作为通知图标 - 我想知道它是否真的使用了不同的100个图像。

Screenshot


3
以防有人感兴趣:我发现上述应用程序确实使用每个值一个图像。 - DonGru
这正是我所需要的。除了创建每个dpi值的100个带电池状态的png之外,你有找到其他解决方案吗? - vault
8个回答

3
   public Drawable getDrawable(String bitmapUrl) {
      try {
        URL url = new URL(bitmapUrl);
        Drawable d =new BitmapDrawable(BitmapFactory.decodeStream(url.openConnection().getInputStream()));
        return d; 
      }
      catch(Exception ex) {return null;}
    }

.setSmallIcon(int) 接受 int 作为输入,我该如何在其中使用 drawable? - Vishnudev K

3

简短回答:不能。

详细解释:通知需要一个R.drawable.something作为图标,而且你不能在运行时创建它。


2

您可以制作自己的自定义drawable,它的工作方式与TextView小部件类似,只是它是一个Drawable而不是一个View。 TextView类只是包含文本的Drawable的容器。


请问您能否提供至少一个能够实现该功能的代码草稿? - vault
2
@vault 我没有样例,但你需要做的是扩展Drawable并重写draw(Canvas)方法,然后只需从draw中调用canvas.drawText()即可。 - Nathan Schwermann

1
我使用了一个解决方法,对我来说它很有效。
首先我将字符串转换为位图,然后将其转换为可绘制对象,以下是代码:
byte [] encodeByte=Base64.decode(":",Base64.DEFAULT);
Bitmap bitmap=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);      
Drawable d = new BitmapDrawable(bitmap);

希望它有所帮助!

.setSmallIcon(int) 接受 int 作为输入,我该如何在其中使用 drawable? - Vishnudev K
你只能在接受Drawable参数的setLargeIcon方法中使用它,smallIcon只接受资源作为参数。 - gmemario
我尝试使用setLargeIcon,但图标从未显示。大图标何时会显示? - Vishnudev K

0

(我知道这并不能完全回答楼主的问题,但是标题吸引了我过来,因为它非常通用。)

经过一番摸索,我想出了这个解决方案。它相当混乱,可能还有改进的空间,但它能够工作。

在当前形式下,该函数获取传递给它的字符串的第一个字母和唯一的ID。该ID仅用于生成背景颜色并记住它,因此如果您要使用固定颜色,则可以将其删除。

我制作了这个函数来为没有保存图像的联系人生成默认图像,但很容易进行调整。它还返回InputStream而不是Drawable,但您可以在绘制后直接返回bitmap,或者使用Drawable.createFromStream()

private static InputStream returnDefaultContact(Context context, String name, long id) {
    Paint textPaint = new Paint();
    textPaint.setColor(Color.WHITE);
    textPaint.setTextAlign(Paint.Align.CENTER);
    textPaint.setTextSize(110);

    int color = PreferenceManager.getDefaultSharedPreferences(context).getInt("contact_by_id_" + id, 0);

    if (color == 0) {
        int colorValue1 = (int)((56 + Math.random() * 200));
        int colorValue2 = (int)((56 + Math.random() * 200));
        int colorValue3 = (int)((56 + Math.random() * 200));

        color = Color.rgb(colorValue1, colorValue2, colorValue3);

        PreferenceManager.getDefaultSharedPreferences(context).edit().putInt("contact_by_id_" + id, color).apply();
    }

    Paint backgroundPaint = new Paint();
    backgroundPaint.setColor(color);

    Bitmap bitmap = Bitmap.createBitmap(120, 120, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);

    canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, canvas.getHeight() / 2, backgroundPaint);

    int xPos = (canvas.getWidth() / 2);
    int yPos = (int) ((canvas.getHeight() / 2) - ((textPaint.descent() + textPaint.ascent()) / 2)) ;

    canvas.drawText(name.substring(0, 1), xPos, yPos, textPaint);

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
    byte[] imageInByte = stream.toByteArray();

    return new ByteArrayInputStream(imageInByte);
}

0

0

你看过API演示 > 应用程序 > 通知 > 状态栏吗?

如果你只有有限数量的字符串选项(比如表情符号),你可以为每个字符串创建可绘制对象。


我想避免这种情况,因为可能性太多了 :) - DonGru

-1
try  {

    InputStream inputStream = new URL(Your imageWebAddress).openStream();

    drawable = Drawable.createFromStream(inputStream, null);
    inputStream.close();
  }
  catch (MalformedURLException ex) { }
  catch (IOException ex) { }
  layout.setBackground(drawable);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接