Android自定义ImageView圆形头像
效果图:
代码如下:
RoundImageView.java
import cn.comnav.evaluationsystem.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* 圆形ImageView,可设置最多两个宽度不同且颜色不同的圆形边框。
* 设置颜色在xml布局文件中由自定义属性配置参数指定
* @author Administrator
*
*/
public class RoundImageView extends ImageView{
private int mBorderThickness = 0;
private Context mContext;
private int defaultColor = 0xFFFFFFFF;
// 如果只有其中一个有值,则只画一个圆形边框
private int mBorderOutsideColor = 0;
private int mBorderInsideColor = 0;
// 控件默认长、宽
private int defaultWidth = 0;
private int defaultHeight = 0;
public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
setCustomAttributes(attrs);
}
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setCustomAttributes(attrs);
}
public RoundImageView(Context context) {
super(context);
mContext = context;
}
private void setCustomAttributes(AttributeSet attrs) {
TypedArray a = mContext.obtainStyledAttributes(attrs,R.styleable.roundedimageview);
mBorderThickness = a.getDimensionPixelSize(R.styleable.roundedimageview_border_thickness, 0);
mBorderOutsideColor = a.getColor(R.styleable.roundedimageview_border_outside_color,defaultColor);
mBorderInsideColor = a.getColor(R.styleable.roundedimageview_border_inside_color, defaultColor);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable() ;
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
this.measure(0, 0);
if (drawable.getClass() == NinePatchDrawable.class)
return;
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
if (defaultWidth == 0) {
defaultWidth = getWidth();
}
if (defaultHeight == 0) {
defaultHeight = getHeight();
}
int radius = 0;
if (mBorderInsideColor != defaultColor && mBorderOutsideColor != defaultColor) {// 定义画两个边框,分别为外圆边框和内圆边框
radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - 2 * mBorderThickness;
// 画内圆
drawCircleBorder(canvas, radius + mBorderThickness / 2,mBorderInsideColor);
// 画外圆
drawCircleBorder(canvas, radius + mBorderThickness + mBorderThickness / 2, mBorderOutsideColor);
} else if (mBorderInsideColor != defaultColor && mBorderOutsideColor == defaultColor) {// 定义画一个边框
radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - mBorderThickness;
drawCircleBorder(canvas, radius + mBorderThickness / 2, mBorderInsideColor);
} else if (mBorderInsideColor == defaultColor && mBorderOutsideColor != defaultColor) {// 定义画一个边框
radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - mBorderThickness;
drawCircleBorder(canvas, radius + mBorderThickness / 2, mBorderOutsideColor);
} else {// 没有边框
radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2;
}
Bitmap roundBitmap = getCroppedRoundBitmap(bitmap, radius);
canvas.drawBitmap(roundBitmap, defaultWidth / 2 - radius, defaultHeight / 2 - radius, null);
}
/**
* 获取裁剪后的圆形图片
* @param radius半径
*/
public Bitmap getCroppedRoundBitmap(Bitmap bmp, int radius) {
Bitmap scaledSrcBmp;
int diameter = radius * 2;
// 为了防止宽高不相等,造成圆形图片变形,因此截取长方形中处于中间位置最大的正方形图片
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
int squareWidth = 0, squareHeight = 0;
int x = 0, y = 0;
Bitmap squareBitmap;
if (bmpHeight > bmpWidth) {// 高大于宽
squareWidth = squareHeight = bmpWidth;
x = 0;
y = (bmpHeight - bmpWidth) / 2;
// 截取正方形图片
squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight);
} else if (bmpHeight < bmpWidth) {// 宽大于高
squareWidth = squareHeight = bmpHeight;
x = (bmpWidth - bmpHeight) / 2;
y = 0;
squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth,squareHeight);
} else {
squareBitmap = bmp;
}
if (squareBitmap.getWidth() != diameter || squareBitmap.getHeight() != diameter) {
scaledSrcBmp = Bitmap.createScaledBitmap(squareBitmap, diameter,diameter, true);
} else {
scaledSrcBmp = squareBitmap;
}
Bitmap output = Bitmap.createBitmap(scaledSrcBmp.getWidth(),
scaledSrcBmp.getHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
Rect rect = new Rect(0, 0, scaledSrcBmp.getWidth(),scaledSrcBmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(scaledSrcBmp.getWidth() / 2,
scaledSrcBmp.getHeight() / 2,
scaledSrcBmp.getWidth() / 2,
paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(scaledSrcBmp, rect, rect, paint);
bmp = null;
squareBitmap = null;
scaledSrcBmp = null;
return output;
}
/**
* 边缘画圆
*/
private void drawCircleBorder(Canvas canvas, int radius, int color) {
Paint paint = new Paint();
/* 去锯齿 */
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
paint.setColor(color);
/* 设置paint的 style 为STROKE:空心 */
paint.setStyle(Paint.Style.STROKE);
/* 设置paint的外框宽度 */
paint.setStrokeWidth(mBorderThickness);
canvas.drawCircle(defaultWidth / 2, defaultHeight / 2, radius, paint);
}
}
1、定义自己的属性配置文件:attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="roundedimageview">
<attr name="border_thickness" format="dimension" />
<attr name="border_inside_color" format="color" />
<attr name="border_outside_color" format="color"></attr>
</declare-styleable>
</resources>
2、在xml配置中使用控件:activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:imagecontrol="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
>
<!-- 没有指定圆形ImageView属性时,默认没有外边圆颜色 -->
<!-- 需要将图片资源自定为src ,或在程序中setImageResource(res) 不能设置background为图片,这样不能达到圆形效果-->
<com.dxd.roundimageview.RoundImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/img"
/>
<!-- border_outside_color 外部圆圈的颜色 -->
<!-- border_inside_color 内部部圆圈的颜色 -->
<!-- border_thickness 外圆和内圆的宽度 -->
<com.dxd.roundimageview.RoundImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/img"
imagecontrol:border_inside_color="#bc0978"
imagecontrol:border_outside_color="#ba3456"
imagecontrol:border_thickness="1dp"
/>
</LinearLayout>
3、主Activity中没有相关代码,直接加载布局文件即可。
Android自定义ImageView圆形头像的更多相关文章
- Android -- 自定义ImageView(圆形头像)
1. 原图
- Android ImageView圆形头像
转载自:http://m.oschina.net/blog/321024 Android ImageView圆形头像 图片完全解析 我们在做项目的时候会用到圆形的图片,比如用户头像,类似QQ.用户在用 ...
- 【转】Android ImageView圆形头像
Android ImageView圆形头像 图片完全解析 我们在做项目的时候会用到圆形的图片,比如用户头像,类似QQ.用户在用QQ更换头像的时候,上传的图片都是矩形的,但显示的时候确是圆形的. 原理: ...
- Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示
Android中的ImageView只能显示矩形的图片,为了用户体验更多,Android实现圆角矩形,圆形或者椭圆等图形,一般通过自定义ImageView来实现,首先获取到图片的Bitmap,然后通过 ...
- 【Android】自己定义圆形ImageView(圆形头像 可指定大小)
近期在仿手Q的UI,这里面常常要用到的就是圆形头像,看到 在android中画圆形图片的几种办法 这篇文章,了解了制作这样的头像的原理.只是里面提供的方法另一个不足的地方就是不能依据实际需求改变图片的 ...
- Android 自定义 View 圆形进度条总结
Android 自定义圆形进度条总结 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 微信公众号:牙锅子 源码:CircleProgress 文中如有纰漏,欢迎大家留言指出. 最近 ...
- Android 自定义ImageView支持缩放,拖拽,方便复用
今天刚发了一篇关于ImageView的缩放和拖拽的博客,然后我想了下,将他自定义下,方便我们来复用这个imageView,效果我就不多说了,http://blog.csdn.net/xiaanming ...
- Android 自定义view --圆形百分比(进度条)
转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50334595 注:本文由于是在学习过程中写的,存在大量问题(overdraw onDr ...
- android 自定义图片圆形进度条
感觉话一个圆形进度条挺简单的 ,但是却偏偏给了几张图片让你话,说实话我没接触过,感觉好难,还好百度有大把的资源,一番努力下终于画出来了. 代码如下. package com.etong.cpms.wi ...
随机推荐
- chrome 问题
1.chrome表单自动填充去掉input黄色背景解决方案 http://blog.csdn.net/wangxiaohui6687/article/details/10149579 2.chrome ...
- Jquery的multifile使用随记
1.多文件上传: 2.如上几个验证不重复,和限制上传数量的验证显示的是英文,改成中文文本时,如果不用国标解码,到时候提示框会出现乱码现象.所以一般需要中文显示的时候,我们应该这样做: 拿denied做 ...
- 初步了解yield_python
yield 关键字是在学习python生成器(Generator)时遇到的,对于它及Generator至今我还不能很深入的理解,当前只是把所理解的知识作下记录,以便以后翻查. yield关键字是用来定 ...
- android数据库SQLite的设计模式
Dao设计模式可能是使用最多的数据库的设计模式其基本思路是将数据库操作的代码 与设计代码分离以便于维护和升级.具体的实现方法是使用包,然后在设计代码中调 用数据库的操作代码,dao设计模式需要创建5个 ...
- Xamarin开发Android笔记:拍照或相册选取图片角度问题
在开发Android应用的时候,可能会遇到类似微信朋友圈中拍照或相册选取图片的场景,拍照或选取图片之后在显示的时候却发现图片的角度不对,明明是竖版拍照,显示出来缺失躺着的. 这是因为在某些特定手机上例 ...
- mongodb(Index)
备忘mongoDb 索引的一些知识点. 1.索引是用以加速数据库查询的手段,在mongo中主要是采用B树的方式: 2.每个集合最多可增加64个索引,不建议增加过多索引,原因在于一是索引本身占用空间,二 ...
- 人人都是 DBA(V)SQL Server 数据库文件
SQL Server 数据库安装后会包含 4 个默认系统数据库:master, model, msdb, tempdb. SELECT [name] ,database_id ,suser_sname ...
- TypeError: 'bases' is null or not an object。IE8 bug 腐朽的对象
使用Webapp Builder时候发现,在IE8上很奇怪的一个现象:在ajax回调函数中引用一个闭包作用域链中的对象作为某一个Dijit的实例化参数时有问题:bases is null or not ...
- 区分各浏览器的CSS hack(包括360、搜狗、opera)
虽然说使用css hack来解决页面兼容性bug并不是个好办法,但是有时候这些hack还是用的着的,比如你接受了一个二手或是三手的遗留界面,杂乱无章的css代码,只在某个浏览器下有兼容bug,而且需要 ...
- 翻译-高效DevOps的10项实践
原文链接: http://www.drdobbs.com/architecture-and-design/top-10-practices-for-effective-devops/240149363 ...