본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] ListView 에서 RecyclerView 로 migration 하세요.

by 돼지왕 왕돼지 2017. 4. 13.
반응형

 [android] ListView 에서 RecyclerView 로 migration 하세요.


http://andraskindler.com/2014/11/22/migrating-to-recyclerview/

adapter, adding, BaseAdapter, baseexpandableadapter, changing, childview, Click, click event, Container, control, custom background drawable, customize, data, DIVIDER, dividers, expandablelistview, fading edge, findchildviewunder, getcount, GetItem, getitemcount, getitemid, getitemoffsets, getitemviewtype, getView, getviewtypecount, google, gridlayoutmanager, Gridview, handling clicks, Headers, Highlight, Horizontal, item animation, itemanimator, itemdecoration, large data set, LayoutManager, linearlayoutmanager, listview, mapping, measuring, migration, Moving, onbindviewholder, oncreateviewholder, onitemclicklistener, OnLongClickListener, OnTouchListener, optional, other properties, outrect, overscrollmode, padding, Position, positioning, recyclerview, recyclerview.adapter, recycling, removing, rendering, ScrollBar, scrolling, setdivider, setdividerheight, sethasfixedsize, staggeredgridlayoutmanager, staggeredgridview, sticky header, subclass, support, support library, swiperefreshlayout, type, vertical, View, viewholder, viewtype, window, [Android] ListView 에서 RecyclerView 로 migration 하세요., 개발자, 방향설정


-
Google 에서도 RecyclerView 을 Support library 에 넣으면서 ListView 를 대체하려는 움직임을 보이고 있다.
RecyclerView 는 새롭고, 효율적이고, customize 하기에도 좋다.
ListView 뿐만 아니라 GridView, StaggeredGridView, ExpandableListView 역시 모두 migration 가능하다.



RecyclerView and LayoutManager


RecyclerView 는 제한된 수의 window 를 이용하여 large data set 을 display 하기 위한 유연성 있는 view 이다.
RecyclerView 는 단순 container 이고, adapter 를 이용하여 rendering 을 할 뿐이다.


방향설정을 비롯한 여러가지 설정은 개발자의 몫이다.

LayoutManager 가 이 여러 가지 설정들에 대한 내용을 담고 있다.
LayoutManager 는 childview 의 positioning, measuring, recycling 등을 담당한다.
LinearLayoutManager 를 사용하면 기본 ListView 를 흉내낼 수 있다.

LayoutManager 는 vertical, horizontal 의 2가지 scrolling 을 갖는다.


android.support.v7.widget.RecyclerView 를 붙였으면 어떤 LayoutManager 를 사용할지 결정해야 한다.

ListView 나 ExpandableListView -> LinearLayoutManager
GridView -> GridLayoutManager
StaggeredGridView -> StaggeredGridLayoutManager ( 비규칙 listing )

cf) setHasFixedSize(true) 를 호출하면 RecyclerView 의 size 변환이 없기 때문에 성능상 좋다.



BaseAdapter vs. RecyclerView.Adapter


BaseAdapter 나 BaseExpandableAdapter 대신 RecyclerView.Adapter 를 상속해야 한다.
BaseAdpater 나 BaseExpandableAdapter 는 ViewHolders 를 따로 정의하여 가지고 있어야 하지만,
RecyclerView.Adapter 는 관련 함수들을 가지고 있어 따로 구현하는 수고가 적다.

이전의 getCount() 는 getItemCount() 로 변형되었다.

getItemID() 가 이전에는 무조건 있어야 하는 함수였는데, 지금은 optional 이다.

getItem(int position) 에 매핑되는 함수는 없다.

getView() 는 ViewHolder 를 이용하여 recycling 하는 역할을 맡았었다.
이것이 RecyclerView.Adapter 에서는 2개의 함수로 분리가 되었다.
onCreateViewHolder() 가 ViewHolder 를 만들고,
onBindViewHolder() 가 data 를 view 에 붙이는 역할을 한다.

좋은 소식은 이제 직접 recycling 을 control 할 일이 적어졌다는 것이다.



Handling Clicks


RecyclerView 에는 OnItemClickListener 나 OnLongClickListener 를 달 수 없다.
Adapter 가 click event 를 직접 handling 해야 한다.


public static class ViewHolder extends RecyclerView.ViewHolder {
    public View view;
    public Item currentItem;

    public ViewHolder(View v) {
        super(v);
        view = v;
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 //...
            }
        });
    }
}


혹은 onTouchListener 를 RecyclerView 에 붙인 후, findChildViewUnder(float x, float y) 를 통해 찾을 수도 있다.



ViewType Handling


item type 에 관련된 것은 이전과 별로 변함이 없다.

getItemViewType(int position) 이 position 과 type 을 mapping 한다.
하지만 getViewTypeCount() 를 구현할 필요는 없다.


Adapter 가 알아서 onBindViewHolder() 에 적절한 ViewHolder 를 전달할 것이기 때문이다.
물론 onCreateViewHolder() 함수의 2번째 parameter 가 ViewType 을 말한다는 것을 알고 제대로 return 해주는 것은 필요하다.





Dividers and padding


Divider 설정은 기존 ListView의 setDivider() 나 setDividerHeight() 함수를 호출하는 것보다 조금 더 많은 작업이 필요하다.
RecyclerView.ItemDecoration 의 sub class 가 필요하기 때문이다.


item 의 padding 값 조정만이 필요하다면 getItemOffsets() 함수를 override 하여 outRect param 을 조정하면 된다.

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    private int padding;

    public DividerItemDecoration(int padding) {
        this.padding = padding;
     }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.left += padding; outRect.right += padding;
    }
}




Headers


header 를 추가하는 것은 매우 쉽다.
ViewType 을 이용하여 그냥 교체만 하면 된다.

Sticky header 는 이를 참조하자.
https://github.com/timehop/sticky-headers-recyclerview



SwipeRefreshLayout


android.support.v4.widget.SwipeRefreshLayout 를 이용하면 된다.



Item Animation


ListView 는 box 바깥쪽으로의 animation 을 support 하지 않는다. ( 정말 복잡한 작업을 통해서만 가능하다. )

하지만 RecyclerView.ItemAnimator 를 사용하면 이를 매우 쉽게 할 수 있다.
adding, removing, changing, moving 에 대한 animation 은 매우 쉽다.



Other Properties


scrollbar, overscrollmode, fading edge 는 이전과 같다.
click 에 따른 highlight 도 역시 이전과 같다. custom background drawable 을 줄 수도 있다.



Summary


ListView 종류에서 RecyclerView 로 전환하는 것은 약간의 노력이 들지만 그럴만 하다.
결과는 훨씬 유연하고 강력하기 때문이다.





반응형

댓글