android自定义view-打造圆形ImageView(三)

前言:

时隔了一个星期,由于毕业论文的事情一直耽搁了写博客,今天有了点空闲时间把上次的圆形图片继续讲完。前面两篇分别用了BitmapShader和Xfermode方式实现了圆形圆角图片,详情请戳android自定义view-打造圆形ImageView(一)、android自定义view-打造圆形ImageView(二)。好,今天我们用比较简单的drawable加上BitmapShader方式去实现,这样做的好处就是省略了自定义view的onMeasure的过程,看起来挺简洁的。

效果图:

android自定义view-打造圆形ImageView(三)_第1张图片

正文:

Step1:继承自drawable

public class RoundDrawableImageView extends Drawable
Step2:在构造方法中初始化画笔等属性:

public RoundDrawableImageView(Bitmap bitmap) {
		mBitmap = bitmap;
		BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setShader(shader);
	}
Step3:重写drawable的几个方法

	@Override
	public int getIntrinsicWidth() {
		return mBitmap.getWidth();
	}

	@Override
	public int getIntrinsicHeight() {
		return mBitmap.getHeight();
	}

	@Override
	public void draw(Canvas canvas) {
		canvas.drawRoundRect(rectF, borderRadius, borderRadius, paint);
	}

	@Override
	public void setAlpha(int alpha) {
		paint.setAlpha(alpha);
	}

	@Override
	public void setColorFilter(ColorFilter cf) {
		paint.setColorFilter(cf);
	}

	@Override
	public int getOpacity() {
		return PixelFormat.TRANSLUCENT;
	}

	@Override
	public void setBounds(int left, int top, int right, int bottom) {
		super.setBounds(left, top, right, bottom);
		// 设置绘制范围
		rectF = new RectF(left, top, right, bottom);
	}
这几个方法中最重要的莫过于draw()方法,其实和前面view中的onDraw是一样的。绘制圆角需要确定绘制范围,我们重写drawable的setBounds方法,在其中获取绘制范围。这边的getOpacity返回的是多alpha值的常量。

Step4:公布设置borderRadius方法

/**
	 * 设置圆角borderRadius
	 * 
	 * @param radius
	 */
	public void setBorderRadius(int radius) {
		this.borderRadius = radius;
	}
Step5:使用

activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/id_img"
        android:layout_width="250.0dip"
        android:layout_height="150.0dip"
        android:layout_gravity="center_horizontal" />
     <ImageView
        android:id="@+id/id_img1"
        android:layout_width="250.0dip"
        android:layout_height="150.0dip"
        android:layout_gravity="center_horizontal" />

</LinearLayout>
MainActivity.java:

package com.beyole.roundimageview;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;

import com.beyole.view.CircleDrawableImageView;
import com.beyole.view.RoundDrawableImageView;

public class MainActivity extends Activity {

	private ImageView imageView,imageView1;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		imageView = (ImageView) findViewById(R.id.id_img);
		imageView1 = (ImageView) findViewById(R.id.id_img1);
		Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.demo);
		imageView.setImageDrawable(new CircleDrawableImageView(bitmap));
		imageView1.setImageDrawable(new RoundDrawableImageView(bitmap));
	}
}
是不是觉得很方便,只需要将图片转换为bitmap使用就行了,不过这边个人觉得网络获取的图片不适合此种方式,还是用之前的两种方式比较好一点。额,忘记贴圆形图片的drawable了:

CircleDrawableImageView.java:

package com.beyole.view;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;

public class CircleDrawableImageView extends Drawable {

	private Bitmap mBitmap;
	private Paint mPaint;
	private int mWidth;

	public CircleDrawableImageView(Bitmap bitmap) {
		mBitmap = bitmap;
		BitmapShader shader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mPaint.setShader(shader);
		mWidth = Math.min(mBitmap.getWidth(), mBitmap.getHeight());
	}

	@Override
	public int getIntrinsicWidth() {
		return mWidth;
	}

	@Override
	public int getIntrinsicHeight() {
		return mWidth;
	}

	@Override
	public void draw(Canvas canvas) {
		canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2, mPaint);
	}

	@Override
	public void setAlpha(int alpha) {
		mPaint.setAlpha(alpha);
	}

	@Override
	public void setColorFilter(ColorFilter cf) {
		mPaint.setColorFilter(cf);
	}

	@Override
	public int getOpacity() {
		return PixelFormat.TRANSLUCENT;
	}

}
处理流程和上面圆角的差不多,唯一的区别就是我们不需要得到绘制范围,但是我们需要获取圆形图片的半径。

完整圆角view的代码奉上,与圆形形成对比,RoundDrawableImageView.java:

package com.beyole.view;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;

public class RoundDrawableImageView extends Drawable {

	private Paint paint;
	private Bitmap mBitmap;
	private RectF rectF;
	private int borderRadius = 30;

	public RoundDrawableImageView(Bitmap bitmap) {
		mBitmap = bitmap;
		BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setShader(shader);
	}

	@Override
	public int getIntrinsicWidth() {
		return mBitmap.getWidth();
	}

	@Override
	public int getIntrinsicHeight() {
		return mBitmap.getHeight();
	}

	@Override
	public void draw(Canvas canvas) {
		canvas.drawRoundRect(rectF, borderRadius, borderRadius, paint);
	}

	@Override
	public void setAlpha(int alpha) {
		paint.setAlpha(alpha);
	}

	@Override
	public void setColorFilter(ColorFilter cf) {
		paint.setColorFilter(cf);
	}

	@Override
	public int getOpacity() {
		return PixelFormat.TRANSLUCENT;
	}

	@Override
	public void setBounds(int left, int top, int right, int bottom) {
		super.setBounds(left, top, right, bottom);
		// 设置绘制范围
		rectF = new RectF(left, top, right, bottom);
	}

	/**
	 * 设置圆角borderRadius
	 * 
	 * @param radius
	 */
	public void setBorderRadius(int radius) {
		this.borderRadius = radius;
	}
}

csdn下载地址: http://download.csdn.net/detail/smarticeberg/9483584
github地址: https://github.com/xuejiawei/beyole_roundimageview 欢迎fork or star

题外话:

android交流群:279031247(广告勿入)

新浪微博:SmartIceberg










你可能感兴趣的:(android自定义view-打造圆形ImageView(三))