woong's

Android Touch Intercept 사용하기 본문

Develop/Android

Android Touch Intercept 사용하기

dlsdnd345 2016. 2. 14. 19:15

Android Touch Intercept 사용하기


1. 문제 상황

 - ViewPager > RecyclerView > ViewPager 

   위와 같은 구조였습니다. 상위의 Viewpager Swipe 를 하려다 보니 안의 ViewPager 가 스크롤이 되는 상황

   안의 ViewPager Swipe 를 막고 버튼으로 대체 하였지만 , 상위 ViewPager가 Swipe가 안됨.

   안의 ViewPager가 Touch 를 뺐어 가기 때문!!

 

2. 해결방안

  - 처음에는 안의 ViewPager 를 막으면 된다고 생각하였지만 , 반대로 적용해야 해결할수 있다.

    * View를 터치하면 상위 View 부터 하위 View로 터치가 전달된다.

     그러기때문에 상위 View 에서 이벤트를 가로채야 한다.


3. 문제점 해결간의 이슈

  - 상위 ViewPager 에서 이벤트를 가로채면 위 문제를 해결 할수 있다.

   하지만 상위 ViewPager 에서 이벤트를 가로 챘기때문에 RecyclerView Item이 선택이 안되는 문제가 발생.

   위 문제를 해결하기 위해서 Touch Action 에 대해 분기가 필요


4. 해결방법


  1. 상위 ViewPager를 CustomViewPager로 만든다.

  2. onInterceptTouchEvent Overide 해서 Action 에대해서 정의

  3. Action 이 Move 일 경우 상위 ViewPager로 이벤트 전달

  4. Action 이 UP , DOWN 일 경우 하위 View 로 이벤트 전달


   * onInterceptTouchEvent getAction 을 하게 되면 ACTOIN_DOWN 밖에 리턴이 안됨.

     아래와 같이 action을 얻어야 원하는 UP , DOWN , MOVE 이벤트를 받을수 있음.


1
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
cs

 

 

     


 코드는 굉장히 간단하다. 하지만 이 Touch 에 대한 개념이 명확히 정리 되지 않으면,

 굉장히 헤맬수 있습니다.


onInterceptTouchEvent

true : 이벤트를 가져온다는 의미

false : 하위 View 로 이벤트를 전달한다는 의미


그리하여 필자는 Drag 시 상위 ViewPager (true) 로 이벤트를 전달 하였고,

아닐경우 하위 View (false) 로 이벤트를 전달해 주었습니다.


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
 
public class SwipeableViewPager extends ViewPager {
 
    private static final int OFF_SET = 10;
 
 
    private float preX;
 
    public SwipeableViewPager(Context context) {
        super(context);
    }
 
    public SwipeableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
 
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
 
        final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
 
        switch (action){
 
            case MotionEvent.ACTION_DOWN:
                preX = ev.getX();
                break;
            case MotionEvent.ACTION_MOVE:
 
                float x = ev.getX();
                if((x - OFF_SET <= preX && preX <= x+ OFF_SET)){
                    return false;
                }else{
                    return true;
                }
        }
 
        return super.onInterceptTouchEvent(ev);
    }
 
}
 
 
 
 
cs



5. 정리


알면 도움될만한 정보를 정리해 보려 합니다.


1. Touch 우선 순위

   


출처 : http://nmshome.tistory.com/71


Activity > ViewGroup > View 순서

dispatchTouchEvent > onInterceptTouchEvent > onTouch 순서


결론 

  - View Touch 에 관해서 정확한 개념이 없으면 코드량은 별로 없지만 굉장히 헤맬수 있는 여지가 많다.

    필자도 android 개발하면 Touch 에 대한 정확한 개념이 없어 위와 같은 상황에서 해결하면서 많은

    시행착오가 있었다. 이런 시행착오를 정리 하지 않으면 다음에 똑같은 상황이 생길것 같아 간단히라도

    개념정리를 해보았다. 이외에도 super , parent 개념이 있는데 조금씩 정리해보아야 겠다.


Comments