Andriod 대화 상자 FLAGNOT_TOUCH_MODAL 활용 정보
이루고 싶은 일.
1. 대화상자가 표시된 상태에서 대화상자 이외의 구역에 단추가 존재하면 단추를 누르면 대화상자를 삭제하는 동시에 단추의 클릭 이벤트도 반응한다.
2. 대화 상자 이외의 영역에 ListView와 같은 스크롤 가능한 UI가 존재하면 스크롤과 동시에 대화 상자를 닫는다
3. 등등
간단하게 말하면, 대화상자가 표시된 상태에서도 대화상자 뒤의 UI를 조작할 수 있다고 생각합니다.
이루어지다
사실 이 문제는 그렇게 어렵지 않을 것 같아요. 자주 사용하는 분들은
android.view.Window
의 로고를 아세요?JAVADOC를 보러 가면:Window flag: even when this window is focusable, allow any pointer events outside of the window to be sent to the windows behind it.
Otherwise it will consume all pointer events itself, regardless of whether they are inside of the window.
그럼, 문제를 해결할 수 있을 거야!
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); // Dialog以外のどころも操作できるように設定
dialog.setCanceledOnTouchOutside(true); // Dialog以外のエリアをタップするとDialog閉じるように設定
실행해 보시면 대화상자 뒤의 UI를 모두 조작할 수 있습니다!그렇지만
대화 상자 예약!set Canceled On Touch Outside(진짜)는 작동하지 않습니다!
그럼 우리 스스로 실현합시다!
1. 대화 상자의 창에 Outside를 추가하고 Listener를 클릭
window.addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
2. 대화 상자에 Ontouch, ACTION 추가OUSIDE 이벤트에 불이 났을 때 대화상자를 닫습니다.Dialog dialog = new Dialog(getActivity(), R.style.modal_dialog_theme) {
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
dismiss();
}
return false;
}
};
그게 다야.다른 소감
아시다시피 안드로이드는 Dialog와 DialogFragment 두 종류가 있고, DialogFragment에는 Lifcycle이 있어 추천합니다.
중국어 판본
이 작은 기능은 듣기에 매우 간단해서 다이어로그 분 하나로는 분명하게 알 수 없다.
그러나 디자이너는 팝업 상자 이외의 어느 구역을 눌러도 이 UI를 끄지 못하고 사용자 체험을 처리할 수 없다고 말했다.
만약 상자 이외의 구역에 카드 누르기가 존재한다면, 이 카드 누르기 구역을 눌렀을 때 대화상자를 닫을 뿐만 아니라 카드 누르기 이벤트도 활성화해야 합니다!
2. 상자 이외의 구역에 ListView와 같은 스크롤할 수 있는 ViewGroup이 존재할 경우, 슬라이딩 팝업 상자 이외의 구역은 반드시 대화상자를 닫지 않고 ListView를 스크롤할 수 있도록 해야 한다.
3. 팝업 상자 이외의 구역에 다른 등이 존재하지 않는다면...
간단하게 말하자면, 이 다이어로그가 표시될 때, 다이어로그 뒤에 있는 모든 뷰도 다이어로그를 닫은 후에야 다른 뷰가 눌리거나 굴러갈 수 있는 상태가 되어야 한다.
사실 곰곰이 생각해봐도 어렵지 않아요. 안드로이드에 익숙해요.view.윈도우 친구들은 모두 윈도우 매니저를 안다.LayoutParams.FLAG_NOT_TOUCH_이 Flag.
이렇게 설명했습니다.
Window flag: even when this window is focusable, allow any pointer events outside of the window to be sent to the windows behind it.
Otherwise it will consume all pointer events itself, regardless of whether they are inside of the window.
좋아, 모든 문제를 알아차렸어!
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); // 设置Dialog以外View处于可操作状态
dialog.setCanceledOnTouchOutside(true); // 点击Dialog以外区域自动关闭该dialog
실행해 보니 역시 다이어로그가 표시된 상태에서 모든 다이어로그 뒤의view는 조작 상태로 처리할 수 있습니다. 단지 문제가 하나 있습니다. 다른 뷰를 조작할 때 현재의 다이어로그는 자동으로 닫히지 않았습니다. 분명히 setCanced OnTouch Outside라는 방법은 효과가 없습니다!나는 곧 깨달았다. 부모님, 나는 또 대안탁의 구덩이에 빠졌다!이미 set Canceled On Touch Outside가 좋지 않으니, 우리 스스로 풍족하게 생활하자!구덩이 메우기 시작!
1. 다이어로그의 윈도에 외곽타격 감청 추가
window.addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
Dialog dialog = new Dialog(getActivity(), R.style.modal_dialog_theme) {
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
dismiss();
}
return false;
}
};
해결!Dialog 사용 보완 정보
안드로이드에는 Dialog와 DialogFragment가 존재하는데 DialogFragment는 생명주기가 존재하기 때문에 사용자를 추천하는 것을 더욱 좋아합니다.
Reference
이 문제에 관하여(Andriod 대화 상자 FLAGNOT_TOUCH_MODAL 활용 정보), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ISmartop/items/747549e0a821ec147f21텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)