一个简单的圆形图片实现

来源:互联网 发布:淘宝最新规则大全 编辑:程序博客网 时间:2024/05/16 16:59

序言

很多时候我们都需要使用到圆形的图像控件,比如头像之类的。如果是开发者自己设计界面的时候使用,取巧的方法就是让美工给你做一个圆形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>

效果图:

上面是原图,下面是圆形图像控件。
但是你会发现,是这张图片切得刚好大小,我们换张大点的试试。

效果并不是我们所想要的。
那么如何改进呢?我们是否可以根据控件的大小来显示图像并将图像进行缩放呢?
改进后:

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);    }}

效果图:

0 0