背景
在日常的开发过程中,有时候会碰到形状不规则的图片(其实是看起来不规则),比如一个卡通人物、特殊的符号或者拟物化的一个东西,如下图这样。当然这些图片也是矩形的,只是人眼看不到的区域是透明的而已。
实现步骤
说白了就是让透明区域不响应触摸事件,所以只要在view的触摸事件里做处理就行了。我们知道,view里的onTouchEvent ( MotionEvent event ) 方法,该方法返回false时,表示当前view不消费此次触摸事件,会把消息传递给它的父控件。(view的消息分发机制:http://www.cnblogs.com/linjzong/p/4191891.html)。
具体代码
1、自定义控件的代码
public class IrregularView extends View {
private Bitmap bitmap; public IrregularView(Context context) {
super(context);
} public IrregularView(Context context, AttributeSet attrs) {
super(context, attrs);
} public IrregularView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} @Override
public boolean onTouchEvent(MotionEvent event) {
// 点击了透明区域,则返回false
return !isPointTransparent(event) && super.onTouchEvent(event);
} /**
* 该点的颜色值是否为透明
* @param event event
* @return boolean
*/
private boolean isPointTransparent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY(); return getPointColor(x, y) == 0;
} /**
* 获取bitmap上某点的颜色值
*/
private int getPointColor(int x, int y) {
if(bitmap == null) {
bitmap = getBitmap();
} try {
return bitmap.getPixel(x, y);
} catch (Exception e) {
return -1;
}
} private Bitmap getBitmap() {
setDrawingCacheEnabled(true);// View对象必须做如下设置后,才能获取其中的图像
Bitmap bitmap = Bitmap.createBitmap(getDrawingCache());// 获取View中的图像
setDrawingCacheEnabled(false);// 从View对象中获取图像后,调用setDrawingCacheEnabled(false)清空画图缓 return bitmap;
}
}
2、XML布局文件 2、XML布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#C7EDCC"> <com.jiazy.irregularviewdemo.view.IrregularView
android:id="@+id/view1"
android:layout_width="200dp"
android:layout_height="200dp"
android:onClick="onClick"
android:background="@drawable/img_1_selector" /> <com.jiazy.irregularviewdemo.view.IrregularView
android:id="@+id/view2"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_alignParentEnd="true"
android:onClick="onClick"
android:background="@drawable/img_2_selector" /> <com.jiazy.irregularviewdemo.view.IrregularView
android:id="@+id/view3"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:onClick="onClick"
android:background="@drawable/img_1_selector" /> <com.jiazy.irregularviewdemo.view.IrregularView
android:id="@+id/view4"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:onClick="onClick"
android:background="@drawable/img_2_selector" />
</RelativeLayout>
效果演示
拓展
上面我们用到了透明的颜色值:0,其实也可以用其他颜色来判断是否需要处理触摸事件。之前有一个需求,是做一个选择地区的图形控件,点击某个地区进行选择,这个时候我们就可以通过这种方法来实现。 图中每个地区是一种颜色值,把地区的颜色值和地区信息对应起来,就可以实现以下效果。