传统的一ImageView皆为正规的矩形,如何识别多边形或是不规则图形的点击事件呢,下面我们针对这块进行研究,
研究对象为正六边形:
最终不同点击事件效果图如下:
对应的输出LogCat,有了这些事件,后续添加处理方法就太容易了,
下面是代码部分,首先是步局文件:
activity_main.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal|center_vertical" >
android:id="@+id/sexangleView0"
android:layout_width="278sp"
android:layout_height="379sp"
android:layout_marginTop="-90sp"
>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="invisible"
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="invisible"/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_light"
/>
android:id="@+id/sexangleView1"
android:layout_width="278sp"
android:layout_height="379sp"
android:layout_marginTop="10sp"
>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_light"
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_email"
android:contentDescription="2"
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_dark"
/>
android:id="@+id/sexangleView2"
android:layout_width="278sp"
android:layout_height="379sp"
android:layout_marginTop="110sp"
>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_dark"
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_pic"
android:contentDescription="1"
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_file"
android:contentDescription="4"/>
android:id="@+id/sexangleView3"
android:layout_width="278sp"
android:layout_height="379sp"
android:layout_marginTop="210sp"
>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_video"
android:contentDescription="3"
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_dark"
/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_light"
/>
android:id="@+id/sexangleView4"
android:layout_width="278sp"
android:layout_height="379sp"
android:layout_marginTop="310sp"
>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/center_light"
/>
main_activity.javapublic class MainActivity extends Activity implements OnClickListener {
private static final int JUMP_FLAG1 = 1;
private static final int JUMP_FLAG2 = 2;
private static final int JUMP_FLAG3 = 3;
private static final int JUMP_FLAG4 = 4;
public static Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case JUMP_FLAG1:
Jump_page(1);
break;
case JUMP_FLAG2:
Jump_page(2);
break;
case JUMP_FLAG3:
Jump_page(3);
break;
case JUMP_FLAG4:
Jump_page(4);
break;
default:
break;
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onClick(View v) {
}
public static void Jump_page(int t){
switch(t){
case 1:
Log.d("TEST","跳往图片");
break;
case 2:
Log.d("TEST","跳往邮件");
break;
case 3:
Log.d("TEST","跳往视频");
break;
case 4:
Log.d("TEST","跳往文件");
break;
default:
break;
}
}
}
//SexangleImageView.javapublic class SexangleImageView extends View {
private int mWidth;
private int mHeight;
private int centreX;//中心点
private int centreY;//中心点
private int mLenght;
private Paint paint;
public SexangleImageView(Context context) {
super(context);
}
public SexangleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mWidth = getWidth();
mHeight = getHeight();
// 计算中心点
centreX = mWidth / 2;
centreY = mHeight / 2;
mLenght = mWidth / 2;
double radian30 = 30 * Math.PI / 180;
float a = (float) (mLenght * Math.sin(radian30));
float b = (float) (mLenght * Math.cos(radian30));
float c = (mHeight - 2 * b) / 2;
if (null == paint) {
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);//FILL
paint.setColor(Color.parseColor("#A2A2A2"));
paint.setAlpha(200);
}
Path path = new Path();
path.moveTo(getWidth(), getHeight() / 2);
path.lineTo(getWidth() - a, getHeight() - c);
path.lineTo(getWidth() - a - mLenght, getHeight() - c);
path.lineTo(0, getHeight() / 2);
path.lineTo(a, c);
path.lineTo(getWidth() - a, c);
path.close();
canvas.drawPath(path, paint);
/*
InputStream is = getResources().openRawResource(R.drawable.sec_10);
Bitmap mBitmap = BitmapFactory.decodeStream(is);
Paint mPaint = new Paint();
canvas.drawBitmap(mBitmap, centreX, centreY, mPaint);
*/
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float edgeLength = ((float) getWidth()) / 2;
float radiusSquare = edgeLength * edgeLength * 3 / 4;
float dist = (event.getX() - getWidth() / 2)
* (event.getX() - getWidth() / 2)
+ (event.getY() - getHeight() / 2)
* (event.getY() - getHeight() / 2);
if (dist <= radiusSquare) {// 点中六边形区域
paint.setColor(Color.parseColor("#A8A8A8"));
paint.setStyle(Style.FILL);
paint.setAlpha(100);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
paint.setColor(Color.parseColor("#A2A2A2"));
paint.setStyle(Style.STROKE);
paint.setAlpha(200);
//String dd = this.getTag().toString();
invalidate();
CharSequence flagIcons = this.getContentDescription();//Flag_image
if(flagIcons==null){
}else{
Message msg1=new Message();
msg1.what = Integer.parseInt(flagIcons.toString());
MainActivity.myHandler.sendMessage(msg1);
}
break;
}
return true;
}
}
//SexangleViewGroup.javapublic class SexangleViewGroup extends ViewGroup {
private static final int SPACE = 15;// view与view之间的间隔
public SexangleViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int lenght = (int) (getWidth() / 2.5) - SPACE;// 每个子VIEW的长度
double radian30 = 30 * Math.PI / 180;
float h = (float) (lenght * Math.cos(radian30));
int bottomSpace = (int) ((lenght - 2 * h) / 2);// 六边形离底部的间隔
int offsetX = lenght * 3 / 4 + SPACE;// X轴每次偏移的长度
int offsetY = lenght / 2;// Y轴每次偏移的长度
int rowIndex = 0;//行下标
int childCount = 3;
int tempCount = 3;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if(i == childCount){
rowIndex++;
if(tempCount - 1 <= 0){
tempCount = 3;
}else{
tempCount --;
}
childCount += tempCount;
}
int startL = i % 3 * offsetX;
int startT = i % 3 * offsetY;
if(tempCount == 1){
startL -= offsetX;
startT -= offsetY;
}
child.layout(startL, startT + rowIndex * lenght,
startL + lenght, startT + lenght
+ rowIndex * lenght - bottomSpace);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure((int) (getWidth() / 2.5), (int) (getWidth() / 2.5));
child.setTag(i);
}
}
}
分析说明:六边形与传统正放的矩形ImageView比较,属不规则图形,意味着imageView的onclick方法将不太精确,必须通过自定义view,在ondraw中进行重新处理;在ontouchevent中的区域识别是关键。熟悉了源码后会发现该内容有很大的扩展空间,当前我好多地方被我写的不太灵活,是因为有现实需要,高手自行修改吧。
免费源码:
SexangleView.zip [登录雪炭网后可见]
资源声明:该资源限下载者本人使用,仅供参考界面设计逻辑,严禁散播至第三方,本文不可转载。违规将追究相关责任。
版权声明:
作者信息(Author) :雪炭网 : 花花世界
原文链接(Hyperlink):https://snowcoal.com/article/520.html
原创内容,尊重版权,转载需注明出处;商业及其他特殊用途转载需原作者同意。