Hello,

kok nae-ga ha-myun an-dweneun MAGIC...🧚

안드로이드

RecyclerView 사용하기 + Click 이벤트

✿도담도담 2018. 4. 30. 00:21

listview란 listview는 다 써본듯 하다..

이번에는 RecyclerView이다.


RecyclerView는 ListView보다 좀더 유연하게 다양한 형태의 커스텀마이징을 할 수 있는 장점이 있다.

ViewHolder라는 친구를 사용하여 Item에 대한 뷰의 변형 또는 애니메이션을 추가 할 수 있다.


나는 기존 listView에서 크게 커스텀이나 애니메이션에 관해 불편해서 바꿨다기 보다..

Coordinary Layout의 NestedScrollView안에 Expandable ListView를 사용하는 중에

작동은 되나 버벅거리고 원활한 기능을 수행하지 못해 다시 ListView로 돌아가려고 하니

둘다 스크롤 기능으로 인해 제대로 구현이 되지 않아 방법을 찾던 중에 접했다. 😣


RecyclerView도 이전의 ListView들과 비슷하나

ViewHolder라는 친구를 사용하는 것이 추가 되었다.

ViewHolder를 찾아 보니 말 그대로 홀더에 뷰를 꼽아놓은듯 보관하는 객체라고 한다.


RecyclerView를 구현하기 까지

1. layout.xml

2. item.xml

3. ListViewItemData.java

4. RecyclerViewAdapter.java

5. ViewHolder.java 

( 나는 4번을 어댑터 안에 내부 클래스로 선언해 주었다. )

이렇게 총 5가지가 필요했다.


우선 항상 가장 첫번째로 했던, layout에 RecyclerView의 위치와

각각 item들의 layout을 ( custom item ) 만들어주자.

( item은 이전 게시글과 같은 형태이므로 ( 그리고 기니까.. ) 생략하겠다. 원하는데로 커스텀 해주면된다. )

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_mainpage">

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.widget.NestedScrollView>


다음은 ListViewItemData다.

DAO처럼 custom item에 해당하는 get/set 메소드로 이루어져 있다.

원하는 데이터를 설정하지 않고 나오는지 테스트만 해주겠다 하면

클래스만 생성해주면 된다.

이 또한 간단하므로 생략하겠다.


아래는 어댑터 부분이다.

주석으로 설명을 달아 놨다.

이때 각각의 아이템에 클릭 이벤트를 준 부분이 onBindViewHolder 메소드 이다.


ViewHolder 클래스에 implement 해주어도 된다.

각각의 아이템을 누르면 몇번째 아이인지 Toast로 출력 테스트를 해주었다.

// RecyclerView 어댑터
// ViewHolder : 뷰들을 홀더에 꼽아놓듯 보관하는 객체
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{

private ArrayList<ListViewItemData> listViewItems;
private int itemLayout;

/**
* 생성자
* @param items
* @param itemLayout
*/
public RecyclerViewAdapter(ArrayList<ListViewItemData> items , int itemLayout){

this.listViewItems = items;
this.itemLayout = itemLayout;
}

/**
* 레이아웃을 만들어서 Holer에 저장
* 뷰 홀더를 생성하고 뷰를 붙여주는 부분
* @param viewGroup
* @param viewType
* @return
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

View view = LayoutInflater.from(viewGroup.getContext()).inflate(itemLayout,viewGroup,false);
return new ViewHolder(view);
}

/**
* 넘겨 받은 데이터를 화면에 출력하는 역할
* 재활용 되는 뷰가 호출하여 실행되는 메소드
* 뷰 홀더를 전달하고 어댑터는 position 의 데이터를 결합
* @param viewHolder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {

ListViewItemData item = listViewItems.get(position);

// 값 설정 ( set )

//Here it is simply write onItemClick listener here
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
Toast.makeText(context, position +"", Toast.LENGTH_LONG).show();
}
});
}

@Override // 데이터 수 반환
public int getItemCount() {
return listViewItems.size();
}

class ViewHolder extends RecyclerView.ViewHolder {

public final View mView;
public ViewHolder(View itemView) {
super(itemView);
mView = itemView;

// 레이아웃 객체화 findViewById
}
}
}



그리고 메인에 간편하게 선언하기 위해 따로 RecyclerView 클래스를 만들어 주었다.

따로 클래스를 만들지 않고 사용하고 싶다면

기존의 ListView를 선언하듯 Main에서 adapter 생성 설정 해주면 된다.


public class RecyclerListView {

private RecyclerView recyclerView;
private RecyclerViewAdapter adapter;
private ArrayList<ListViewItemData> listViewItems;

public RecyclerListView(Context context, View view)
{
listViewItems = new ArrayList<ListViewItemData>();
adapter = new RecyclerViewAdapter(listViewItems, R.layout.group_listview);


recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(context.getApplicationContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());

}

// Default 값, 테스트 용
public void addItem()
{
ListViewItemData listViewItem = new ListViewItemData();
listViewItems.add(listViewItem);
}
}


이렇게 따로 클래스를 만들었다면 액티비티에 아래와 같이면 적어주면 된다 :)


RecyclerListView recyclerListView = new RecyclerListView(getContext(), view);
recyclerListView.addItem();



실행 화면 이다 !

해당 item들이 들어있는 Arraylist의 index값이 Toast로 출력 된다 👀👍