[android] ListView 에서 RecyclerView 로 migration 하세요. |
http://andraskindler.com/2014/11/22/migrating-to-recyclerview/
-
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 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 을 조정하면 된다.
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 로 전환하는 것은 약간의 노력이 들지만 그럴만 하다.
결과는 훨씬 유연하고 강력하기 때문이다.
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] ContentProviderOperation 에 대한 짧은 이야기 (0) | 2017.04.15 |
---|---|
[Java Concurrency] 스레드 안전성 (2) | 2017.04.14 |
[Android] Overview screen 을 꾸며보세요. (0) | 2017.04.11 |
[Android] Material Design 개략적으로 알아보기~ (0) | 2017.04.10 |
[Java] Executor : Java Concurrency API (0) | 2017.03.08 |
댓글