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

这篇博客是关于如何使用drawable和BitmapShader在Android中创建圆形ImageView的教程。作者介绍了通过继承drawable来简化自定义view的过程,避免了onMeasure的复杂性。文章包括步骤说明,并提供了相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

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

效果图:


正文:

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

github地址: https://github.com/xuejiawei/beyole_roundimageview 欢迎fork or star

题外话:

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

新浪微博:SmartIceberg










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值