前言:
时隔了一个星期,由于毕业论文的事情一直耽搁了写博客,今天有了点空闲时间把上次的圆形图片继续讲完。前面两篇分别用了BitmapShader和Xfermode方式实现了圆形圆角图片,详情请戳android自定义view-打造圆形ImageView(一)、android自定义view-打造圆形ImageView(二)。好,今天我们用比较简单的drawable加上BitmapShader方式去实现,这样做的好处就是省略了自定义view的onMeasure的过程,看起来挺简洁的。
效果图:
正文:
Step1:继承自drawable
public class RoundDrawableImageView extends DrawableStep2:在构造方法中初始化画笔等属性:
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; } }
题外话:
android交流群:279031247(广告勿入)
新浪微博:SmartIceberg