使用圆角可绘制

流行的Google开发人员Romain Guy 发表了一篇很好的文章 ,展示了如何有效地在视图上使用圆角可绘制(在他的代码中称为“StreamDrawable”)。

在纵向模式下,样本本身在我的Galaxy S3上工作得非常好,但我有一些问题:

  1. 如果屏幕较小(例如在qvga屏幕上),则会显示所显示的图像。

  2. 如果我的输入位图比我想要显示的位图小,输出图像的边缘会被涂抹。 即使在Galaxy S3上,当您运行示例代码并且它在横向上时,它看起来很糟糕:

    在此处输入图像描述

  3. 我仍然不确定它(因为我使用缩放图像以使用示例代码的解决方法),但它认为即使这个解决方案在listView中使用时有点慢。 也许这有一个renderscript解决方案?

如果我使用setImageDrawable或setBackgroundDrawable并不重要。 它必须是drawable本身的东西。

我试过玩variables和bitmapShader,但没有任何效果。 可悲的是, TileMode没有拉伸图像的值,只是以某种方式对其进行平铺。

作为一种解决方法,我可以创建一个新的缩放位图,但它只是一种解决方法。 当然有一种更好的方法,也不会使用更多的内存。

如何解决这些问题并使用这个优秀的代码?

我认为本网站提供的解决方案效果很好。

与其他解决方案不同,它不会导致内存泄漏,即使它基于Romain Guy的解决方案。

编辑:现在在支持库上,您还可以使用RoundedBitmapDrawable (使用RoundedBitmapDrawableFactory )。

我有这个代码的一些大小问题,我解决了它。

也许这也会对你有所帮助:

1)在构造函数中将位图存储在局部variables中(例如私有Bitmap bmp;)

2)覆盖另外两种方法:

@Override public int getIntrinsicWidth() { return bmp.getWidth(); } @Override public int getIntrinsicHeight() { return bmp.getHeight(); } 

最好的问候,DaRolla

潜在的问题是BitmapShader的TileMode没有缩放选项。 您将在源代码中注意到它已设置为Shader.TileMode.CLAMP ,并且文档将其描述为:

如果着色器在其原始边界之外绘制,则复制边缘颜色

要解决这个问题,有三种解决方案:

  1. 将使用drawable的视图的大小限制为位图的大小。
  2. 约束绘图区域; 例如,改变:

     int width = bounds.width() - mMargin; int height = bounds.height() - mMargin; mRect.set(mMargin, mMargin, width, height); 

    至:

     int width = Math.min(mBitmap.getWidth(), bounds.width()) - mMargin; int height = Math.min(mBitmap.getHeight(), bounds.height()) - mMargin; mRect.set(mMargin, mMargin, width, height); 
  3. 将位图缩放到drawable的大小。 我已经将着色器创建为onBoundsChange(),并选择从此处创建一个新的位图:

     bitmap = Bitmap.createScaledBitmap(mBitmap, width, height, true); mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 

    请注意,这可能是一个很慢的操作,并将在主线程上运行。 在进行最后一个解决方案之前,您可能需要仔细考虑如何实现它。