2026년 상식닷컴 선정 식당 & 카페 리스트
최근에 오픈한 호텔을 찾는다면 살펴보세요

ViewPager 내부에서 HorizontalScrollView를 지원하는 방법.

_____
ViewPager 내부에서 HorizontalScrollView를 지원하는 방법 FAQ

Q1: ViewPager 내부에 HorizontalScrollView를 넣으면 스크롤 충돌이 발생하는 이유는?
A1: ViewPager와 HorizontalScrollView 모두 수평 방향 스크롤을 처리하므로, 터치 이벤트가 두 컴포넌트 사이에서 충돌하여 스크롤 방향이 불명확해집니다. ViewPager가 수평 스와이프 제스처를 우선 처리하면서 HorizontalScrollView 내부의 스크롤이 제대로 작동하지 않을 수 있습니다.

Q2: ViewPager와 HorizontalScrollView의 스크롤 충돌을 해결하는 기본적인 방법은?
A2: HorizontalScrollView가 터치 이벤트를 처리하도록 하여 ViewPager가 이벤트 인터셉트를 하지 못하게 해야 합니다. 즉, HorizontalScrollView에서 스크롤 가능 영역 내에 있을 때 ViewPager에 터치 이벤트 전달을 막는 커스텀 처리가 필요합니다.

---

Q3: ViewPager 내부의 HorizontalScrollView에서 터치 이벤트 충돌을 방지하는 샘플 코드는?
A3: HorizontalScrollView를 상속받아 onTouchEvent와 onInterceptTouchEvent를 오버라이딩 합니다.

```java
public class CustomHorizontalScrollView extends HorizontalScrollView {
private float mDownX;
private float mDownY;
private boolean mIsVpDragger;

public CustomHorizontalScrollView(Context context) {
super(context);
}

public CustomHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = ev.getX();
mDownY = ev.getY();
mIsVpDragger = false;
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
float diffX = Math.abs(ev.getX() - mDownX);
float diffY = Math.abs(ev.getY() - mDownY);
if (diffX > diffY) {
// 수평 드래그로 판단
mIsVpDragger = true;
getParent().requestDisallowInterceptTouchEvent(true);
} else {
getParent().requestDisallowInterceptTouchEvent(false);
mIsVpDragger = false;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
getParent().requestDisallowInterceptTouchEvent(false);
break;
}
return super.onInterceptTouchEvent(ev);
}
}
```

이 코드는 HorizontalScrollView가 수평 스와이프 동작인 경우 부모(ViewPager)에게 이벤트 전달을 막아 충돌을 방지합니다.

---

Q4: ViewPager2에서도 동일하게 적용 가능한가?
A4: ViewPager2는 RecyclerView 기반이므로 약간 다르지만, touch 이벤트 충돌 해결법은 비슷합니다. HorizontalScrollView 내부에서 부모(ViewPager2)에게 `requestDisallowInterceptTouchEvent(true)` 호출하여 수평 스크롤 이벤트를 차단하면 됩니다.

---

Q5: 다른 대안이 있을까?
A5:
- 중첩 스크롤 컨테이너 대신 다른 UI 설계: 수평 스크롤 뷰 내에 또다른 수평 스크롤 뷰를 넣는 것보다 사용자 경험을 고려해 다른 디자인을 고민.
- ViewPager 수평 스와이프 제한: ViewPager의 setUserInputEnabled(false)로 터치 스와이프 비활성화 후 버튼 등 다른 방식으로 페이지 이동 처리.
- 사용자 지정 터치 감지: 커스텀 뷰에서 ViewPager의 인터셉트 이벤트를 통제해 복잡한 충돌 처리도 가능.

---

Q6: 요약하면 어떻게 구현하는 게 좋은가?
A6:
1. HorizontalScrollView를 상속하여 커스텀 뷰를 생성.
2. onInterceptTouchEvent 또는 onTouchEvent에서 부모에 `requestDisallowInterceptTouchEvent(true)` 호출해 ViewPager의 이벤트 인터셉트를 막음.
3. 필요 시 수평과 수직 스크롤 구분하여 이벤트 처리를 세밀하게 제어.

---

이와 같은 방식을 사용하면 ViewPager 내부에서 HorizontalScrollView를 사용할 때 터치 이벤트 충돌 문제를 효과적으로 해결할 수 있습니다.
ViewPager와 HorizontalScrollView를 함께 사용할 때, 사용자 경험을 고려하여 어떻게 두 컴포넌트를 적절하게 조합할 수 있는지 알아보겠습니다.

이 두 컴포넌트를 함께 사용하려면 몇 가지 사항을 염두에 두어야 합니다.

기본 개념 1. ViewPager : 여러 페이지를 스와이프 할 수 있도록 하는 컴포넌트입니다.

각 페이지는 사용자 정의 뷰일 수 있습니다.



2. HorizontalScrollView : 수평 스크롤이 가능한 뷰 그룹으로, 여러 개의 뷰를 수평으로 배치할 수 있습니다.

문제점 ViewPager와 HorizontalScrollView를 동시에 사용할 경우, 스와이프 제스처와 스크롤 제스처가 충돌할 수 있습니다.

이러한 충돌을 해결하기 위해 터치 이벤트를 오버라이드하거나 조정해야 합니다.

해결 방법 구현 방법은 아래와 같습니다: 1. 커스텀 ViewPager 우선, 터치 이벤트를 적절히 관리하기 위해 Custom ViewPager를 정의합니다.

```java public class CustomViewPager extends ViewPager { private boolean isPagingEnabled = true; public CustomViewPager(Context context) { super(context); } public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return isPagingEnabled && super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { return isPagingEnabled && super.onTouchEvent(ev); } public void setPagingEnabled(boolean enabled) { this.isPagingEnabled = enabled; } } ```

2. HorizontalScrollView 내에서 스와이프 감지 HorizontalScrollView를 포함할 때, 스와이프와 스크롤을 구분하여 처리하기 위해 아래와 같이 터치 이벤트를 오버라이드합니다.

```java public class CustomHorizontalScrollView extends HorizontalScrollView { public CustomHorizontalScrollView(Context context) { super(context); } public CustomHorizontalScrollView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // 스크롤이 활성화되어있으면 ViewPager가 터치 이벤트를 가로채지 않도록 설정 getParent().requestDisallowInterceptTouchEvent(true); return super.onInterceptTouchEvent(ev); } } ```

3. XML 레이아웃 구성 Activity 또는 Fragment의 레이아웃 XML 파일에서 CustomViewPager와 CustomHorizontalScrollView를 사용합니다.

```xml ``` 최적화 및 테스트 - 위의 코드는 기본적인 설정을 보여줍니다.

실제 앱에서는 터치와 스와이프 제스처를 더 세밀하게 조정하여 사용자 경험을 개선해야 합니다.

- 다양한 기기에서 충분한 테스트를 진행하여, 터치 및 스와이프 동작이 자연스럽고 사용자의 기대에 부합하는지 확인합니다.

이와 같이 ViewPager와 HorizontalScrollView를 조합하여 사용할 수 있습니다.

적절한 이벤트 처리를 통해 두 컴포넌트를 원활하게 결합할 수 있습니다.

작성자: 박지민 [비회원] | 작성일자: 1년 전 2025-04-03 07:01:40
조회수: 125 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.