前文 Android超出父布局控件点击事件失效问题处理 讲了当使用 clipChildren=false
属性时,超出父控件的子控件区域点击会失效的问题,也给出了解决方案,但是觉得还不够方便,就封装了一个 GlobalTouchActivity
基类,以便于使用。
代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100package com.game.win.xxx.sdk.pages.ui;
import android.app.Activity;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import com.game.win.wallet.sdk.utils.ViewUtils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class GlobalTouchActivity extends Activity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportGlobalTouchListener();
}
/**
* 全局点击事件监听
*/
public interface OnGlobalTouchListener{
/**
* 监听事件回调
* @param rect View所在坐标范围
* @param point 点击事件发生的坐标
*/
void onTouch(Rect rect, Point point);
}
final Map<View,OnGlobalTouchListener> globalTouchViews = new HashMap<>();
/**
* 支持全局触摸事件监听
*/
public void supportGlobalTouchListener(){
getWindow().getDecorView().getRootView().setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
Set<Map.Entry<View, OnGlobalTouchListener>> touchViewSet = globalTouchViews.entrySet();
Iterator<Map.Entry<View, OnGlobalTouchListener>> it = touchViewSet.iterator();
while(it.hasNext()){
Map.Entry<View, OnGlobalTouchListener> entry = it.next();
View view = entry.getKey();
if(globalTouch(view,event)){
Rect rect = new Rect();
view.getGlobalVisibleRect(rect);
OnGlobalTouchListener globalTouchListener = entry.getValue();
if(globalTouchListener!=null){
globalTouchListener.onTouch(rect,new Point((int)event.getRawX(),(int)event.getRawY()));
}
return true;
}
}
return false;
}
});
}
/**
* 设置全局触摸事件监听
* @param view
* @param listener
*/
public void setGlobalTouchListener(View view,OnGlobalTouchListener listener){
globalTouchViews.put(view,listener);
}
/**
* 全局坐标点击判断
* @param targetView
* @param event
* @return
*/
private boolean globalTouch(View targetView, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
Rect r = new Rect();
targetView.getGlobalVisibleRect(r);
int x = (int) event.getRawX();
int y = (int) event.getRawY();
return r.contains(x,y);
}
return false;
}
public void onDetachedFromWindow() {
globalTouchViews.clear();
super.onDetachedFromWindow();
}
}这样一来,当需要处理全局事件点击时,直接继承自
GlobalTouchActivity
,然后设置全局触摸点击事件,就变得非常简单了:1
2
3
4
5
6setGlobalTouchListener(center_icon, new OnGlobalTouchListener() {
public void onTouch(Rect rect, Point point) {
finish();
}
});