Android实现圆角和圆形

转载自:http://blog.csdn.NET/lmj623565791/article/details/24555655
自定义View实现圆角和圆形的效果:
这里写图片描述

核心代码

/**
     * 根据原图和变长绘制圆形图片
     *
     * @param _bitmap
     * @param _min
     * @return
     */
    private Bitmap createCircleImage(Bitmap _bitmap, int _min) {
        Paint _paint = new Paint();
        _paint.setAntiAlias(true);
        Bitmap _target = Bitmap.createBitmap(_min, _min, Bitmap.Config.ARGB_8888);
        //产生一个同样大小的画布
        Canvas _canvas = new Canvas(_target);
        //首先绘制圆形
        _canvas.drawCircle(_min / 2, _min / 2, _min / 2, _paint);
        //使用SRC_IN
        _paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //绘制图片
        _canvas.drawBitmap(_bitmap, 0, 0, _paint);
        return _target;
    }

其实主要靠:paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));这行代码,为什么呢,我给大家解释下,SRC_IN这种模式,两个绘制的效果叠加后取交集展现后图,怎么说呢,咱们第一个绘制的是个圆形,第二个绘制的是个Bitmap,于是交集为圆形,展现的是BItmap,就实现了圆形图片效果。圆角,其实就是先绘制圆角矩形,是不是很简单,以后别人再说实现圆角,你就把这一行代码给他就行了。
从Android的示例中,给大家证明一下:
下面有一张PorterDuff.Mode的16中效果图,咱们的只是其一:
这里写图片描述
源码咱们只关心谁先谁后绘制的:

canvas.translate(x, y);  
canvas.drawBitmap(mDstB, 0, 0, paint);  
paint.setXfermode(sModes[i]);  
canvas.drawBitmap(mSrcB, 0, 0, paint);  
paint.setXfermode(null);  
canvas.restoreToCount(sc);

可以看出先绘制的Dst,再绘制的Src,最后的展示是SrcIn那个图:显示的区域是二者交集,展示的是Src(后者)。和咱们前面结论一致。效果16种,大家可以自由组合展示不同的效果。

一、自定义属性

<declare-styleable name="CustomCircleImage">
        <attr name="borderRadius" format="dimension" />
        <attr name="type">
            <enum name="circle" value="0" />
            <enum name="round" value="1" />
        </attr>
        <attr name="src" format="reference" />
    </declare-styleable>

二、构造函数中获取属性

private int mType;
    private static final int TYPE_CIRCLE = 0;
    private static final int TYPE_ROUND = 1;

    //图片
    private Bitmap mBitmap;
    //圆角的大小
    private int mRadius;
    //控件的宽度
    private int mWidth;
    //控件的高度
    private int mHeight;

    public CustomCircleImage(Context context) {
        this(context, null);
    }

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

    public CustomCircleImage(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray _typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomCircleImage);
        mRadius = (int) _typedArray.getDimension(R.styleable.CustomCircleImage_borderRadius, 10);
        mType = _typedArray.getInt(R.styleable.CustomCircleImage_type, 0);
        mBitmap = BitmapFactory.decodeResource(getResources(), _typedArray.getResourceId(R.styleable.CustomCircleImage_src, 0));
        _typedArray.recycle();
    }

三、onMeasure方法

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = getOnMeasure(widthMeasureSpec);
        mHeight = getOnMeasure(heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);
    }

    private int getOnMeasure(int _measureSpec) {
        int _size = 100;
        int _measureMode = View.MeasureSpec.getMode(_measureSpec);
        int _measureSize = View.MeasureSpec.getSize(_measureSpec);
        if (MeasureSpec.EXACTLY == _measureMode) {
            _size = _measureSize;
        }
        return _size;
    }

四、onDraw方法

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        switch (mType) {
            //如果是绘制圆形
            case TYPE_CIRCLE:
                //长度如果不一致,则按照小的进行压缩
                int _min = Math.min(mWidth, mHeight);
                mBitmap = Bitmap.createScaledBitmap(mBitmap, _min, _min, false);
                canvas.drawBitmap(createCircleImage(mBitmap, _min), 0, 0, null);
                break;
            case TYPE_ROUND:
                canvas.drawBitmap(createRoundImage(mBitmap), 0, 0, null);
                break;
        }
    }

    /**
     * 根据原图和变长绘制圆形图片
     *
     * @param _bitmap
     * @param _min
     * @return
     */
    private Bitmap createCircleImage(Bitmap _bitmap, int _min) {
        Paint _paint = new Paint();
        _paint.setAntiAlias(true);
        Bitmap _target = Bitmap.createBitmap(_min, _min, Bitmap.Config.ARGB_8888);
        //产生一个同样大小的画布
        Canvas _canvas = new Canvas(_target);
        //首先绘制圆形
        _canvas.drawCircle(_min / 2, _min / 2, _min / 2, _paint);
        //使用SRC_IN
        _paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //绘制图片
        _canvas.drawBitmap(_bitmap, 0, 0, _paint);
        return _target;
    }

    /**
     * 根据原图添加圆角
     *
     * @param _bitmap
     * @return
     */
    private Bitmap createRoundImage(Bitmap _bitmap) {
        Paint _paint = new Paint();
        _paint.setAntiAlias(true);
        Bitmap _target = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        //产生一个同样大小的画布
        Canvas _canvas = new Canvas(_target);
        RectF rect = new RectF(0, 0, _bitmap.getWidth(), _bitmap.getHeight());
        _canvas.drawRoundRect(rect, mRadius, mRadius, _paint);
        _paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        _canvas.drawBitmap(_bitmap, 0, 0, _paint);
        return _target;
    }

五、布局中使用

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.millet.myblogexercise.CustomCircleImage.CustomCircleImage
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:src="@mipmap/d"
        app:type="circle" />

</RelativeLayout>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可生成圆形、方形、及方形的组合头像。项目地址:https://github.com/Pedroafa/avatar-android 效果图:如何使用:首先创建个ImageView<ImageView             android:id="@ id/roundedAvatar"             android:layout_height="fill_parent"             android:layout_width="fill_parent"/>2. //通过AvatarDrawableFactory生成各种形状的Drawable AvatarDrawableFactory avatarDrawableFactory = new AvatarDrawableFactory(getResources()); BitmapFactory.Options options = new BitmapFactory.Options(); options.inMutable = false; Bitmap avatar = BitmapFactory.decodeResource(getResources(), R.drawable.avatar, options); //圆形的 Drawable roundedAvatarDrawable = avatarDrawableFactory.getRoundedAvatarDrawable(avatar);//生成圆形的Drawable ImageView roundedAvatarView = (ImageView)rootView.findViewById(R.id.roundedAvatar); roundedAvatarView.setImageDrawable(roundedAvatarDrawable);其他形状的://圆形的且带边框的 Drawable borderedRoundedAvatarDrawable = avatarDrawableFactory.getBorderedRoundedAvatarDrawable(avatar); ImageView borderedRoundedAvatarView = (ImageView)rootView.findViewById(R.id.borderedRoundedAvatar); borderedRoundedAvatarView.setImageDrawable(borderedRoundedAvatarDrawable); //方形的 Drawable squaredAvatarDrawable = avatarDrawableFactory.getSquaredAvatarDrawable(avatar); ImageView squaredAvatarView = (ImageView)rootView.findViewById(R.id.squaredAvatar); squaredAvatarView.setImageDrawable(squaredAvatarDrawable); //俩个方形的组合头像 Drawable doubleSquaredAvatarDrawable = avatarDrawableFactory.getSquaredAvatarDrawable(avatar, avatar); ImageView doubleSquaredAvatarView = (ImageView)rootView.findViewById(R.id.doubleSquaredAvatar); doubleSquaredAvatarView.setImageDrawable(doubleSquaredAvatarDrawable); //三个方形的组合头像 Drawable tripleSquaredAvatarDrawable = avatarDrawableFactory.getSquaredAvatarDrawable(avatar, avatar, avatar); ImageView tripleSquaredAvatarView = (ImageView)rootView.findViewById(R.id.tripleSquaredAvatar); tripleSquaredAvatarView.setImageDrawable(tripleSquaredAvatarDrawable); //四个方形的组合头像 Drawable quadrupleSquaredAvatarDrawable = avatarDrawableFactory                     .getSquaredAvatarDrawable(avatar, avatar, avatar, avatar); ImageView quadrupleSquaredAvatarView = (ImageView)rootView.findViewById(R.id.quadrupleSquaredAvatar); quadrupleSquaredAvatarView.setImageDrawable(quadrupleSquaredAvatarDrawable);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值