Android自定义圆形ImageView

相关的说明都在注释里面了

package com.example.a_0102.mylearn.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.example.a_0102.mylearn.R;

/**
 * Created by a-0102 on 2018/7/9.
 */

public class CustomView extends ImageView {

    private Paint paint = new Paint();

    // 如果View是在Java代码里面new的,则调用第一个构造函数
    public CustomView(Context context) {
        this(context,null);
    }

    // 如果View是在.xml里声明的,则调用第二个构造函数
    public CustomView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    // 不会自动调用
    // 一般是在第二个构造函数里主动调用
    // 如View有style属性时
    // 自定义属性是从AttributeSet参数传进来的
    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //继承ImageView才会有这个方法,记住在xml文件中使用src去设置,不要用background,下面也不要用getBackground,这两种情况一个会报空指针一个可能的得不到你想要效果
        Drawable drawable = getDrawable();
        Bitmap bitmap = null;
        if(drawable!=null){
            BitmapDrawable bd = (BitmapDrawable) drawable;
            bitmap = bd.getBitmap();
        }else {
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.imt_test);
        }
        //将绘制操作保存到新的图层(更官方的说法应该是离屏缓存)
        // saveLayer可以为canvas创建一个新的透明图层,在新的图层上绘制,并不会直接绘制到屏幕上,而会在restore之后,绘制到上一个图层或者屏幕上(如果没有上一个图层)。
        // 为什么会需要一个新的图层,例如在处理xfermode的时候,原canvas上的图(包括背景)会影响src和dst的合成,这个时候,使用一个新的透明图层是一个很好的选择。
        // 又例如需要当前绘制的图形都带有一定的透明度,那么创建一个带有透明度的图层,也是一个方便的选择。
        canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);

        paint.setAntiAlias(true);
        //绘制目标图
        canvas.drawCircle(getWidth()/2, getHeight()/2 , getHeight() / 2, paint);
        //目标图和源图的模式,这里使用的是目标图和源图相交的区域画源图
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //绘制源图
        canvas.drawBitmap(bitmap, 0, 0, paint);//将图片画出来
        paint.setXfermode(null);
        canvas.restore();
    }
}

参考文档:
【Android - 自定义View】之自定义View浅析

猜你喜欢

转载自blog.csdn.net/hello_1s/article/details/81129501