这几天一直被公司的项目所困扰,尤其是一个简单的遥控按钮布局的问题,几张不规则的按钮图片拼凑在一起,点击事件之间总是受影响,所以,尝试去想很多办法去解决,但唯一能想到的就是自定义View的方式去确认每个点击位置,对位置精确化,但这看似简单,做起来很繁琐,当然自己能力有限,自定义View这块的知识并不是很牢固,所以没多尝试,直接pass掉了。之后会多研究自定义View,希望在这块能写下一份专栏式的笔记,以后好回忆。
最好逛逛github,既然找到了一种比较简单的思路,同样是自定义View,不过这个简单多了。思路就是取得不规则图片,然后识别出其非透明状态的形状,只对改形状获取点击事件,就这样简单的完成了。
代码如下:
/**
* 描述:自定义实现不规则按钮交互效果
* Created by jrue on 2015/10/9.
*/
public class IrregularButton extends ImageView {
//当前布局尺寸
private int width = -1;
private int height = -1;
private Bitmap bitmap;
private Context mContext;
//实际图片缩放比例
float viewScaleX;
float viewScaleY;
private int bgColor;
public IrregularButton(Context context) {
super(context);
this.mContext = context;
}
public IrregularButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mContext = context;
}
public IrregularButton(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IrregularButton);
bgColor = a.getColor(R.styleable.IrregularButton_bgcolor, getResources().getColor(android.R.color.transparent));
a.recycle();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action != MotionEvent.ACTION_DOWN) {
return super.onTouchEvent(event);
}
//获取背景selector
if (width == -1 || height == -1) {
Object object = getDrawable();
if (object instanceof BitmapDrawable) {
//如果没有使用selector
BitmapDrawable bitmapDrawable = (BitmapDrawable) object;
bitmap = bitmapDrawable.getBitmap();
} else {
//获取selector
StateListDrawable drawable = ((StateListDrawable) object);
Class<StateListDrawable> c = StateListDrawable.class;
try {
//获取背景selecttor个数,如果有两个,则取当前的
Method methodCount = c.getMethod("getStateCount");
int count = (int) methodCount.invoke(drawable);
if (count > 1) {
Drawable selectorDrawable = drawable.getCurrent();
bitmap = ((BitmapDrawable) selectorDrawable).getBitmap();
} else {
//获取没有显示的特定图片
Method method = c.getMethod("getStateDrawable", int.class);
Drawable selectorDrawable = (Drawable) method.invoke(drawable, 0);
bitmap = ((BitmapDrawable) selectorDrawable).getBitmap();
}
} catch (Exception e) {
e.printStackTrace();
}
}
width = getWidth();
height = getHeight();
viewScaleX = (width / (float) bitmap.getWidth());
viewScaleY = (height / (float) bitmap.getHeight());
}
int x = (int) (event.getX() / viewScaleX);
int y = (int) (event.getY() / viewScaleY);
//判断请求是否超出范围
if (null == bitmap || x < 0 || y < 0 || x >= width || y >= height) {
return false;
}
//获取像素
int pixel = bitmap.getPixel(x, y);
//判断像素是否是指定空白颜色,阻止请求
if (pixel == bgColor) {
return false;
}
return super.onTouchEvent(event);
}
}
还有attrs.xml文件里自定义的属性:
<!-- 不规则按钮的实现 -->
<declare-styleable name="IrregularButton">
<attr name="bgcolor" format="color"/>
</declare-styleable>
在布局中这样用:
<com.meizu.router.widget.IrregularButton
android:id="@+id/btn_tv_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/remote_tv_key_ok"
mzsz:bgcolor="@android:color/transparent" />
别忘了再头部加上:
xmlns:mzsz="http://schemas.android.com/apk/res-auto"
就这样OK,完美。