package com.fanxin.easeui.widget;
import android.content.Context;
import android.content.res.TypedArray;
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.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;
import com.hyphenate.easeui.R;
/**
* Created by lzan13 on 2015/4/30.
* customized ImageView,Rounded Rectangle and border is implemented, and change color when you press
*/
public class EaseImageView extends ImageView {
// paint when user press
private Paint pressPaint;
private int width;
private int height;
// default bitmap config
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private static final int COLORDRAWABLE_DIMENSION = 1;
// border color
private int borderColor;
// width of border
private int borderWidth;
// alpha when pressed
private int pressAlpha;
// color when pressed
private int pressColor;
// radius
private int radius;
// rectangle or round, 1 is circle, 2 is rectangle
private int shapeType;
public EaseImageView(Context context) {
super(context);
init(context, null);
}
public EaseImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public EaseImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
//init the value
borderWidth = 0;
borderColor = 0xddffffff;
pressAlpha = 0x42;
pressColor = 0x42000000;
radius = 16;
shapeType = 0;
// get attribute of EaseImageView
if (attrs != null) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.EaseImageView);
borderColor = array.getColor(R.styleable.EaseImageView_ease_border_color, borderColor);
borderWidth = array.getDimensionPixelOffset(R.styleable.EaseImageView_ease_border_width, borderWidth);
pressAlpha = array.getInteger(R.styleable.EaseImageView_ease_press_alpha, pressAlpha);
pressColor = array.getColor(R.styleable.EaseImageView_ease_press_color, pressColor);
radius = array.getDimensionPixelOffset(R.styleable.EaseImageView_ease_radius, radius);
shapeType = array.getInteger(R.styleable.EaseImageView_ease_shape_type, shapeType);
array.recycle();
}
// set paint when pressed
pressPaint = new Paint();
pressPaint.setAntiAlias(true);
pressPaint.setStyle(Paint.Style.FILL);
pressPaint.setColor(pressColor);
pressPaint.setAlpha(0);
pressPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
setClickable(true);
setDrawingCacheEnabled(true);
setWillNotDraw(false);
}
@Override
protected void onDraw(Canvas canvas) {
if (shapeType == 0) {
super.onDraw(canvas);
return;
}
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
// the width and height is in xml file
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap bitmap = getBitmapFromDrawable(drawable);
drawDrawable(canvas, bitmap);
drawPress(canvas);
drawBorder(canvas);
}
/**
* draw Rounded Rectangle
*
* @param canvas
* @param bitmap
*/
private void drawDrawable(Canvas canvas, Bitmap bitmap) {
Paint paint = new Paint();
paint.setColor(0xffffffff);
paint.setAntiAlias(true); //smooths out the edges of what is being drawn
PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
// set flags
int saveFlags = Canvas.MATRIX_SAVE_FLAG
| Canvas.CLIP_SAVE_FLAG
| Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
| Canvas.FULL_COLOR_LAYER_SAVE_FLAG
| Canvas.CLIP_TO_LAYER_SAVE_FLAG;
canvas.saveLayer(0, 0, width, height, null, saveFlags);
if (shapeType == 1) {
canvas.drawCircle(width / 2, height / 2, width / 2 - 1, paint);
} else if (shapeType == 2) {
RectF rectf = new RectF(1, 1, getWidth() - 1, getHeight() - 1);
canvas.drawRoundRect(rectf, radius + 1, radius + 1, paint);
}
paint.setXfermode(xfermode);
float scaleWidth = ((float) getWidth()) / bitmap.getWidth();
float scaleHeight = ((float) getHeight()) / bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
//bitmap scale
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.restore();
}
/**
* draw the effect when pressed
*
* @param canvas
*/
private void drawPress(Canvas canvas) {
// check is rectangle or circle
if (shapeType == 1) {
canvas.drawCircle(width / 2, height / 2, width / 2 - 1, pressPaint);
} else if (shapeType == 2) {
RectF rectF = new RectF(1, 1, width - 1, height - 1);
canvas.drawRoundRect(rectF, radius + 1, radius + 1, pressPaint);
}
}
/**
* draw customized border
*
* @param canvas
*/
private void drawBorder(Canvas canvas) {
if (borderWidth > 0) {
Paint paint = new Paint();
paint.setStrokeWidth(borderWidth);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(borderColor);
paint.setAntiAlias(true);
// // check is rectangle or circle
if (shapeType == 1) {
canvas.drawCircle(width / 2, height / 2, (width - borderWidth) / 2, paint);
} else if (shapeType == 2) {
RectF rectf = new RectF(borderWidth / 2, borderWidth / 2, getWidth() - borderWidth / 2,
getHeight() - borderWidth / 2);
canvas.drawRoundRect(rectf, radius, radius, paint);
}
}
}
/**
* monitor the size change
*
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
}
/**
* monitor if touched
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
pressPaint.setAlpha(pressAlpha);
invalidate();
break;
case MotionEvent.ACTION_UP:
pressPaint.setAlpha(0);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
break;
default:
pressPaint.setAlpha(0);
invalidate();
break;
}
return super.onTouchEvent(event);
}
/**
*
* @param drawable
* @return
*/
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap;
int width = Math.max(drawable.getIntrinsicWidth(), 2);
int height = Math.max(drawable.getIntrinsicHeight(), 2);
try {
bitmap = Bitmap.createBitmap(width, height, BITMAP_CONFIG);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
} catch (IllegalArgumentException e) {
e.printStackTrace();
bitmap = null;
}
return bitmap;
}
/**
* set border color
*
* @param borderColor
*/
public void setBorderColor(int borderColor) {
this.borderColor = borderColor;
invalidate();
}
/**
* set border width
*
* @param borderWidth
*/
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
}
/**
* set alpha when pressed
*
* @param pressAlpha
*/
public void setPressAlpha(int pressAlpha) {
this.pressAlpha = pressAlpha;
}
/**
* set color when pressed
*
* @param pressColor
*/
public void setPressColor(int pressColor) {
this.pressColor = pressColor;
}
/**
* set radius
*
* @param radius
*/
public void setRadius(int radius) {
this.radius = radius;
invalidate();
}
/**
* set shape
*
* @param shapeType
*/
public void setShapeType(int shapeType) {
this.shapeType = shapeType;
invalidate();
}
}