Android圆形图片不求人,自定义View实现(BitmapShader使用)
2017-04-17 14:15
1076 查看
在很多APP当中,圆形的图片是必不可少的元素,美观大方。本文将带领读者去实现一个圆形图片自定View,力求只用一个Java类来完成这件事情。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/b672c5286fb37c52183a76e70642ae55.jpg)
在自定义View的onDraw()里面使用画笔paint结合BitmapShaper画出一个圆形区域。
上述两步已经可以实现一个圆形图片,但是如果图片大于View的设定的宽高,则只会绘制左上角的局域,内容显示不完全(如下图)。因此,还应该做好图片的缩放。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/fb5298e8103724853bf95dd89db80e6d.png)
2. onMeasure()方法里面,计算好宽高
因为是圆形图片,所以应该让宽高保持一致,取测量尺寸宽高中的最小值最为最终结果。
3. onDraw()方法里面画出圆形图片,注意看注释,很详细。
4. 上一步中的将drwable转换为bitmap的方法。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/10fabcdedebdd90deee664cf51cf724a.jpg)
2. 各种效果图,用于验证适应性
尺寸都指定为200dp
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/7e25ecef7547bd1e072a3b95952cf94b.jpg)
尺寸都指定为100dp
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/1353a80a4a05cf51bc7f28db874e1451.jpg)
尺寸都指定不一样,一个150,一个400
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/f214754515f9ca992516105365e1ca53.jpg)
尺寸设定为wrap_content
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/b39113314de16dfdd364e2f8e5994f3a.jpg)
可以使用一些开源框架如Fresco,这个可以参考本人的另一篇博客 Fresco图片框架简介及使用
笨办法,让视觉给到一张圆形图片(如果每张图都需要处理,可能她会打死你)
笨办法,用一个view在上面挡住(这个我写的自己都笑了)
自定义View,就如本文介绍的。
自定义Drawble,这个和自定义view可以相互补充。
总之,通过以上各个不同属性验证,可以发现本文的自定义View完美的实现了圆形图片。如果读者有需要圆形图的,可以把这个copy一下自己用,就一个类,简单精巧。
如果觉得本文对你有帮助,请关注、留言、点赞我,谢谢!
来自:http://www.jianshu.com/p/6b5eef0f6f3d
一、先上效果图
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/b672c5286fb37c52183a76e70642ae55.jpg)
二、实现思路
在定义View 的onMeasure()方法里设置View的宽高相等,应该取宽高中的最小值。在自定义View的onDraw()里面使用画笔paint结合BitmapShaper画出一个圆形区域。
上述两步已经可以实现一个圆形图片,但是如果图片大于View的设定的宽高,则只会绘制左上角的局域,内容显示不完全(如下图)。因此,还应该做好图片的缩放。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/fb5298e8103724853bf95dd89db80e6d.png)
三、具体实现
1.新建一个java类 CircleImageView继承 ImageView,这个是完整的代码。public class CircleImageView extends ImageView { private Paint mPaint; //画笔 private int mRadius; //圆形图片的半径 private float mScale; //图片的缩放比例 public CircleImageView(Context context) { super(context); } public CircleImageView(Context context, AttributeSet attrs) { super(context, attrs); } public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //因为是圆形图片,所以应该让宽高保持一致 int size = Math.min(getMeasuredWidth(), getMeasuredHeight()); mRadius = size / 2; setMeasuredDimension(size, size); } @Override protected void onDraw(Canvas canvas) { mPaint = new Paint(); Bitmap bitmap = drawableToBitmap(getDrawable()); //初始化BitmapShader,传入bitmap对象 BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //计算缩放比例 mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth()); Matrix matrix = new Matrix(); matrix.setScale(mScale, mScale); bitmapShader.setLocalMatrix(matrix); mPaint.setShader(bitmapShader); //画圆形,指定好中心点坐标、半径、画笔 canvas.drawCircle(mRadius, mRadius, mRadius, mPaint); } //写一个drawble转BitMap的方法 private Bitmap drawableToBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; } }
2. onMeasure()方法里面,计算好宽高
因为是圆形图片,所以应该让宽高保持一致,取测量尺寸宽高中的最小值最为最终结果。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //因为是圆形图片,所以应该让宽高保持一致 int size = Math.min(getMeasuredWidth(), getMeasuredHeight()); mRadius = size / 2; setMeasuredDimension(size, size); }
3. onDraw()方法里面画出圆形图片,注意看注释,很详细。
@Override protected void onDraw(Canvas canvas) { mPaint = new Paint(); Bitmap bitmap = drawableToBitmap(getDrawable()); //初始化BitmapShader,传入bitmap对象 BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //计算缩放比例 mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth()); Matrix matrix = new Matrix(); matrix.setScale(mScale, mScale); bitmapShader.setLocalMatrix(matrix); mPaint.setShader(bitmapShader); //画圆形,指定好中心点坐标、半径、画笔 canvas.drawCircle(mRadius, mRadius, mRadius, mPaint); }
4. 上一步中的将drwable转换为bitmap的方法。
//写一个drawble转BitMap的方法 private Bitmap drawableToBitmap(Drawable drawable) { if (drawable instanceof BitmapDrawable) { BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; }
四、使用该自定义View
1. 布局文件里面使用,此处使用了斯嘉丽的美图![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/10fabcdedebdd90deee664cf51cf724a.jpg)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.roundimage.MainActivity" > <com.roundimage.CircleImageView android:id="@+id/image1" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:scaleType="centerCrop" android:src="@drawable/beauty" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/image1" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:text="斯嘉丽·约翰逊" android:textColor="#333333" android:textSize="17sp" /> </RelativeLayout>
2. 各种效果图,用于验证适应性
尺寸都指定为200dp
android:layout_width="200dp" android:layout_height="200dp"
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/7e25ecef7547bd1e072a3b95952cf94b.jpg)
尺寸都指定为100dp
android:layout_width="100dp" android:layout_height="100dp"
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/1353a80a4a05cf51bc7f28db874e1451.jpg)
尺寸都指定不一样,一个150,一个400
android:layout_width="100dp" android:layout_height="200dp"
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/f214754515f9ca992516105365e1ca53.jpg)
尺寸设定为wrap_content
android:layout_width="wrap_content" android:layout_height="wrap_content"
![](https://oscdn.geek-share.com/Uploads/Images/Content/201704/b39113314de16dfdd364e2f8e5994f3a.jpg)
五、总结
实现圆形图片有很多种方法:可以使用一些开源框架如Fresco,这个可以参考本人的另一篇博客 Fresco图片框架简介及使用
笨办法,让视觉给到一张圆形图片(如果每张图都需要处理,可能她会打死你)
笨办法,用一个view在上面挡住(这个我写的自己都笑了)
自定义View,就如本文介绍的。
自定义Drawble,这个和自定义view可以相互补充。
总之,通过以上各个不同属性验证,可以发现本文的自定义View完美的实现了圆形图片。如果读者有需要圆形图的,可以把这个copy一下自己用,就一个类,简单精巧。
如果觉得本文对你有帮助,请关注、留言、点赞我,谢谢!
来自:http://www.jianshu.com/p/6b5eef0f6f3d
相关文章推荐
- Android圆形图片不求人,自定义View实现(BitmapShader使用)
- Android圆形图片不求人,自定义View实现(BitmapShader使用)
- Android圆形图片不求人,自定义View实现(BitmapShader使用)
- Android 自定义View修炼-Android实现圆形、圆角和椭圆自定义图片View(使用BitmapShader图形渲染方法)
- Android使用BitmapShader图形渲染实现圆形、圆角和椭圆自定义图片View
- Android自定义view实现圆形、圆角和椭圆图片(BitmapShader图形渲染)
- Android 自定义View 使用ShapeDrawable加BitmapShader实现图片局部放大效果
- Android BitmapShader 实战 实现圆形、圆角图片(重写ImageView)
- 自定义View—使用clipPath或者BitmapShader实现圆角图片
- Android自定义View【实战教程】4⃣️----BitmapShader详解及圆形、圆角、多边形实现
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader实现圆形和圆角图片
- 【转】Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片
- 使用BitmapShader实现图片的圆形、圆角
- Android BitmapShader 实战 实现圆形、圆角图片
- Android BitmapShader 实战 实现圆形、圆角图片