RecyclearView에서 FastScroll

13363 단어 RecyclerViewAndroid
ListView와 GridView(AbsListView)라면 레이아웃 XML에 아래와 같이 쓰면 된다.
<ListView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fastScrollEnabled="true" />
RecyclearView에서 이렇게 할 수 없는 상황이 오랫동안 지속되었다.
프로그램 라이브러리를 가져오려고 해도 결정판(개인 소감)이 나오지 않았다.
라고 생각했지만, 오랜만에 재조사해보니 서포트 리브레리 26에 API가 추가됐다.
https://developer.android.com/topic/libraries/support-library/revisions.html#26-0-0
New fastScrollEnabled boolean flag for RecyclerView. If enabled, fastScrollHorizontalThumbDrawable, fastScrollHorizontalTrackDrawable, fastScrollVerticalThumbDrawable, and fastScrollVerticalTrackDrawable must be set.

동작 이미지



샘플 코드 설치 요약
https://gist.github.com/75py/3b510a511d3d3231bc409e5517207818

설정 방법


Layout XML


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:fastScrollEnabled="true"
    app:fastScrollHorizontalThumbDrawable="@drawable/fast_scroll_thumb"
    app:fastScrollHorizontalTrackDrawable="@drawable/fast_scroll_track"
    app:fastScrollVerticalThumbDrawable="@drawable/fast_scroll_thumb"
    app:fastScrollVerticalTrackDrawable="@drawable/fast_scroll_track" />
  • android:fastScrollAlwaysVisible처럼 세밀하게 지정할 수 없기 때문에 AbsListView와 완전히 동일할 수 없습니다.
  • 가로세로 한 쪽으로만 굴러가도 Vertical/Horizontal 두 쪽의 지정이 필요하다(한 쪽이 부족하면 예외적으로 투척된다)
  • java.lang.IllegalArgumentException: Trying to set fast scroller without both required drawables.

    Drawable XML


    기본적으로 이렇게 하면 된다.
    fast_scroll_thumb.xml
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true">
            <shape android:shape="rectangle">
                <solid android:color="#f00" />
            </shape>
        </item>
        <item>
            <shape android:shape="rectangle">
                <solid android:color="#00f" />
            </shape>
        </item>
    </selector>
    
    fast_scroll_track.xml
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <solid android:color="#0f0" />
    </shape>
    
    나는 개인적으로 트랙의 투명함이 비교적 좋다고 생각한다.
    fast_scroll_track_transparent.xml
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <solid android:color="@android:color/transparent" />
    </shape>
    

    Drawable XML(개선 방안 API23 이후)


    ↑ 접촉의 범위가 매우 좁기 때문에 솔직히 사용하기 어렵다.
    소스만 보면 머지않아 Margin과 같은 값을 지정할 수 있고, 어쨌든 Drawable에 먼저 공을 들이면 접촉 범위를 확대할 수 있다.
    아래의 예에서도 아래 그림 8dp의 왼쪽 40dp를 만져 보았다.
    [2018/1/24 추기] 다음 예에서 API22 이하의 두루마리 폭은 48dp이다.(내 응용 프로그램은minSdkVersion=24이어서 눈치채지 못했다.)
    fast_scroll_thumb2.xml
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true">
            <layer-list>
                <item android:gravity="end">
                    <shape android:shape="rectangle">
                        <solid android:color="#f00" />
                        <size android:width="8dp" />
                    </shape>
                </item>
                <item>
                    <shape android:shape="rectangle">
                        <solid android:color="@android:color/transparent" />
                        <size android:width="48dp" />
                    </shape>
                </item>
            </layer-list>
        </item>
        <item>
            <layer-list>
                <item android:gravity="end">
                    <shape android:shape="rectangle">
                        <solid android:color="#00f" />
                        <size android:width="8dp" />
                    </shape>
                </item>
                <item>
                    <shape android:shape="rectangle">
                        <solid android:color="@android:color/transparent" />
                        <size android:width="48dp" />
                    </shape>
                </item>
            </layer-list>
        </item>
    </selector>
    

    Drawable XML(개선 시나리오 2)


    앞의 예에서 API22 이하에서는 함몰 폭이 48dp로 변경됩니다.
    (API22-23 사이에 XML의 해석 방법이 바뀌었지만 아직 이치를 찾지 못했다)
    변경점은 "gravity→left"뿐입니다.
    fast_scroll_thumb3.xml
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true">
            <layer-list>
                <item android:left="40dp">
                    <shape android:shape="rectangle">
                        <solid android:color="#f00" />
                        <size android:width="8dp" />
                    </shape>
                </item>
                <item>
                    <shape android:shape="rectangle">
                        <solid android:color="@android:color/transparent" />
                        <size android:width="48dp" />
                    </shape>
                </item>
            </layer-list>
        </item>
        <item>
            <layer-list>
                <item android:left="40dp">
                    <shape android:shape="rectangle">
                        <solid android:color="#00f" />
                        <size android:width="8dp" />
                    </shape>
                </item>
                <item>
                    <shape android:shape="rectangle">
                        <solid android:color="@android:color/transparent" />
                        <size android:width="48dp" />
                    </shape>
                </item>
            </layer-list>
        </item>
    </selector>
    

    좋은 웹페이지 즐겨찾기