解决Android实现圆角效果在Android P以下成黑色
短信预约 -IT技能 免费直播动态提醒
背景
项目中测试反馈在Android P以下图片边黑了。看了一下项目代码发现是自定义圆角图片View造成的,review 代码发现实现原理很简单。就是如下图绘制出四个黄色的角,盖在图片上就行了。(PS:图画的比较粗糙,大家见谅)
先上代码
package com.wzc.xfermodedemo.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
public class RoundImageView extends AppCompatImageView {
private Paint mPaint;
private RectF mRoundRectF;
private Path mRoundPath;
private Path mRectanglePath;
private int mViewWidth;
private int mViewHeight;
private float[] mCornerRadius = new float[]{50, 50, 50, 50, 50, 50, 50, 50};
public RoundImageView(Context context) {
super(context);
initView();
}
public RoundImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView();
}
public RoundImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
mRoundRectF = new RectF();
mRoundPath = new Path();
mRectanglePath = new Path();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mViewWidth = w;
mViewHeight = h;
mRoundRectF.set(0, 0, w, h);
mRoundPath.reset();
mRoundPath.addRoundRect(mRoundRectF, mCornerRadius, Path.Direction.CW);
mRectanglePath.reset();
mRectanglePath.addRect(mRoundRectF, Path.Direction.CW);
mRectanglePath.op(mRoundPath, Path.Op.DIFFERENCE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.class="lazy" data-src_IN));
canvas.drawPath(mRectanglePath, mPaint);
mPaint.setXfermode(null);
}
}
运行复现一下
如下图,左边是在android9.0以下的效果,中间是android9.0及以上的效果,右边是想要的效果。中间的只要把蓝色改为Activity背景色就是想要的效果了。
解决办法:
1.去掉setXfermode
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(mRectanglePath, mPaint);
}
2.使用canvas.saveLayer
//第一种
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int sc = canvas.saveLayer(0, 0, mViewWidth, mViewHeight, null, Canvas.ALL_SAVE_FLAG);
//去掉setXfermode或者PorterDuff.Mode.class="lazy" data-src_IN改为PorterDuff.Mode.class="lazy" data-src
//mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.class="lazy" data-src));
canvas.drawPath(mRectanglePath, mPaint);
mPaint.setXfermode(null);
canvas.restoreToCount(sc);
}
//第二种
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int sc = canvas.saveLayer(0, 0, mViewWidth, mViewHeight, null, Canvas.ALL_SAVE_FLAG);
//如果不设置canvas.drawColor,只能是去掉setXfermode或者PorterDuff.Mode.class="lazy" data-src_IN改为PorterDuff.Mode.class="lazy" data-src
canvas.drawColor(Color.RED);
//如果设置了canvas.drawColor,PorterDuffXfermode可以是class="lazy" data-src_IN或者class="lazy" data-src,也可以是DST_IN(但是此时四个角的颜色是canvas.drawColor(XXX)设置的颜色
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.class="lazy" data-src_IN));
canvas.drawPath(mRectanglePath, mPaint);
mPaint.setXfermode(null);
canvas.restoreToCount(sc);
}
但就官方不建议使用该方法,具体可以看官方文档
3.关闭硬件加速
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.class="lazy" data-src_IN));
//关闭硬件加速,如果应用已经关闭的硬件加速设置LAYER_TYPE_HARDWARE和LAYER_TYPE_SOFTWARE效果是相同的
setLayerType(LAYER_TYPE_SOFTWARE, null);
canvas.drawPath(mRectanglePath, mPaint);
mPaint.setXfermode(null);
}
注意:你是无法在视图级别开启硬件加速的,如果你的应用已经关闭了硬件加速,那么设置LAYER_TYPE_HARDWARE和LAYER_TYPE_SOFTWARE 效果是相同的。可以看官方文档 视图级别关闭硬件加速 和 hardware layer
为什么是黑色的原因,我找了很久也没找到,如果有知道原因的,希望能告诉我一下,谢谢。
作者:一个小道士
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341