Android 개발(11) : RecyclerView와 CardView

Myeong Ho Song
Android Develop & Android
13 min readJul 15, 2015

--

안드로이드 5.0 롤리팝이 업데이트 된 후, 여러가지 변화가 생겼습니다. 특히 이전까지는 리스트형태를 만들기 위해 사용했던 리스트뷰를 사용하고, 그리드 형태를 만들기 위해 사용했던 그리드뷰를 사용하였습니다. 이렇게 사용한 뷰들은 뷰 내의 아이템들을 동적으로 사용할 수 없다는 점에서 많이 불편했습니다.

5.0이 올라가면서(SDK21) RecyclerView가 등장하였는데 RecyclerView는 여러모습의 뷰들을 넣을 수 있는 예전에 등장한 뷰들보다 많이 동적입니다.

또한 리스트의 내부를 채울 때 카드를 많이 사용한 레이아웃이 구현되었는데 개인적으로 이런 레이아웃을 만들기 위해서 shape을 다르게 하여 주는 등의 방법으로 구현했었습니다. 이 또한 CardView라는 뷰를 추가함으로서 간단하게 쓸 수 있게 되었습니다.

이번 포스팅에는 이 두 뷰를 이용하여 이전의 리스트뷰와 같은 레이아웃을 만들어보겠습니다.

0. Library 추가

지금까지 썼던 뷰들과 다르게 두가지 뷰를 사용하려면 라이브러리를 추가하여야 됩니다. 구글이 이클립스의 지원을 종료하기로 하였기 때문에 안드로이드 스튜디오 기준으로 하겠습니다.

위와 같이 프로젝트 파일에서 오른쪽 마우스클릭 후 ‘Open Module Settings’를 클릭합니다.

그럼 아래와 같은 창이 뜨게 되는데 Dependencies 탭으로 이동합니다.

오른쪽 상단에 초록색으로 되어있는 +버튼을 클릭하면 3가지의 리스트가 보이는데 그중 최상위의 것인 Library dependency를 클립합니다.

위와 같은 창이 뜨면 cardview-v7(com.android.support:cardview-v7:22.2.0)과 recyclerview-v7(com.android.support:recyclerview-v7:22.2.0)를 찾아 추가를 합니다. 그리고 project structure창에서 ok를 클릭한 후 기다리면 두가지뷰를 사용할 수 있는 준비가 됩니다.

1. 레이아웃 구성

본 액티비티와 리스트에 들어갈 아이템 레이아웃 총 2종류의 레이아웃이 필요합니다.

우선 본액티비티 코드입니다. (activity_main.xml)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

다른 내용을 추가하지 않고 RecyclerView만 사용하였습니다.

다음은 리스트안에 들어갈 아이템에 대한 레이아웃입니다.(item_cardview.xml) 내부에 이미지와 텍스트를 넣는 형식으로 구성하였습니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/cardview"
card_view:cardCornerRadius="3dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="355dp"
android:layout_height="210dp"
android:id="@+id/image"/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="ddd"/>
</LinearLayout>
</android.support.v7.widget.CardView>

</LinearLayout>

cardview를 사용하였는데 cardview의 테두리를 둥글게 만들려면 card_view:cardCornerRadius인자를 cardview에 추가하면 됩니다. 이 때 car d_view는 xmlns:card_view=”http://schemas.android.com/apk/res-auto" 로 사용됩니다.

2. Activity 구현

recyclerview 또한 listview와 같은 방식으로 어댑터를 사용합니다.

우선 item에 대한 java코드를 보겠습니다.

public class Recycler_item {
int image;
String title;

int getImage(){
return this.image;
}
String getTitle(){
return this.title;
}

Recycler_item(int image, String title){
this.image=image;
this.title=title;
}
}

문자열과 이미지가 아이템에 들어가므로 두가지를 쓰시면 됩니다.

RecyclerView를 사용하는 액티비티에 대한 코드입니다.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

RecyclerView recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager=new LinearLayoutManager(getApplicationContext());
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);

List<Recycler_item> items=new ArrayList<>();
Recycler_item[] item=new Recycler_item[5];
item[0]=new Recycler_item(R.drawable.a,"#1");
item[1]=new Recycler_item(R.drawable.b,"#2");
item[2]=new Recycler_item(R.drawable.c,"#3");
item[3]=new Recycler_item(R.drawable.d,"#4");
item[4]=new Recycler_item(R.drawable.e,"#5");

for(int i=0;i<5;i++) items.add(item[i]);

recyclerView.setAdapter(new RecyclerAdapter(getApplicationContext(),items,R.layout.activity_main));
}

어댑터를 사용하므로 일반적인 사용 구조는 ListView와 많이 비슷합니다. 하지만 LayoutManiger를 사용한다는 부분이 다릅니다. LayoutManager를 현재 액티비티의 context를 받아서 사용하고, RecyclerView에 이 layoutmanager를 연결해줍니다.

LinearLayoutManager layoutManager=new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);

다음은 어댑터입니다. 어댑터는 RecyclerView.Adapter<(만든 어댑터 이름).ViewHolder>를 상속받습니다.

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
Context context;
List<Recycler_item> items;
int item_layout;
public RecyclerAdapter(Context context, List<Recycler_item> items, int item_layout) {
this.context=context;
this.items=items;
this.item_layout=item_layout;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cardview,null);
return new ViewHolder(v);
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Recycler_item item=items.get(position);
Drawable drawable=context.getResources().getDrawable(item.getImage());
holder.image.setBackground(drawable);
holder.title.setText(item.getTitle());
holder.cardview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context,item.getTitle(),Toast.LENGTH_SHORT).show();
}
});
}

@Override
public int getItemCount() {
return this.items.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
TextView title;
CardView cardview;

public ViewHolder(View itemView) {
super(itemView);
image=(ImageView)itemView.findViewById(R.id.image);
title=(TextView)itemView.findViewById(R.id.title);
cardview=(CardView)itemView.findViewById(R.id.cardview);
}
}
}

ViewHolder는 사용 시, 사용하지 않았을 때 findviewById를 계속해서 사용해야되는 것을 막습니다. RecyclerView의 어댑터에서는 이런 viewHolder를 바로 사용하도록 해두었습니다. viewholder에는 item xml에 있던 뷰들을 불러주면 됩니다.

onCreateViewHolder에서는 ViewHolder를 불러줍니다. 그리고 onBindViewHolder에서는 액티비티에서 불러왔던 데이터를 아이템에 넣어주는 코드를 작성하면 됩니다.

RecyclerView의 경우 listview에 있었던 OnitemclickListner가 존재하지 않으므로 같은 형식으로 쓰고 싶다면 아이템의 전체를 아우르는 뷰에 Onclicklistener를 걸어줍니다.

RecyclerView를 이용하게 되면 이런 리스트뷰뿐만아니라 그리드뷰도 만들 수 있고, 여러 뷰들이 들어간 레이아웃또한 만들 수 있습니다. 다른 포스팅에서 리스트뷰뿐만 아니라 다른 뷰들을 추가하는 방법을 알아보겠습니다.

이번 포스팅에 쓰인 코드는 아래 주소로 가면 받아서 사용할 수 있습니다.

https://github.com/songmho/RecyclerView

--

--