自定义View--圆形头像(用PorterDuff.Mode)

效果图:

自定义View--圆形头像(用PorterDuff.Mode)_第1张图片

与自定义view--刮刮卡类似的是,都是使用PorterDuff.Mode来实现效果,不同的是这次使用的是SRC_IN

代码:

自定义View--圆形头像(用PorterDuff.Mode)_第2张图片该例子中,SRC是那张头像图片,DST就是画的圆形,先画圆形,再设置mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));


public class GuaThree extends View {
    private Paint mPaint;//绘制mPath的画笔
    private Canvas mCanvas;
    private Bitmap mBitmap;
    private Bitmap src;
    int width ;
    int height ;
    int min;//画圆的半径
    public GuaThree(Context context) {
        this(context, null);
    }

    public GuaThree(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GuaThree(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获得控件的宽高
        width = getMeasuredWidth();
        height = getMeasuredHeight();
        min = Math.min(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawMyCanvas();
        canvas.drawBitmap(mBitmap, 0, 0, null);
    }

    private void drawMyCanvas(){
        //初始化bitmap
        mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);//用指定的位图构造一个画布来绘制。
        mCanvas.drawCircle(width / 2, height / 2, min / 2 - 20, mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        mCanvas.drawBitmap(src, 0, 0, mPaint);
    }

    /**  * 初始化信息  */  private void init() {
        // 禁止硬件加速,硬件加速会有一些问题,这里禁用掉
       setLayerType(LAYER_TYPE_SOFTWARE, null);
        mPaint = new Paint();
        src = BitmapFactory.decodeResource(getResources(),
                R.drawable.tou);
    }
}

我在上一篇文章中写刮刮卡的时候,临时画布mCanvas就是在onMeasure里面初始化并画相关的东西,但是在这个例子中,就出不来效果,参考的网友的代码,把mCanvas相关的操作放在onDraw()里面,就可以出来效果了,很神奇。有待后面研究。现在能想到的就是onMeasure会反复的执行,可能多次执行会引起很多问题吧。


题外话:

在自定义view--刮刮卡的基础上,本来实现篇文章的效果是很容易了,不就改个参数吗?可是我遇到的好多问题。

我直接在上一篇文章的基础上改属性,出不来效果,而且下面这图上的每个参数我都试了试,将近一半的参数与图上的效果不对应,百度了很多文章,也没有找到解决问题的关键,特别让自己很无语的是,有一部分能出来,一部分不能出来,比如Dst,DsrOver,DstOut,Xor和最下面一排都没有问题,剩下的很多都出不来效果,记不清楚是哪些了。

我疑问,按照图上的效果图,我之前的做法是,把头像图片当作Dst,绘制完了之后再设置画笔DstIn,之后再绘制圆形当作Src,这样是应该呈现出两则交汇(即所要的圆形头像部分)的地方显示,其他不显示。理论上是可以的啊,可是怎么都出不来。

然后找大神帮忙,大神看了许久,给了我一篇文章,该文章说上面的图是有问题的,具体看文章内容,他说他测量的效果图:

自定义View--圆形头像(用PorterDuff.Mode)_第3张图片

我看了之后,按照该作者的代码测试,的确和他给出的上图效果一模一样。

不过在我们的实际运用中,我们会觉得他们的图都有问题,我想原因应该是你选用的Src和Dst的大小的位置关系不同,你想象的效果也就有所不同。

比如:

以下是Clear参数值的效果图,两种情况都是没有错误的,当SRC很大而且位置刚好盖过DST的时候,那么效果图就是左边这个,如果两者只是相交一点点,那么效果图就是右边这个(绿色部分为背景颜色,即最外层布局,便于观看效果)

自定义View--圆形头像(用PorterDuff.Mode)_第4张图片


以下是Src参数值效果图,也是和上面一样的理解,如果蓝色框框太大就会覆盖掉黄色圆,这时候效果图就是左边,否则就是右边。


剩下的就不分析了,总的来说就是自己选择的SRC和DST大小和相对位置不同,效果和官网上的图会有所差别,不用一概而论,就像要那样的效果,所以,自己用的时候还是得动动脑袋。









你可能感兴趣的:(自定义View--圆形头像(用PorterDuff.Mode))