gpt4 book ai didi

Android自定义 ImageView 形状

转载 作者:行者123 更新时间:2023-11-29 15:49:46 27 4
gpt4 key购买 nike

我正在创建一个自定义 ImageView,它将我的图像裁剪成六边形并添加边框。我想知道我的方法是否正确,或者我是否以错误的方式这样做。有很多自定义库已经在执行此操作,但开箱即用的库中没有一个具有我正在寻找的形状。话虽如此,这更多是关于最佳实践的问题。

expected result

您可以在这个 gist 中看到完整的类(class),但主要问题是这是最好的方法。我觉得不对劲,部分原因是一些神奇的数字意味着它可能会在某些设备上搞砸。

这是代码的核心:

      @Override      protected void onDraw(Canvas canvas) {        Drawable drawable = getDrawable();        if (drawable == null || getWidth() == 0 || getHeight() == 0) {          return;        }        Bitmap b = ((BitmapDrawable) drawable).getBitmap();        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);        int dimensionPixelSize = getResources().getDimensionPixelSize(R.dimen.width); // (width and height of ImageView)        Bitmap drawnBitmap = drawCanvas(bitmap, dimensionPixelSize);        canvas.drawBitmap(drawnBitmap, 0, 0, null);      }      private Bitmap drawCanvas(Bitmap recycledBitmap, int width) {        final Bitmap bitmap = verifyRecycledBitmap(recycledBitmap, width);        final Bitmap output = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);        final Canvas canvas = new Canvas(output);        final Rect rect = new Rect(0, 0, width, width);        final int offset = (int) (width / (double) 2 * Math.tan(30 * Math.PI / (double) 180)); // (width / 2) * tan(30deg)        final int length = width - (2 * offset);        final Path path = new Path();        path.moveTo(width / 2, 0); // top        path.lineTo(0, offset); // left top        path.lineTo(0, offset + length); // left bottom        path.lineTo(width / 2, width); // bottom        path.lineTo(width, offset + length); // right bottom        path.lineTo(width, offset); // right top        path.close(); //back to top        Paint paint = new Paint();        paint.setStrokeWidth(4);        canvas.drawARGB(0, 0, 0, 0);        canvas.drawPath(path, paint);        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));        canvas.drawBitmap(bitmap, rect, rect, paint); // draws the bitmap for the image        paint.setColor(Color.parseColor("white"));        paint.setStrokeWidth(4);        paint.setDither(true);        paint.setStyle(Paint.Style.STROKE);        paint.setStrokeJoin(Paint.Join.ROUND);        paint.setStrokeCap(Paint.Cap.ROUND);        paint.setPathEffect(new CornerPathEffect(10));        paint.setAntiAlias(true); // draws the border        canvas.drawPath(path, paint);        return output;      }

我正在查看一些 iOS 代码,他们能够将实际图像应用为蒙版来实现此结果。 Android 上有没有类似的东西?

最佳答案

长期以来,我一直在寻找最佳方法。您的解决方案非常繁重,不适用于动画。 clipPath 方法不使用抗锯齿功能,并且不适用于某些版本的 Android(4.0 和 4.1?)上的硬件加速。似乎最好的方法(动画友好、抗锯齿、非常干净和硬件加速)是使用 Canvas 层:

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private static PorterDuffXfermode pdMode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);

@Override
public void draw(Canvas canvas) {
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(),
null, Canvas.ALL_SAVE_FLAG);

super.draw(canvas);

paint.setXfermode(pdMode);
canvas.drawBitmap(maskBitmap, 0, 0, paint);

canvas.restoreToCount(saveCount);
paint.setXfermode(null);
}

您可以使用任何类型的 mask ,包括自定义形状和位图。 Carbon使用这种方法动态地对小部件进行圆角处理。

关于Android自定义 ImageView 形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30871568/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com