iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >解决Android实现圆角效果在Android P以下成黑色
  • 477
分享到

解决Android实现圆角效果在Android P以下成黑色

Android 2022-06-06 13:06:00 477人浏览 安东尼
摘要

背景 项目中测试反馈在Android P以下图片边黑了。看了一下项目代码发现是自定义圆角图片View造成的,review 代码发现实现原理很简单

背景
项目测试反馈在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.SRC_IN));
        canvas.drawPath(mRectanglePath, mPaint);
        mPaint.setXfermode(null);
    }
}

运行复现一下
如下图,左边是在android9.0以下的效果,中间是android9.0及以上的效果,右边是想要的效果。中间的只要把蓝色改为Activity背景色就是想要的效果了。
在android P以下变成黑色 在android P以上能正常显示 想要的效果

解决办法:

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.SRC_IN改为PorterDuff.Mode.SRC
        //mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.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.SRC_IN改为PorterDuff.Mode.SRC
        canvas.drawColor(Color.RED);
        //如果设置了canvas.drawColor,PorterDuffXfermode可以是SRC_IN或者SRC,也可以是DST_IN(但是此时四个角的颜色是canvas.drawColor(XXX)设置的颜色
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.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.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

为什么是黑色的原因,我找了很久也没找到,如果有知道原因的,希望能告诉我一下,谢谢。


作者:一个小道士


--结束END--

本文标题: 解决Android实现圆角效果在Android P以下成黑色

本文链接: https://www.lsjlt.com/news/29433.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作