Skip to content

Commit 4c4e37b

Browse files
committed
feat: 添加对话框活跃监听功能
1 parent 7d886a5 commit 4c4e37b

16 files changed

Lines changed: 459 additions & 0 deletions

DialogFragmentUtilsLib/src/main/java/com/osard/dialogfragmentutilslib/BaseDialogLibUtils.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import com.osard.dialogfragmentutilslib.init.DialogLibInitSetting;
2222
import com.osard.dialogfragmentutilslib.utils.DensityUtils;
23+
import com.osard.dialogfragmentutilslib.utils.TouchCallbackWrapper;
2324

2425
import java.util.HashMap;
2526
import java.util.Map;
@@ -38,6 +39,8 @@ public abstract class BaseDialogLibUtils extends DialogFragment implements Dialo
3839
//别名,同一个别名的对话框同一时间只能弹出一个,在show时如果存在未关闭的对话框则直接返回原本对象
3940
protected String alias = UUID.randomUUID().toString();
4041

42+
protected Runnable onActiveListener;
43+
4144
protected float landscapeWidthFactor = -1;
4245
protected float portraitWidthFactor = -1;
4346

@@ -71,6 +74,23 @@ public String getAlias() {
7174
return alias;
7275
}
7376

77+
@Override
78+
public void onStart() {
79+
super.onStart();
80+
Dialog dialog = getDialog();
81+
if (dialog == null) return;
82+
Window window = dialog.getWindow();
83+
if (window == null) return;
84+
85+
if (window.getCallback() instanceof TouchCallbackWrapper) {
86+
return; // 已安装
87+
}
88+
89+
Window.Callback origin = window.getCallback();
90+
window.setCallback(new TouchCallbackWrapper(origin, onActiveListener));
91+
}
92+
93+
7494
/**
7595
* 宽度
7696
* <p>
@@ -210,6 +230,7 @@ public void closeDuplicateAliasDialog() {
210230

211231
/**
212232
* 延迟关闭方法,避免出现还未添加就关闭导致无法关闭的情况,最大延迟3秒
233+
*
213234
* @param TAG
214235
* @param retryCount
215236
* @return

DialogFragmentUtilsLib/src/main/java/com/osard/dialogfragmentutilslib/DialogLibAllCustom.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ public DialogLibAllCustom setPortraitWidthFactor(float portraitWidthFactor) {
5353
return this;
5454
}
5555

56+
/**
57+
* 设置活跃监听,对话框在用户按下操作时触发,包括对话框空白区域
58+
*/
59+
public DialogLibAllCustom setOnActiveListener(Runnable onActiveListener) {
60+
this.onActiveListener = onActiveListener;
61+
return this;
62+
}
63+
5664
/**
5765
* 是否允许点击其他位置关闭
5866
*/

DialogFragmentUtilsLib/src/main/java/com/osard/dialogfragmentutilslib/DialogLibCommon.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ private String getTitle() {
6363
return title;
6464
}
6565

66+
/**
67+
* 设置活跃监听,对话框在用户按下操作时触发,包括对话框空白区域
68+
*/
69+
public DialogLibCommon setOnActiveListener(Runnable onActiveListener) {
70+
this.onActiveListener = onActiveListener;
71+
return this;
72+
}
73+
6674
/**
6775
* 横屏时dialog占屏幕宽度的百分比系数,0-1之间有效,不含边界
6876
*/

DialogFragmentUtilsLib/src/main/java/com/osard/dialogfragmentutilslib/DialogLibCustom.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ public DialogLibCustom setAlias(String alias) {
116116
return this;
117117
}
118118

119+
/**
120+
* 设置活跃监听,对话框在用户按下操作时触发,包括对话框空白区域
121+
*/
122+
public DialogLibCustom setOnActiveListener(Runnable onActiveListener) {
123+
this.onActiveListener = onActiveListener;
124+
return this;
125+
}
126+
119127
/**
120128
* 设置自定义视图触发ok按钮时的响应
121129
* 接口返回true关闭对话框,反之不关闭

DialogFragmentUtilsLib/src/main/java/com/osard/dialogfragmentutilslib/DialogLibInput.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,14 @@ public DialogLibInput setOnDismissListener(OnDismissListener onDismissListener)
147147
return this;
148148
}
149149

150+
/**
151+
* 设置活跃监听,对话框在用户按下操作时触发,包括对话框空白区域
152+
*/
153+
public DialogLibInput setOnActiveListener(Runnable onActiveListener) {
154+
this.onActiveListener = onActiveListener;
155+
return this;
156+
}
157+
150158
/**
151159
* 显示查看/隐藏密码图标组件
152160
* <p>

DialogFragmentUtilsLib/src/main/java/com/osard/dialogfragmentutilslib/DialogLibLoading.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ public DialogLibLoading setOnDismissListener(OnDismissListener onDismissListener
7575
return this;
7676
}
7777

78+
/**
79+
* 设置活跃监听,对话框在用户按下操作时触发,包括对话框空白区域
80+
*/
81+
public DialogLibLoading setOnActiveListener(Runnable onActiveListener) {
82+
this.onActiveListener = onActiveListener;
83+
return this;
84+
}
7885

7986
/**
8087
* 别名,同一个别名的对话框同一时间只能弹出一个,在show时如果存在未关闭的对话框则直接返回原本对象

DialogFragmentUtilsLib/src/main/java/com/osard/dialogfragmentutilslib/PopupWindowLib.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import android.os.Handler;
55
import android.os.Looper;
66
import android.util.Log;
7+
import android.view.MotionEvent;
78
import android.view.View;
89
import android.view.WindowManager;
910
import android.widget.PopupWindow;
@@ -25,6 +26,7 @@ public class PopupWindowLib {
2526
private boolean mAttachedInDecor;
2627
private boolean mFocusable;
2728
private long mAutoCloseTime;
29+
private Runnable onActiveListener;
2830

2931
//自动关闭的Handler和处理对象
3032
private Handler autoCloseHandler;
@@ -75,6 +77,14 @@ public PopupWindowLib setAttachedInDecor(boolean enabled) {
7577
return this;
7678
}
7779

80+
/**
81+
* 设置活跃监听,对话框在用户按下操作时触发,包括对话框空白区域
82+
*/
83+
public PopupWindowLib setOnActiveListener(Runnable onActiveListener) {
84+
this.onActiveListener = onActiveListener;
85+
return this;
86+
}
87+
7888
/**
7989
* PopupWindow 是否可以获取焦点
8090
*/
@@ -165,6 +175,15 @@ void createPopupWindow() {
165175
popupWindow.setAttachedInDecor(mAttachedInDecor);
166176
}
167177
popupWindow.setFocusable(mFocusable);
178+
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
179+
@Override
180+
public boolean onTouch(View v, MotionEvent event) {
181+
if (event.getAction() == MotionEvent.ACTION_DOWN && null != onActiveListener) {
182+
onActiveListener.run();
183+
}
184+
return false; // 返回 false,不影响 PopupWindow 正常点击
185+
}
186+
});
168187
} catch (Exception e) {
169188
if (DialogLibInitSetting.getInstance().isDebug()) {
170189
Log.e(TAG, "创建PopupWindow时出现错误", e);
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package com.osard.dialogfragmentutilslib.utils;
2+
3+
import android.os.Build;
4+
import android.view.ActionMode;
5+
import android.view.KeyEvent;
6+
import android.view.Menu;
7+
import android.view.MenuItem;
8+
import android.view.MotionEvent;
9+
import android.view.SearchEvent;
10+
import android.view.View;
11+
import android.view.Window;
12+
import android.view.WindowManager;
13+
import android.view.accessibility.AccessibilityEvent;
14+
15+
import androidx.annotation.NonNull;
16+
import androidx.annotation.Nullable;
17+
18+
public class TouchCallbackWrapper implements Window.Callback {
19+
private final Window.Callback origin;
20+
private final Runnable onTouch;
21+
22+
public TouchCallbackWrapper(Window.Callback origin, Runnable onTouch) {
23+
this.origin = origin;
24+
this.onTouch = onTouch;
25+
}
26+
27+
@Override
28+
public boolean dispatchKeyEvent(KeyEvent event) {
29+
if (null != onTouch && event.getAction() == KeyEvent.ACTION_DOWN) {
30+
onTouch.run();
31+
}
32+
return origin.dispatchKeyEvent(event);
33+
}
34+
35+
@Override
36+
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
37+
return origin.dispatchKeyShortcutEvent(event);
38+
}
39+
40+
@Override
41+
public boolean dispatchTouchEvent(MotionEvent event) {
42+
if (null != onTouch && event.getAction() == MotionEvent.ACTION_DOWN) {
43+
onTouch.run();
44+
}
45+
return origin.dispatchTouchEvent(event);
46+
}
47+
48+
@Override
49+
public boolean dispatchTrackballEvent(MotionEvent event) {
50+
return origin.dispatchTrackballEvent(event);
51+
}
52+
53+
@Override
54+
public boolean dispatchGenericMotionEvent(MotionEvent event) {
55+
return origin.dispatchGenericMotionEvent(event);
56+
}
57+
58+
@Override
59+
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
60+
return origin.dispatchPopulateAccessibilityEvent(event);
61+
}
62+
63+
@Nullable
64+
@Override
65+
public View onCreatePanelView(int featureId) {
66+
return origin.onCreatePanelView(featureId);
67+
}
68+
69+
@Override
70+
public boolean onCreatePanelMenu(int featureId, @NonNull Menu menu) {
71+
return origin.onCreatePanelMenu(featureId, menu);
72+
}
73+
74+
@Override
75+
public boolean onPreparePanel(int featureId, @Nullable View view, @NonNull Menu menu) {
76+
return origin.onPreparePanel(featureId, view, menu);
77+
}
78+
79+
@Override
80+
public boolean onMenuOpened(int featureId, @NonNull Menu menu) {
81+
return origin.onMenuOpened(featureId, menu);
82+
}
83+
84+
@Override
85+
public boolean onMenuItemSelected(int featureId, @NonNull MenuItem item) {
86+
return origin.onMenuItemSelected(featureId, item);
87+
}
88+
89+
@Override
90+
public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
91+
origin.onWindowAttributesChanged(attrs);
92+
}
93+
94+
@Override
95+
public void onContentChanged() {
96+
origin.onContentChanged();
97+
}
98+
99+
@Override
100+
public void onWindowFocusChanged(boolean hasFocus) {
101+
origin.onWindowFocusChanged(hasFocus);
102+
}
103+
104+
@Override
105+
public void onAttachedToWindow() {
106+
origin.onAttachedToWindow();
107+
}
108+
109+
@Override
110+
public void onDetachedFromWindow() {
111+
origin.onDetachedFromWindow();
112+
}
113+
114+
@Override
115+
public void onPanelClosed(int featureId, @NonNull Menu menu) {
116+
origin.onPanelClosed(featureId, menu);
117+
}
118+
119+
@Override
120+
public boolean onSearchRequested() {
121+
return origin.onSearchRequested();
122+
}
123+
124+
@Override
125+
public boolean onSearchRequested(SearchEvent searchEvent) {
126+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
127+
return origin.onSearchRequested(searchEvent);
128+
}
129+
return false;
130+
}
131+
132+
@Nullable
133+
@Override
134+
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
135+
return origin.onWindowStartingActionMode(callback);
136+
}
137+
138+
@Nullable
139+
@Override
140+
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
141+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
142+
return origin.onWindowStartingActionMode(callback, type);
143+
}
144+
return null;
145+
}
146+
147+
@Override
148+
public void onActionModeStarted(ActionMode mode) {
149+
origin.onActionModeStarted(mode);
150+
}
151+
152+
@Override
153+
public void onActionModeFinished(ActionMode mode) {
154+
origin.onActionModeFinished(mode);
155+
}
156+
}

DialogUtilsLib/src/main/java/com/mjsoftking/dialogutilslib/BaseDialogLibUtils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import com.mjsoftking.dialogutilslib.init.DialogLibInitSetting;
1414
import com.mjsoftking.dialogutilslib.utils.DensityUtils;
15+
import com.mjsoftking.dialogutilslib.utils.TouchCallbackWrapper;
1516

1617
/**
1718
* 加载等待框工具类
@@ -28,6 +29,8 @@ public abstract class BaseDialogLibUtils implements DialogLibUtils {
2829
//临时翻转确定与取消按钮位置
2930
protected Boolean reverseButton;
3031

32+
protected Runnable onActiveListener;
33+
3134
protected Context getContext() {
3235
return context;
3336
}
@@ -73,6 +76,12 @@ public void setDialogWidth(String TAG, Dialog dialog, Configuration configuratio
7376
p.width = (int) (DensityUtils.dipToPX(getContext(), configuration.screenWidthDp) * dialogWidthFactor(configuration));
7477
}
7578
dialog.getWindow().setAttributes(p);
79+
80+
if (window.getCallback() instanceof TouchCallbackWrapper) {
81+
return; // 已安装
82+
}
83+
Window.Callback origin = window.getCallback();
84+
window.setCallback(new TouchCallbackWrapper(origin, onActiveListener));
7685
} catch (Exception e) {
7786
if (DialogLibInitSetting.getInstance().isDebug()) {
7887
Log.w(TAG, "设置对话框宽度异常", e);

DialogUtilsLib/src/main/java/com/mjsoftking/dialogutilslib/DialogLibAllCustom.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ public DialogLibAllCustom setPortraitWidthFactor(float portraitWidthFactor) {
6767
return this;
6868
}
6969

70+
/**
71+
* 设置活跃监听,对话框在用户按下操作时触发,包括对话框空白区域
72+
*/
73+
public DialogLibAllCustom setOnActiveListener(Runnable onActiveListener) {
74+
this.onActiveListener = onActiveListener;
75+
return this;
76+
}
77+
7078
/**
7179
* 是否允许点击其他位置关闭
7280
*/

0 commit comments

Comments
 (0)