您的位置:首页 > 移动开发 > Android开发

精简版BitmapShader实现圆形头像和圆角方形头像

2017-07-21 16:27 447 查看

一种简单明了的圆形头像实现方式



import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapShader;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.Shader;

import android.graphics.drawable.BitmapDrawable;

import android.util.AttributeSet;

import android.widget.ImageView;

public class MyCircleView extends ImageView {

private Paint paint = new Paint(); // 图片画笔
private Paint paint2 = new Paint(); // 边框画笔
Matrix mShaderMatrix = new Matrix();
private Bitmap mBitmap;
private BitmapShader bs;
private int bitmapheight;
private int bitmapwidth;
private float rudius; // 圆形图片半径
private int borderWidth = 0; // 边框宽度
private int borderColor = Color.RED; // 边框颜色

public MyCircleView (Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);

update();
}

@Override
public void setImageResource(int resId) {
// TODO Auto-generated method stub
super.setImageResource(resId);
update();
}

@Override
public void setImageBitmap(Bitmap bm) {
// TODO Auto-generated method stub
super.setImageBitmap(bm);
update();
}

/**
* @param borderWidth
*/
public void setBorderWidth(int borderWidth){
this.borderWidth = borderWidth;
update();
}

/**
* @param borderColor
*/
public void setBorderColor(int borderColor){
this.borderColor = borderColor;
update();
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
// super.onDraw(canvas);

canvas.drawCircle(getWidth()/2, getHeight()/2, rudius, paint);
if (borderWidth != 0) {
canvas.drawCircle(getWidth()/2, getHeight()/2, rudius-(borderWidth/2), paint2);
}
}

private void update() {
// TODO Auto-generated method stub
if (null == getDrawable()) {
return;
}
BitmapDrawable bd = (BitmapDrawable) getDrawable();
mBitmap = bd.getBitmap();

bs = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setShader(bs);

paint2.setStyle(Paint.Style.STROKE);
paint2.setAntiAlias(true);
paint2.setDither(true);
paint2.setColor(borderColor);
paint2.setStrokeWidth(borderWidth);

bitmapwidth = mBitmap.getWidth();
bitmapheight = mBitmap.getHeight();

rudius = Math.min(getWidth()/2, getHeight()/2);

setShaderMatrix();
invalidate();
}

private void setShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;

mShaderMatrix.set(null);

// 根据View和图片的宽高比对图片进行缩小或放大
if (bitmapwidth * getHeight() > getWidth() * bitmapheight) {
scale = getHeight() / (float) bitmapheight;
dx = (getWidth() - bitmapwidth * scale) * 0.5f;
} else {
scale = getWidth() / (float) bitmapwidth;
dy = (getHeight() - bitmapheight * scale) * 0.5f;
}

mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate(dx,dy);

bs.setLocalMatrix(mShaderMatrix);
}


}

初始化完View后直接设置属性就可以了

MyCircleView circle_img = (MyCircleView ) findViewById(R.id.circle_img);
circle_img.setImageResource(R.drawable.b);
circle_img.setBorderWidth(14);
circle_img.setBorderColor(Color.BLUE);


也可以更改onDraw方法,画出圆角方形图片,

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub
//  super.onDraw(canvas);

// 设置矩形各边位置
float l = 0;
float t = 0;
float r = 0;
float b = 0;
// 设置圆角半径
float rx = 0;
float ry = 0;

// 判断是长图还是宽图,来设置矩形四个边的位置
if (getHeight() > getWidth()) {
t = (getHeight()-getWidth())/2;
r = getWidth();
b = (getHeight()+getWidth())/2;

} else {
l = (getWidth()-getHeight())/2;
t = 0;
r = (getWidth()+getHeight())/2;
b = getWidth();
}
// 找出一个最小边,设置圆角半径为该边的1/6。
rx = ry = Math.min(getWidth(), getHeight())/6;

RectF rect = new RectF(l, t, r, b);
canvas.drawRoundRect(rect, rx, ry, paint);
if (borderWidth != 0) {
// 画边框时,应减去边框的宽度,
RectF rect2 = new RectF((borderWidth/2)+l, t+(borderWidth/2), r-(borderWidth/2), b-(borderWidth/2));
canvas.drawRoundRect(rect2, rx-(borderWidth/2), ry-(borderWidth/2), paint2);
}


}



也可以根据需求画出椭圆、三角形等其他形状

如果要自定义xml属性要先写一个attr文件,定义属性

<resources>
<declare-styleable name="MyView">
<attr name="borderWidth" format="dimension"/>
<attr name="borderColor" format="color"/>

</declare-styleable>

</resources>


**不要忘记在xml布局文件中加上

xmlns:mystyle=”http://schemas.android.com/apk/res/com.example.xxxxxx”**

其中mystyle是自己定义名字(随便起名字),com.example.xxxxxx是自己项目的包名

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:mystyle="http://schemas.android.com/apk/res/com.example.xxxxxx"
android:layout_width="match_parent"
android:layout_height="match_parent"

<com.example.xxxxxx.MyCircleView
android:id="@+id/circle_img2"
android:layout_width="200dp"
android:layout_height="200dp"

mystyle:borderColor="@android:color/holo_red_light"
mystyle:borderWidth="12dp"

...省略

</RelativeLayout>


重写的构造方法,获取xml中的参数

public MyCircleView (Context context) {
this(context, null);
// TODO Auto-generated constructor stub
}

public MyCircleView (Context context, AttributeSet attrs) {
this(context, attrs, 0);
// TODO Auto-generated constructor stub
}

public MyCircleView (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
TypedArray ob = context.obtainStyledAttributes(attrs, R.styleable.MyView, defStyle, 0);

// getDimension 和 getColor的第二个参数都是给的默认值
float borderWidth = ob.getDimension(R.styleable.MyView_borderWidth, 6);
int borderColor = ob.getColor(R.styleable.MyView_borderColor, Color.BLUE);

// 把获取到的值赋值给变量
this.borderWidth = borderWidth;
this.borderColor = borderColor;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BitmapShad android