안드로이드에서 ListView를 수평으로 나타낼 수 있나요?
조회수 8080회
리스트뷰를 수평으로 나타내는게 가능한가요? Gallery view를 사용해서 하긴했는데 그걸 쓰면 각 항목을 선택하면 자동으로 화면 가운데로 와요. 이 문제를 어떻게 해결하죠 제 생각엔 ListView를 수평으로 출력하면 될것같은데 가능할까요?
1 답변
-
안드로이드 최신버전이 나오면서 기존 리스트뷰의 문제를 개선한 RecyclerView가 나왔는데요. RecyclerView를 이용하면 수평으로 나타낼수있습니다.
리사이클러뷰의 장점 :
- RecyclerView의 어댑터에서 뷰홀더 패턴을 자동으로 구현해준다.
- 애니메이션을 구현하기가 쉽다.
- 더 많은 형태를 제공한다.
주요 클래스
- Adapter – 기존의 ListView에서 사용하는 Adapter와 같은 개념으로 데이터와 아이템에 대한 View생성
- ViewHolder – 재활용 View에 대한 모든 서브 뷰를 보유
- LayoutManager – 아이템의 항목을 배치
- ItemDecoration – 아이템 항목에서 서브뷰에 대한 처리
- ItemAnimation – 아이템 항목이 추가, 제거되거나 정렬될때 애니메이션 처리
LayoutManager
RecyclerView에서 가장 흥미로운 부분이다. RecyclerView를 생성시 반드시 생성되어야 하며 이를 통해 모든 아이템의 뷰의 레이아웃을 관리한다. 수평/수직 배치 뿐만아니라 그리드형태의 다양하게 레이아웃을 배치 할 수 있다.
기본적으로 제공하는 LayoutManager
- LinearLayoutManager – 수평/수직의 스크롤 리스트
- GridLayoutManager – 그리드 리스트
- StaggeredGridLayoutManage – 높이가 불구칙적인 형태의 그리드 리스트
이외에 개발자는 LayoutManager를 확장하여 다양한 형태를 만들 수 있다. 아래와 같이 사용한다.
LinearLayoutManager layoutManager = new LinearLayoutManager(context); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); layoutManager.scrollToPosition(currPos); recyclerView.setLayoutManager(layoutManager);
ViewHolder
ViewHolder는 기존의 ListView에서 많이 사용하고 구글 안드로이드 팀에서도 오랫동안 추천 된 패턴이다. 하지만 이를 사용하는 것을 강제적으로 제한하지 않았지만 RecyclerView에서는 Adapter와 ViewHolder를 반듯이 같이 사용 할 수 밖에 없는 구조로 바꼈다. ViewHolder패턴을 사용 하지 않은 개발자는 약간의 훈련이 필요 할것이다.
public final static class ListItemViewHolder extends RecyclerView.ViewHolder { TextView label; TextView dateTime; public ListItemViewHolder(View itemView) { super(itemView); label = (TextView) itemView.findViewById(R.id.txt_label_item); dateTime = (TextView) itemView.findViewById(R.id.txt_date_time); } }
사용법은 ViewHolder를 확장 후 서브 클래스를 findViewById()를 통해 저장해놓으면 된다. 이렇게 함으로 한번 생성한 클래스를 통해 서브 클래스(뷰)를 빠르게 다시 액세스 할 수 있다.
Adapter
ListView에서 Adpater와 동일한 형태의 구조로 해당 아이템의 데이터와 뷰간의 처리를 한다. 다음과 같은 3가지의 인터페이스를 구현해야 한다.
- public ListItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
- 제네릭 형식의 변수로 ViewHolder를 생성
- public void onBindViewHolder(ListItemViewHolder holder, int position)
- 만들어진 ViewHolder에 데이터를 넣는 작업, ListView의 getView()와 동일
public int getItemCount()
- 데이터의 갯수 ```java public class RecyclerViewDemoAdapter extends RecyclerView.Adapter {
private List items;
RecyclerViewDemoAdapter(List modelData) { if (modelData == null) { throw new IllegalArgumentException( "modelData must not be null"); } this.items = modelData; }
@Override public ListItemViewHolder onCreateViewHolder( ViewGroup viewGroup, int viewType) { View itemView = LayoutInflater. from(viewGroup.getContext()). inflate(R.layout.item_demo_01, viewGroup, false); return new ListItemViewHolder(itemView, viewType); }
@Override public void onBindViewHolder( ListItemViewHolder viewHolder, int position) { DemoModel model = items.get(position); viewHolder.label.setText(model.label); String dateStr = DateUtils.formatDateTime( viewHolder.label.getContext(), model.dateTime.getTime(), DateUtils.FORMAT_ABBREV_ALL); viewHolder.dateTime.setText(dateStr); }
@Override public int getItemCount() { return items.size(); }
public final static class ListItemViewHolder extends RecyclerView.ViewHolder { // ViewHolder } }
기존의 ListView와 동일한 구조라서 쉽게 구현이 가능하며, Adapter의 기본 클래스를 확장한 형태(CursorAdapter, ArrayAdapter)는 없다.
댓글 입력