一个简单的圆形图片实现

序言

很多时候我们都需要使用到圆形的图像控件,比如头像之类的。如果是开发者自己设计界面的时候使用,取巧的方法就是让美工给你做一个圆形ICON,但很多时候是需要显示用户上传的图像,这时候做一个通用的圆形图像控件是有必要的,那如何实现呢?

正文

Android图像控件一般是使用ImageView,那么我们这个自定义CircleView的圆形图像控件就继承于该控件。

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;


/**
 * Helen 2015-05-13 
 */
public class CircleView extends ImageView{
    private Bitmap mSrcBitmap;//ImageView设置的图像资源文件
    private Bitmap mOut;
    private Paint mPaint;//画笔
    public CircleView(Context context) {
        super(context);
        init();
    }

    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

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

    private void init(){

        //setLayerType(LAYER_TYPE_SOFTWARE,null);//禁用硬件加速
        mSrcBitmap=((BitmapDrawable)getDrawable()).getBitmap();
   mOut=Bitmap.createBitmap(mSrcBitmap.getWidth(),mSrcBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        Canvas canvas=new Canvas(mOut);
        //Dst
        canvas.drawCircle(mOut.getWidth() / 2, mOut.getHeight() / 2,mOut.getWidth() / 2, mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //Src
        canvas.drawBitmap(mSrcBitmap,0,0,mPaint);
        mPaint.setXfermode(null);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mOut,0,0,null);
    }

}

实现的方法是使用Paint的Xfermode属性。需要了解的请戳这里
布局文件如下activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/test"
        android:layout_above="@+id/view"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="64dp" />
    <com.hbase.view.CircleView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@mipmap/test"
        android:id="@+id/view" />
RelativeLayout>

效果图:
一个简单的圆形图片实现_第1张图片
上面是原图,下面是圆形图像控件。
但是你会发现,是这张图片切得刚好大小,我们换张大点的试试。
一个简单的圆形图片实现_第2张图片
效果并不是我们所想要的。
那么如何改进呢?我们是否可以根据控件的大小来显示图像并将图像进行缩放呢?
改进后:

package com.hbase.view;

import android.content.Context;
import android.graphics.Bitmap;
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.util.AttributeSet;
import android.widget.ImageView;


/**
 * Helen 2015-05-13
 */
public class CircleView extends ImageView{
    private Bitmap mSrcBitmap;//ImageView设置的图像资源文件
    private Bitmap mOut;
    private Paint mPaint;//画笔
    public CircleView(Context context) {
        super(context);
        //init();
    }

    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //init();
    }

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

    private void init(){
        //setLayerType(LAYER_TYPE_SOFTWARE,null);//禁用硬件加速
        Drawable d=getDrawable();
        if(d==null) return;
        mSrcBitmap=((BitmapDrawable)d).getBitmap();
        //mOut=Bitmap.createBitmap(mSrcBitmap.getWidth(),mSrcBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        mSrcBitmap=Bitmap.createScaledBitmap(mSrcBitmap,getWidth(),getHeight(),true);//设置缩放
        mOut=Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        Canvas canvas=new Canvas(mOut);
        //Dst
        canvas.drawCircle(getWidth() / 2, getHeight() / 2,getWidth() / 2, mPaint);
        //canvas.drawCircle(mOut.getWidth() / 2, mOut.getHeight() / 2,mOut.getWidth() / 2, mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //Src
        canvas.drawBitmap(mSrcBitmap,0,0,mPaint);
        mPaint.setXfermode(null);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        //只有在onDraw中才能获取到控件的宽高
        init();
        canvas.drawBitmap(mOut,0,0,null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width=Math.min(getMeasuredHeight(),getMeasuredWidth());
        //因为是要圆形图像,所以将控件的宽高设置为一样
        setMeasuredDimension(width,width);
    }
}

效果图:
一个简单的圆形图片实现_第3张图片

你可能感兴趣的:(Android学习笔记)