由于Android在9.0 改变了绘制透明像素的方式,所以导致Xformode无法通过透明像素裁剪或者拼接边界,具体改变如下:
SDK_VERSION < 9.0 的情况下:
透明像素按 透明像素绘制 即 hex Color(ARGB): #00000000
SDK_VERSION >= 9.0的情况下
透明像素不在被绘制
由于Xformode 是通过相同位置是否透明 来进行裁剪 或者 拼接
所以 XFormode 在9.0即以上系统上可能 没办法实现期望的功能
Google的答复在下面:
https://issuetracker.google.com/issues/111819103(需要翻墙)
为了很多不能翻墙的同志们, 将谷歌的回复粘贴如下:
In Android O, the paths are drawn as rectangles covering the entire path bounds. The inverse path pixels are drawn with transparent pixels.
In Android P, only the paths pixels that have a fill are drawn. The inverse path pixels are not touched/drawn at all, which is faster.
Sample.apk draws a rounded rect over an image. The PorterDuff mode is not important at corners, because there is no blending/drawing in Android P.
To achieve a round rect image, I suggest 3 ways:
- Use android.view.ViewOutlineProvider (as per example here https://github.com/googlesamples/android-ClippingBasic).
- Replace the ImageView with a BitmapShader, which is fast (each pixel is drawn once) and more portable way as BitmapShader is supported in API level 1.
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.spiderman);
Shader shader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
Path corners = new Path();
corners.addRoundRect(bounds, radii, Path.Direction.CW);
canvas.drawPath(corners, paint);
- Draw an inverse path with SRC_OVER on top of the ImageView. This works if background is solid color and it is slower, because some pixels are drawn twice.
该问题回答的也是一个比较典型的问题:提出问题的人是想 实现圆形图片,由于Xformode 不能在用了。Google也提出了各种解决方案,大概翻译下:
1.使用ViewOutLineProvider(Sample:https://github.com/googlesamples/android-ClippingBasic)
2.使用Paint的 BitmapShader(位图渲染器)
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.spiderman);
Shader shader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
Path corners = new Path();
corners.addRoundRect(bounds, radii, Path.Direction.CW);
canvas.drawPath(corners, paint);
3.使用反选(即目标是圆形,反选即选中是圆形外部的部分)后的圆形图片 并使用Xformode的 SRC_OVER来裁剪图片。但是不推荐,因为像素会被绘制两遍