您的位置:首页 > 其它

自定义圆形头像CircleImageView

2016-05-16 15:24 615 查看
  圆形头像很常用功能,于是想自己写个自定义的圆形的view。搜索了一下,android中可以通过BitmapShader实现这个效果。



  BitmapShader是Shader的子类,可以通过Paint.setShader(Shader shader)进行设置、

  这里我们只关注BitmapShader,构造方法:

  bitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);

  参数1:bitmap

  参数2,参数3:TileMode;

  TileMode的取值有三种:

  CLAMP 拉伸

  REPEAT 重复

  MIRROR 镜像

  如果大家给电脑屏幕设置屏保的时候,如果图片太小,可以选择重复、拉伸、镜像;

  重复:就是横向、纵向不断重复这个bitmap

  镜像:横向不断翻转重复,纵向不断翻转重复;

  拉伸:这个和电脑屏保的模式应该有些不同,这个拉伸的是图片最后的那一个像素;横向的最后一个横行像素,不断的重复,纵项的那一列像素,不断的重复;

首先现在values下新建attrs.xml,自定义属性。

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleImageView">
<attr name="mborder_color" format="color"></attr>
<attr name="mborder_width" format="dimension"></attr>
<attr name="msrc" format="reference"></attr>
</declare-styleable>
</resources>


CircleImageView.java

package com.sy.callme.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

import com.sy.callme.R;

/**
* Created by SY on 2016/5/16.
*/
public class CircleImageView extends View {
private Bitmap bitmap;
private int borderWidth;
private Drawable drawable;
private int borderColor;
private int width;
private int height;
private Bitmap src;
private BitmapShader shader;
private Paint paint;
private int radius;
private int circleX;
private int circleY;
private Paint borderPaint;

public CircleImageView(Context context) {
super(context);
}

public CircleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取自定义属性
TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView);
borderColor = type.getColor(R.styleable.CircleImageView_mborder_color, 0);
borderWidth = type.getDimensionPixelSize(R.styleable.CircleImageView_mborder_width, 2);
drawable = type.getDrawable(R.styleable.CircleImageView_msrc);
//转换为bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
bitmap = bitmapDrawable.getBitmap();

}

private int measureHeight(int heightMeasureSpec) {
int size = MeasureSpec.getSize(heightMeasureSpec);
int sizeMode = MeasureSpec.getMode(heightMeasureSpec);
int result = 0;
if (sizeMode == MeasureSpec.EXACTLY) {
//如果是精确尺寸就直接返回结果
result = size;
} else {
//不是就尺寸设置最大为200
result = 200;
if (sizeMode == MeasureSpec.AT_MOST) {
//如果是最大尺寸就返回实际尺寸和最大尺寸之中较小的
result = Math.min(result, size);
}
}
return result;
}

private int measureWidth(int widthMeasureSpec) {
int size = MeasureSpec.getSize(widthMeasureSpec);
int sizeMode = MeasureSpec.getMode(widthMeasureSpec);
int result = 0;
if (sizeMode == MeasureSpec.EXACTLY) {
//如果是精确尺寸就直接返回结果
result = size;
} else {
//如果是精确尺寸就直接返回结果
result = 200;
if (sizeMode == MeasureSpec.AT_MOST) {
//如果是最大尺寸就返回实际尺寸和最大尺寸之中较小的
result = Math.min(result, size);
}
}
return result;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = measureWidth(widthMeasureSpec);
height = measureHeight(heightMeasureSpec);
width = height = Math.min(width, height);
initView();//初始化画笔参数
setMeasuredDimension(width, height);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(circleX, circleY, radius, paint);
canvas.drawCircle(circleX, circleY, radius, borderPaint);
}

private void initView() {

src = Bitmap.createScaledBitmap(bitmap, width, height, true);
shader = new BitmapShader(src, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint = new Paint();
paint.setShader(shader);//设置shader
radius = (width - borderWidth * 2) / 2;
circleX = (width) / 2;
circleY = (height) / 2;

borderPaint = new Paint();
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderWidth);
borderPaint.setColor(borderColor);
borderPaint.setStrokeJoin(Paint.Join.ROUND);//接合处的圆滑
borderPaint.setStrokeCap(Paint.Cap.ROUND);//圆角的笔触
}

public void setImageResoure(Drawable drawable) {
//转换为bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
bitmap = bitmapDrawable.getBitmap();
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint = new Paint();
paint.setShader(shader);
requestLayout();
invalidate();
}
}


  首先获取自定义属性的值,然后在onMeasure方法里获得控件宽高,initView方法里设置画笔的参数,创建BitmapShader并给paint设置shader。最后在onDraw方法里绘制就可以了。具体使用:

  

<com.sy.callme.view.CircleImageView
android:id="@+id/c_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="20dp"
android:layout_gravity="center_horizontal"
app:mborder_color="#ff7700"
app:mborder_width="3dp"
app:msrc="@mipmap/touxiang" />


记得使用自定义view的自定义属性需要在布局文件中引入
xmlns:app="http://schemas.android.com/apk/res-auto"


参考资料:Android自定义属性时TypedArray的使用方法

     Android学习笔记进阶15之Shader渲染

      Android学习笔记进阶16之BitmapShader

      详解Paint的各种set方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: