일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 프래그먼트
- 끝말잇기
- 캐치마인드
- 커스텀린트
- 1일1커밋
- 리얼하다
- 테트리스
- 아비투스
- 한달독서
- 목적중심리더십
- 재택근무
- 베드트레이
- 소프시스
- T자형인재
- 좌식테이블
- 한달브런치북만들기
- 한단어의힘
- 베드테이블
- 어떻게 나답게 살 것인가
- 슬기로운 온라인 게임
- 소프시스 밤부 좌식 엑슬 테이블
- 안드로이드
- 자취필수템
- 브런치작가되기
- 한달어스
- 면접
- 북한살둘레길
- 지지않는다는말
- 목적 중심 리더십
- 함수형 프로그래밍
- Today
- Total
정상에서 IT를 외치다
[Android, Double Scroll] 이중 스크롤 어떻게 구성하면 좋을까? 본문
안녕하세요. 블랙진입니다.
ScrollView 안에 ListView 혹은 RecyclerView 가 있는 이중 스크롤에 관한 포스팅입니다.
cf) 제가 사용한 RecyclerView 예제는 이 링크에서 받을 실 수 있습니다.
1. 처음 생각이 드는 ScrollView 안에 RecyclerView 구조
preview
xml code
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:background="@android:color/holo_blue_bright"
android:layout_width="match_parent"
android:layout_height="300dp">
<TextView
android:layout_centerInParent="true"
android:text="BlackJin Tistory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
ScrollView 안에는 자식뷰를 단 1개만 가질 수 있습니다. 이에 LinearLayout 을 설정하여 TextView 1개 있는 레이아웃과 그 아래 RecyclerView를 달아보았습니다. 어떻게 동작을 할까요?
BlcakJin Tistory 부분을 스크롤 하면 ScrollVIew 가 동작되고 RecyclerView 를 스크롤 하게 되면 RecyclerView 의 스크롤이 움직입니다.
1. 처음 앱을 시작 할 때 상단뷰의 일부가 가려저 있습니다. (리사이클러뷰의 일부가 위로 올라와 있다)
이는 RecycleView 에서 아이템을 그리는 과정에서 아이템에 포커싱이 되어 ScrollView 가 말려 올라가는 현상입니다. 리사이클러뷰로 가는 포커싱을 막아줌으로서 해결할 수 있습니다.
<!-- 자식뷰의 포커싱을 막아주는 blocksDescendants 를 추가해 줍니다. -->
<LinearLayout
android:descendantFocusability="blocksDescendants"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:descendantFocusability
Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.
Must be one of the following constant values.
Constant | Value | Description |
---|---|---|
afterDescendants | 1 | The ViewGroup will get focus only if none of its descendants want it. |
beforeDescendants | 0 | The ViewGroup will get focus before any of its descendants. |
blocksDescendants | 2 | The ViewGroup will block its descendants from receiving focus. |
AndroidVIewGroup - blacksDescendants
2. ScrollView 와 RecyclerView 의 스크롤이 따로따로 동작한다.
이중 스크롤에서 가장 큰 문제가 바로 각각의 스크롤이 따로 동작한다는 것입니다. 이를 알아서 해결해 주는 NestedScrollView 를 사용해 주면 됩니다.
NestedScrollView 에 관한 구글 문서에는 이렇게 적혀 있습니다.
NestedScrollView is just like ScrollView
, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. Nested scrolling is enabled by default.
ScrollView 와 동작은 같으나 부모와 자식 둘다 중첩된 스크롤링 액션을 지원해준다!
동작원리에 관해 궁금하신 분은 이에 관한 영문 포스터가 있으니 참고해 주세요.
3. Solution
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:descendantFocusability="blocksDescendants"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:background="@android:color/holo_blue_bright"
android:layout_width="match_parent"
android:layout_height="300dp">
<TextView
android:layout_centerInParent="true"
android:text="BlackJin Tistory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
두가지 Solution을 모두 적용해 위와 같이 작업해 주면 이중 스크롤뷰 안에 리사이클러뷰를 구현 하실 수 있습니다.
cf) 이중 스크롤뷰 안에 리사이클러 뷰를 사용하게 되면 리사이클러뷰는 아이템을 전부 미리 생성하게 됩니다. (RecyclerView Adapter 의 onBindViewHolder 에서 로그를 찍어보시면 확인하실 수 있습니다.) 또한 Item View 를 재활용 하지 않기 때문에 View 를 재사용하여 메모리 효율을 높일 수 있다는 리사이클러뷰의 큰 이점을 잃어버리게 되니 꼭 참고해서 사용해 주셔야 합니다. 아이템이 많은 경우에는 사용을 지양합니다.
'안드로이드' 카테고리의 다른 글
[Android, Kotlin] 코틀린의 run, with, apply, let, also 정리 (0) | 2019.03.18 |
---|---|
[Android, Dagger2] ContributesAndroidInjector 사용해보기 (2) | 2019.03.17 |
[Android, TargetVersion 28] TargetVersion 28 에 따른 조치 사항 (2) | 2019.03.06 |
[Android, MVP, Dagger] MVP 기본 예제 - Dagger 사용하기 (0) | 2019.02.08 |
[Android, MVP, Room] MVP 기본 예제 - Room 활용 (0) | 2019.02.07 |