近期在仿手Q的UI,这里面常常要用到的就是圆形头像,看到 在android中画圆形图片的几种办法 这篇文章,了解了制作这样的头像的原理.只是里面提供的方法另一个不足的地方就是不能依据实际需求改变图片的大小,也就是说提供的原图是大尺寸的,转换之后的图片也是大尺寸的,这显然不符合我们实际项目中的需求.于是我对里面介绍的第一种方法做了一番改进,使其能直接在XML中指定图片的大小.

大体步骤

  1. 将原图居中裁剪成正方形
  2. 依据指定的宽度对正方形进行缩放
  3. 裁剪成圆形

效果



代码实现

package com.demos.tencent_qq_ui.CustomerView;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView; /**
* Created by mummyding on 15-8-7.
*/
public class AvatarImageView extends ImageView {
private Paint paint = new Paint(); public AvatarImageView(Context context) {
super(context);
} public AvatarImageView(Context context, AttributeSet attrs) {
super(context, attrs);
} public AvatarImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} //将头像按比例缩放
private Bitmap scaleBitmap(Bitmap bitmap){
int width = getWidth();
//一定要强转成float 不然有可能由于精度不够 出现 scale为0 的错误
float scale = (float)width/(float)bitmap.getWidth();
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); }
//将原始图像裁剪成正方形
private Bitmap dealRawBitmap(Bitmap bitmap){
int width = bitmap.getWidth();
int height = bitmap.getHeight();
//获取宽度
int minWidth = width > height ? height:width ;
//计算正方形的范围
int leftTopX = (width - minWidth)/2;
int leftTopY = (height - minWidth)/2;
//裁剪成正方形
Bitmap newBitmap = Bitmap.createBitmap(bitmap,leftTopX,leftTopY,minWidth,minWidth,null,false);
return scaleBitmap(newBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (null != drawable) {
Bitmap rawBitmap =((BitmapDrawable)drawable).getBitmap(); //处理Bitmap 转成正方形
Bitmap newBitmap = dealRawBitmap(rawBitmap);
//将newBitmap 转换成圆形
Bitmap circleBitmap = toRoundCorner(newBitmap, 14); final Rect rect = new Rect(0, 0, circleBitmap.getWidth(), circleBitmap.getHeight());
paint.reset();
//绘制到画布上
canvas.drawBitmap(circleBitmap, rect, rect, paint);
} else {
super.onDraw(canvas);
}
} private Bitmap toRoundCorner(Bitmap bitmap, int pixels) { //指定为 ARGB_4444 能够减小图片大小
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(output); final int color = 0xff424242;
final Rect rect = new Rect(0, 0,bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
int x = bitmap.getWidth();
canvas.drawCircle(x / 2, x / 2, x / 2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}

然后就能够直接像其它View一样直接在XML中使用了.
比如
 <com.demos.tencent_qq_ui.CustomerView.AvatarImageView
android:layout_width="96dip" <!--可自行指定大小-->
android:layout_height="96dip"
android:layout_centerHorizontal="true"
android:src="@drawable/avatar" <!--这里放图片-->
/>

这样,在界面上显示的图像就是圆形的了.

       只是我这里另一个不足的地方是没有检查原图片的大小,假设你放一张高清的图片,那就非常可能crash 掉.对于这点,我眼下的解决方法就是 Google 官方教程里的 Loading
Large Bitmaps Efficiently
   但它的原理就是先不不把图片载入进来,而是先依据原图的大小计算缩放值,然后在依据缩放值读取图片(算是在读取的时候进行压缩吧....).可是这种方法须要提供视图ID,也就是说要给AvatarImageView 指定一个ID,然后一个AvatarImageView 要相应一个视图(我是这么理解的) 这种话AvatarImageView就无法重用了.当项目中多处要用到这个的话就会非常麻烦.
为此我在stackoverflow提了一个问,可是眼下还没有人回答T_T  How
to make bitmap(set in src) compress?

【转载请注明出处】

Author: MummyDing

出处:http://blog.csdn.net/u012560612/article/category/5651761





【Android】自己定义圆形ImageView(圆形头像 可指定大小)的更多相关文章

  1. Android自己定义圆角ImageView 支持网络图片

    先看下效果图 我们再来看一张CSDN的圆角图片 从布局能够看出csdn app 的头像也是圆角的Image,但能够看到.有明显的毛刺感.不知道是csdn 程序猿的疏忽还是 我手机的问题,本人手机(小米 ...

  2. Android自己定义圆角ImageView

    我们常常看到一些app中能够显示圆角图片.比方qq的联系人图标等等,实现圆角图片一种办法是直接使用圆角图片资源,当然假设没有圆角图片资源.我们也能够自己通过程序实现的,以下介绍一个自己定义圆角Imag ...

  3. android 自己定义水平和圆形progressbar 仅仅定义一些style就能够

    效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/diss ...

  4. Android自己定义控件--圆形进度条(中间有图diao)

    智能家居越来越流行,在智能家居中我们常要表现一些数据的百分比 圆形度条中间加个图是一种很流行的自己定义View 1.第一步 你首先须要对类进行继承View public class CirclePro ...

  5. Android自定义ImageView圆形头像

    效果图: 代码如下: RoundImageView.java import cn.comnav.evaluationsystem.R; import android.content.Context; ...

  6. Android ImageView圆形头像

    转载自:http://m.oschina.net/blog/321024 Android ImageView圆形头像 图片完全解析 我们在做项目的时候会用到圆形的图片,比如用户头像,类似QQ.用户在用 ...

  7. 【转】Android ImageView圆形头像

    Android ImageView圆形头像 图片完全解析 我们在做项目的时候会用到圆形的图片,比如用户头像,类似QQ.用户在用QQ更换头像的时候,上传的图片都是矩形的,但显示的时候确是圆形的. 原理: ...

  8. Android 自己定义ImageView实现圆角/圆形 附加OnTouchListener具体凝视以及Button圆角

    转载请注明出处:王亟亟的大牛之路 平时要用一些非方方正正的button之类的小伙伴们是怎样实现的?RadioButton? ImageButton? 还是其它? 今天亟亟上的是ImageView来实现 ...

  9. Android特效专辑(五)——自定义圆形头像和仿MIUI卸载动画—粒子爆炸

    Android特效专辑(五)--自定义圆形头像和仿MIUI卸载动画-粒子爆炸 好的,各位亲爱的朋友,今天讲的特效还是比较炫的,首先,我们会讲一个自定义圆形的imageView,接着,我们会来实现粒子爆 ...

随机推荐

  1. UIPickerView 多级联动

    UIPickerView的多级联动问题有些地方需要注意,其实多级联动并不难...楼主因为项目需要又没法使用网上的第三方,所以最近写了一个省市区多级联动,还是手写代码好!! 为了演示效果,我会多定义几个 ...

  2. [ ZJOI 2010 ] 网络扩容

    \(\\\) Description 给定一张有向图,每条边都有一个容量 \(C\) 和一个扩容费用 \(W\). 这里扩容费用是指将容量扩大 \(1\) 所需的费用.求: 在不扩容的情况下, \(1 ...

  3. poj3411 Paid Roads

    思路: 搜索.注意点和边都有可能经过多次. 实现: #include <iostream> #include <cstdio> #include <vector> ...

  4. WinRT ListView间隔变色(一)

    我们知道,在WPF里,MSDN提供了三种方法 1.使用转换器Converter 2.继承ListView类,自己处理 3.使用StyleSelctor 到了WinRT的世界了 1. Winrt中Set ...

  5. mac下iterm2 设置笔记

    1.利用brew install zsh 来安装oh my zsh 2.chsh -s /bin/zsh,修改~/.zshrc文件 alias cls='clear' alias ll='ls -l' ...

  6. Uploadify上传大文件

    一丶参考地址 <script type="text/javascript"> var auth = "@(Request.Cookies[FormsAuthe ...

  7. block的作用

    ios高效开发--blocks相关   1.替换delegate       如果我们有2个viewController,a和b,当我们从a界面push到b后,在b上面触发了一些事件,这些时间又会影响 ...

  8. 洛谷——P1972 [SDOI2009]HH的项链(线段树)

    P1972 [SDOI2009]HH的项链 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的 ...

  9. 队列的头函数使用C++

    queue queue模板类的定义在<queue>头文件中. 与stack模板类很相似,queue模板类也需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的 ...

  10. springBoot启动及发布

    1.在项目编辑器(IDEA)中启动 运行springBoot项目Application类中main方法,这两个按钮都可以.如下图: 当然还有我们配置的启动按钮,这是最常用的启动方式,不再赘述,如下图: ...