/**
* 扩展的{@link ImageView}, 增加了多种点击效果.
* 效果请参照{@link ButtonEffect}
*
*/
public class UIImageButton extends ImageView {
private static final int EFFECT_NONE = 0;
/** 光照效果 **/
private static final int EFFECT_SUN = 1;
/** 变暗效果 **/
private static final int EFFECT_DARKEN = 2;
/** 描边效果 **/
private static final int EFFECT_RIM = 3;
/** 水印效果 **/
private static final int EFFECT_WATERMARK = 4;
/** 效果 **/
// private int mEffect = EFFECT_SUN;
private ButtonEffect mEffect = ButtonEffect.SUNSHINE;
/** 是否开启效果 **/
private boolean fEffect = false;
/** 水印 **/
private Drawable mWatermark;
/** 默认画笔 **/
private Paint mPaint;
/** 效果集, 效果不可进行叠加 **/
public enum ButtonEffect {
/** 无效果,设置该属性后,使用时请参照{@link ImageView} **/
NONE(EFFECT_NONE),
/** 该属性会产生光照的效果 **/
SUNSHINE(EFFECT_SUN),
/** 该属性会产生变暗的效果 **/
DARKEN(EFFECT_DARKEN),
/** 该属性会产生描边的效果 **/
RIM(EFFECT_RIM),
/** 该属性为水印效果,设置该属性还需要同时设置水印来源{@link #mWatermark} **/
WATERMARK(EFFECT_WATERMARK);
private ButtonEffect(int nativeInt) {
this.nativeInt = nativeInt;
}
final int nativeInt;
}
public UIImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.UIImageButton, defStyle, 0);
if (a != null) {
mWatermark = a
.getDrawable(R.styleable.UIImageButton_ui_image_button_mark_src);
final int effect = a.getInteger(
R.styleable.UIImageButton_ui_image_button_type,
ButtonEffect.NONE.nativeInt);
if (effect == ButtonEffect.NONE.nativeInt) {
mEffect = ButtonEffect.NONE;
} else if (effect == ButtonEffect.SUNSHINE.nativeInt) {
mEffect = ButtonEffect.SUNSHINE;
} else if (effect == ButtonEffect.DARKEN.nativeInt) {
mEffect = ButtonEffect.DARKEN;
} else if (effect == ButtonEffect.RIM.nativeInt) {
mEffect = ButtonEffect.RIM;
} else if (effect == ButtonEffect.WATERMARK.nativeInt) {
mEffect = ButtonEffect.WATERMARK;
}
a.recycle();
}
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
// boolean reset = true;
//
// for(int i : getDrawableState()){
// if(i == android.R.attr.state_pressed){
// reset = false;
// break;
// }
// }
//
// if(reset){
// invalidEffect();
// invalidate();
// }
}
public UIImageButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public UIImageButton(Context context) {
this(context, null);
}
private void init() {
setClickable(true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setFilterBitmap(true);
}
/**
* 设置特效类型
*
* @param effect
*/
public void setEffectType(ButtonEffect effect) {
mEffect = effect;
invalidate();
}
/**
* 获得特效类型
*
* @return
*/
public ButtonEffect getEffectType() {
return mEffect;
}
/**
* 设置水印
*
* @param bmp
* 水印
**/
public void setWaterMask(Bitmap bmp) {
setWaterMask(new BitmapDrawable(getContext().getResources(), bmp));
}
/**
* 设置水印
*
* @param ResourceId
* 水印资源
**/
public void setWaterMask(int ResourceId) {
setWaterMask(getResources().getDrawable(ResourceId));
}
/**
* 设置水印
*
* @param drawable
* 水印
**/
public void setWaterMask(Drawable drawable) {
this.mWatermark = drawable;
invalidate();
}
/**
* 使效果失效
*/
public void invalidEffect(){
fEffect = false;
if (mEffect == ButtonEffect.DARKEN) {
setColorFilter(getColorFilter(effectDarken(1.0f)));
}
invalidate();
}
/**
* 使效果生效
*/
protected void validEffect(){
fEffect = true;
if (mEffect == ButtonEffect.DARKEN) {
setColorFilter(getColorFilter(effectDarken(0.8f)));
}
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(getDrawable() == null ){
return;
}
if (fEffect && mEffect == ButtonEffect.NONE) {
// return;
final Drawable d = getDrawable();
final Bitmap bmp = Bitmap.createBitmap(d.getIntrinsicWidth(),
d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
final Drawable nul = getContext().getResources().getDrawable(R.drawable.bg_null);
Log.i("size", nul.getIntrinsicWidth()+" "+nul.getIntrinsicHeight());
BitmapDrawable bd = (BitmapDrawable) nul;
Bitmap bmp_null = bd.getBitmap();
// final Canvas c = new Canvas(bmp_null);
// nul.draw(c);
canvas.drawBitmap(bmp_null, 0, 0, mPaint);
// canvas.drawBitmap(bmp, bmp.getWidth() / 2, bmp.getHeight() / 2, mPaint);
// mPaint.setColor(getContext().getResources().getColor(R.color.default_navigationbar_text_color));
// canvas.drawLine(0, 0, 30, 5, mPaint);
} else if (fEffect && mEffect == ButtonEffect.SUNSHINE) {
final Drawable d = getDrawable();
final Bitmap bmp = Bitmap.createBitmap(d.getIntrinsicWidth(),
d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(bmp);
d.draw(c);
canvas.drawBitmap(
effectSunshine(bmp, bmp.getWidth() / 2, bmp.getHeight() / 2),
0, 0, mPaint);
} else if (mWatermark != null && fEffect
&& mEffect == ButtonEffect.WATERMARK) {
final Drawable d = getDrawable();
final int left = (d.getIntrinsicWidth() - mWatermark
.getIntrinsicWidth()) / 2;
final int top = (d.getIntrinsicHeight() - mWatermark
.getIntrinsicHeight()) / 2;
// canvas.drawBitmap(mWatermark, left, top, mPaint);
mWatermark.setBounds(left, top,
left + mWatermark.getIntrinsicWidth(),
top + mWatermark.getIntrinsicHeight());
mWatermark.draw(canvas);
} else if (fEffect && mEffect == ButtonEffect.RIM) {
final Drawable d = getDrawable();
final Bitmap bmp = Bitmap.createBitmap(d.getIntrinsicWidth(),
d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(bmp);
d.draw(c);
canvas.drawBitmap(effectRim(bmp), 0, 0, mPaint);
}
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
return super.onTrackballEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = MotionEventCompat.getActionMasked(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
//不让父控件获取手势
// if (getParent() != null) {
// getParent().requestDisallowInterceptTouchEvent(true);
// }
validEffect();
break;
case MotionEvent.ACTION_MOVE:
// if(!fEffect){
// validEffect();
// }
break;
case MotionEvent.ACTION_UP:
//不让父控件获取手势
// if (getParent() != null) {
// getParent().requestDisallowInterceptTouchEvent(false);
// }
invalidEffect();
break;
case MotionEvent.ACTION_OUTSIDE:
invalidEffect();
break;
// case MotionEvent.ACTION_CANCEL:
// invalidEffect();
// break;
}
return super.onTouchEvent(event);
}
/**
* 光照效果
*
* @param bmp
* 光照中心x坐标
* @param centerX
* 光照中心要坐标
* @param centerY
* @return
*/
public static Bitmap effectSunshine(Bitmap bmp, int centerX, int centerY) {
final int width = bmp.getWidth();
final int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int radius = Math.min(centerX, centerY);
final float strength = 150F; // 光照强度 100~150
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int pos = 0;
for (int i = 1, length = height - 1; i < length; i++) {
for (int k = 1, len = width - 1; k < len; k++) {
pos = i * width + k;
pixColor = pixels[pos];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = pixR;
newG = pixG;
newB = pixB;
// 计算当前点到光照中心的距离,平面座标系中求两点之间的距离
int distance = (int) (Math.pow((centerY - i), 2) + Math.pow(
centerX - k, 2));
if (distance < radius * radius) {
// 按照距离大小计算增加的光照值
int result = (int) (strength * (1.0 - Math.sqrt(distance)
/ radius));
newR = pixR + result;
newG = pixG + result;
newB = pixB + result;
}
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
pixels[pos] = Color.argb(Color.alpha(pixColor), newR, newG,
newB);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
/**
* 调整亮度
* 1f为原始亮度, 范围为0f - 2f
*/
private ColorMatrix effectDarken(float light) {
final ColorMatrix cm = new ColorMatrix();
cm.setScale(light, light, light, 1);
return cm;
}
private ColorMatrixColorFilter getColorFilter(ColorMatrix cm) {
return new ColorMatrixColorFilter(cm);
}
/**
* 缩放位图
*
* @param src
* 原图
* @param sx
* x缩放值
* @param sy
* y缩放值
* @return
*/
private Bitmap scale(Bitmap src, float sx, float sy) {
final Matrix m = new Matrix();
m.postScale(sx, sy);
return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(),
m, true);
}
/**
* 描边效果
*
* @param bmp
* @return
*/
private Bitmap effectRim(Bitmap bmp) {
final Canvas c = new Canvas(bmp);
final Bitmap rim = bmp.extractAlpha();
final float sx = (rim.getWidth() - 5.0f) / rim.getWidth();
final float sy = (rim.getHeight() - 5.0f) / rim.getHeight();
final Bitmap scale = scale(rim, sx, sy);
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.CYAN);
c.drawBitmap(rim, 0, 0, paint);
final Bitmap b = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(),
Bitmap.Config.ARGB_8888);
c.setBitmap(b);
c.drawBitmap(scale, (b.getWidth() - scale.getWidth()) / 2,
(b.getHeight() - scale.getHeight()) / 2, paint);
final int[] pixels = new int[b.getWidth() * b.getHeight()];
b.getPixels(pixels, 0, b.getWidth(), 0, 0, b.getWidth(), b.getHeight());
// 过滤掉遮罩部分
for (int i = 0, m = bmp.getWidth(); i < m; i++) {
for (int j = 0, n = bmp.getHeight(); j < n; j++) {
final int pos = i * bmp.getWidth() + j;
if (pixels[pos] == Color.CYAN) {
bmp.setPixel(i, j, Color.TRANSPARENT);
}
}
}
return bmp;
}
}