BottomSheet를 구현하는 도중, BottomSheet 뒤에 가려진 버튼들이 클릭이 가능해지는 버그가 있었다.
스택 오버플로우의 글을 읽고 바텀시트에 clickable="true"를 추가해서 간단히 해결했지만, CoordinatorLayout에서 터치를 가로채는 방식에 대해서 정리해야겠다는 생각이 들었다.
coordinatorLayout에서 상위 뷰가 하위 뷰의 터치를 가로채는 동작은 아래에 보이는 CoordinatorLayout.Behavior 를 상속받아서 구현한다.
public class CoordinatorLayout extends ViewGroup implements NestedScrollingParent2,
NestedScrollingParent3 { ...
public static abstract class Behavior<V extends View> { ...
public boolean onInterceptTouchEvent(@NonNull CoordinatorLayout parent, @NonNull V child,
@NonNull MotionEvent ev) {
return false;
}
public boolean onTouchEvent(@NonNull CoordinatorLayout parent, @NonNull V child,
@NonNull MotionEvent ev) {
return false;
}
...}
...}
Behavior에는 다른 메서드들도 많이 있지만, 지금은 터치에 관련된 메서드 두개만 보자.
onInterceptTouchEvent
Params:
parent – the parent view currently receiving this touch event
child – the child view associated with this Behavior
ev – the MotionEvent describing the touch event being processed
Returns:
true if this Behavior would like to intercept and take over the event stream.
The default always returns false.
말 그대로 Event를 intercept할지 결정한다.
CoordinatorLayout으로 전달된 터치 이벤트 중 어떤걸 가로채고 어떤걸 자식에게 전달해줄건지 결정한다.
드래그처럼 단일 터치 이벤트만으로는 판단이 힘든 경우, 자식에게 넘겨주는 일을 보류할 수도 있다.
이벤트를 intercept 할거라면 true를 반환하고, 그 전까지는 false를 반환하면 된다.
기본적으로 항상 false를 반환하기 때문에 따로 구현하지 않으면 자식에게 모든 터치 이벤트가 넘어가게된다.
자식 뷰가 표시되는지에 대한 여부를 View.isShown() 으로 확인할 수 있다. 이 메서드는 자식뷰가 보일때만 터치를 넘겨주는 동작을 구현할 때 유용하게 사용할 수 있다.
onTouchEvent
Params:
parent – the parent view currently receiving this touch event
child – the child view associated with this Behavior
ev – the MotionEvent describing the touch event being processed
Returns:
true if this Behavior would like to intercept and take over the event stream.
The default always returns false.
onInterceptTouchEvent 가 intercept를 시작했을 때, (=true를 반환하는 경우)
가로챈 이벤트를 가지고 뷰 레이아웃을 변경하는 작업을 여기서 처리한다.
이 메서드도 자식의 가시성과 상관없이 동작하기 때문에 View.isShown() 으로 확인해서 처리해야한다.
UI 창을 열고닫는 동작 등을 여기서 구현할 수 있다.
'프레임워크 > Android' 카테고리의 다른 글
compiler version error 원인 (0) | 2023.02.18 |
---|---|
Android와 이미지 형식 (0) | 2023.01.24 |
Databinding Type mismatch 문제 : layout format 확인하기 (0) | 2022.11.30 |
Jetpack Navigation Safeargs 사용법 (0) | 2022.11.29 |
RecyclerView 요약정리 (0) | 2022.11.03 |