(210518 수정)
리사이클러뷰(RecyclerView)는 안드로이드 개발을 할 때에 굉장히 많이 사용된다.
왜냐하면 가장 많이 사용되는 UI의 모양들 중 하나이기 때문이다.
이전에 게시했던 채팅앱만 봐도 리사이클러뷰로 구현했다는 것을 알 수 있을 것이다.
기본적으로 사용되는 ListView와 비슷하지만 ListView의 기능에 추가적으로
레이아웃 설정도 자유롭고(유연성 증가), 효율성도 더 좋다(성능 발전).
RecyclerView가 어떤 것인지 간단하게 알아보고
이에 대한 구현 방법을 알아보겠다.
우선 리사이클러뷰(RecyclerView)란 무엇인가?
첫 번째,
언뜻 보면 비슷해보이지만
RecyclerView가 ListView와 다른 점은 재활용, 즉 재사용을 할 수 있다는 뷰라는 점에서
차이점을 보인다. 재사용을 하면 어떻게 다를까?
이전에 올린 채팅앱을 예시로 설명해보자.
예를 들어
100개의 채팅 메시지가 있고 화면에는 10개의 채팅 메시지만 보인다.
(채팅앱에서의 뷰 객체라고 하면 보통 말풍선을 나타내는 아이템 뷰이다.)
여기서 ListView는,
사용자가 스크롤을 위아래로 움직이면 맨 위에 있는 뷰 객체가 삭제되고
맨 아래에 새롭게 뷰 객체가 생성되는 것을 수 십번 수 백번 그 이상의 갱신을 반복하게 된다.
이렇게 되면 결과적으로
성능을 저하시키게 되는 요인이 된다.
하지만 RecyclerView는?
맨 위의 뷰 객체를 삭제하지 않고 맨 아래로 이동시켜
재사용(Recycle)을 한다.
하지만 뷰 객체 자체를 재사용하는 것일뿐,
뷰 객체가 가지고 있는 데이터는 새롭게 만들어진다.
화면에 10개의 채팅 메시지만 보이면 되기 때문에
몇 백 몇 천개의 채팅 메시지 데이터가 있든 말든
결국 뷰 객체는 10개만 있으면 된다.
두 번째,
레이아웃을 보다 유연하게 설정할 수 있다.
수직으로만 가능했던 ListView 한계점을 극복하고
RecyclerView에서는 수평도 가능하다.
이 부분은 LayoutManager라는 객체를 사용해서 설정하는데,
아래 코드들에서 다뤄볼 것이다.
-----------------------------------------------------------------------------------------
이제부터 RecyclerView를 간단하게 구현하면서 알아보자.
이번에는 카카오톡 같은 채팅앱의 채팅창 화면이 아닌
채팅할 친구목록을 구현해 볼 것이다.
먼저, 메인 친구목록(RecyclerView) 화면을 보여주는 activity_main.xml부터 작성해보자.
activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
|
<?xml version="1.0" encoding="utf-8"?>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
|
cs |
간단하게 RecyclerView만 구현해볼 것이기 때문에 (아직은 껍데기 상태의) RecyclerView만 넣는다.
그리고 친구목록을 보여주는 각 친구의 간단프로필을 list_item.xml로 만들건데,
이것은 어댑터의 인플레이션을 통해 뷰 객체가 될 것이다.
list_item.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/item_line">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv"
android:layout_width="77dp"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1">
<TextView
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="이름"
android:textSize="40sp" />
<TextView
android:id="@+id/tvStmsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="상태 메시지"
android:textSize="25sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
|
cs |
아이템에 테두리를 만들어주고 코너를 둥글게 한다.
1
2
3
4
5
6
7
8
|
<?xml version="1.0" encoding="utf-8"?>
<stroke android:width="1dp" />
<corners
android:radius="15dp" />
</shape>
|
cs |
</shape>

그 다음으로는 친구목록의 데이터 정보를 담고 있는 Friends.java 라는 모델을 만든다.
Friends.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package com.example.recyclerviewtest;
public class Friends {
String name; // 이름
String stateMsg; // 상태메시지
int resId; // 이미지 아이디
public Friends(String name, String stateMsg, int resId) {
this.name = name;
this.stateMsg = stateMsg;
this.resId = resId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStateMsg() {
return stateMsg;
}
public void setStateMsg(String stateMsg) {
this.stateMsg = stateMsg;
}
public int getResId() {
return resId;
}
public void setImageView(int resId) {
this.resId = resId;
}
}
|
cs |
|
|
처음에 만들었던 activity_main.xml에서의 RecyclerView는 껍데기에 불과하다.
이 RecyclerView를 실제로 화면에 보여지게 하려면
어댑터(Adapter)를 통해서 데이터와 연결을 해야한다.
FriendsAdapter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
public class FriendsAdapter extends RecyclerView.Adapter<FriendsAdapter.ViewHolder> {
ArrayList<Friends> items = new ArrayList<Friends>(); // 아이템 리스트, 여러 아이템을 어댑터가 관리해야하기 때문에 어레이 리스트형 변수 선언
@NonNull
@Override // 리사이클러뷰에서 보여지는 여러 개의 아이템은 내부에서 캐시되기 때문에 아이템 갯수만큼 객체가 만들어지는 것은 아님
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());// 인플레이션을 하려면 Context 객체가 필요한데 뷰 그룹 객체의 getContext()를 이용하면 Context 참조 가능함함
View itemView = inflater.inflate(R.layout.list_item, parent, false); // 뷰 그룹 객체는 각 아이템 뷰를 위한 뷰 그룹 객체이므로 xml을 인플레이션하여 이 뷰그룹 객체에 설정
return new ViewHolder(itemView); // 뷰홀더 객체를 생성하면서 뷰 객체를 전달하고 그 뷰홀더 객체를 반환
}
@Override // 뷰홀더가 재사용될 때 호출되므로 뷰 객체는 기존 것을 그대로 사용하고 데이터만 바꿔줌
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Friends item = items.get(position); // 재활용 가능한 뷰홀더 객체를 파라미터로 전달하기 때문에 그 뷰홀더에 맞는 현재 아이템에 맞는 데이터만 설정(현재 몇 번째 것이 보여야 되는 시점인가)
holder.setItem(item); // 핸들러에 아이템을 설정
}
@Override
public int getItemCount() { // 어댑터가 관리하는 아이템의 갯수를 알아야 할 때 사용
return items.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvName;
TextView tvStmsg;
ImageView iv;
public ViewHolder(@NonNull View itemView) { // 뷰홀더 생성자로 전달되는 뷰 객체를 참조함(아이템들은 뷰로 만들어지고, 뷰는 뷰홀더에 담아둠)
super(itemView); // 이 뷰 객체를 부모 클래스의 변수에 담아둠
// 뷰 객체에 들어 있는 텍스트뷰를 참조함
tvName = itemView.findViewById(R.id.tvName);
tvStmsg = itemView.findViewById(R.id.tvStmsg);
iv= itemView.findViewById(R.id.iv);
}
public void setItem(Friends item) {
tvName.setText(item.getName());
tvStmsg.setText(item.getStateMsg());
iv.setImageResource(item.getResId());
}
}
// 이 어댑터가 아이템을 위한 Friends 객체를 어레이 리스트 안에 넣어 관리하기 때문에
// 이 어댑터를 사용하는 소스코드에서 어댑터에 Friends 객체를 넣거나 가져갈 수 있도록 아래의 메소드들을 추가
public void addItem(Friends item) {
items.add(item); // 어레이 리스트에다 아이템 추가
}
public void setItems(ArrayList<Friends> items) {
this.items = items;
}
public void getItem(int position) {
items.get(position);
}
public void setItem(int position, Friends item) {
items.set(position, item);
}
}
|
cs} |
어댑터를 통해서 아이템 뷰와 데이터를 연결했다면
MainActivity 클래스에서
어댑터의 addItem() 메서드를 이용해 Friends 객체를 추가한다.
MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); // 리니어 레이아웃 매니저를 생성해서 레이아웃 방향을 설정함(vertical)
recyclerView.setLayoutManager(layoutManager); // 리사이클러뷰에 레이아웃 매니저 객체 설정-> 리니어 레이아웃으로 설정됨
FriendsAdapter adapter = new FriendsAdapter(); // 리사이클러뷰와 어댑터 상호작용
// 어댑터에 아이템을 추가함(Friends 객체의 이름, 상태 메시지, 프로필 이미지)
adapter.addItem(new Friends("하빌리즘", "안녕하세요", R.drawable.flower));
adapter.addItem(new Friends("비둘기", "gugugu", R.drawable.gugu));
adapter.addItem(new Friends("하빌리즘", "안녕하세요", R.drawable.flower));
adapter.addItem(new Friends("비둘기", "gugugu", R.drawable.gugu));
adapter.addItem(new Friends("하빌리즘", "안녕하세요", R.drawable.flower));
adapter.addItem(new Friends("비둘기", "gugugu", R.drawable.gugu));
adapter.addItem(new Friends("하빌리즘", "안녕하세요", R.drawable.flower));
adapter.addItem(new Friends("비둘기", "gugugu", R.drawable.gugu));
adapter.addItem(new Friends("하빌리즘", "안녕하세요", R.drawable.flower));
adapter.addItem(new Friends("비둘기", "gugugu", R.drawable.gugu));
adapter.addItem(new Friends("하빌리즘", "안녕하세요", R.drawable.flower));
adapter.addItem(new Friends("비둘기", "gugugu", R.drawable.gugu));
adapter.addItem(new Friends("하빌리즘", "안녕하세요", R.drawable.flower));
adapter.addItem(new Friends("비둘기", "gugugu", R.drawable.gugu));
adapter.addItem(new Friends("하빌리즘", "안녕하세요", R.drawable.flower));
adapter.addItem(new Friends("비둘기", "gugugu", R.drawable.gugu));
recyclerView.setAdapter(adapter); // 리사이클러뷰에 어댑터를 설정함
}
}
|
cs} |
간단하게 RecyclerView에 대해서 알아보았는데
개인적으로 많은 공부가 되었고,
보시는 분들에게 조금이나마 도움이 되셨으면 좋겠다.
피드백은 언제나 환영입니다.
'프로그래밍(programming) > 안드로이드(android)' 카테고리의 다른 글
안드로이드 스크롤뷰(ScrollView)로 화면 스크롤하기 (210423) (0) | 2021.04.23 |
---|---|
안드로이드 페이지 슬라이딩(Page Sliding) (210421) (0) | 2021.04.21 |
안드로이드 채팅 (3/3) - 채팅 기능 (210415) (0) | 2021.04.15 |
안드로이드 채팅 (2/3) - 채팅 화면 (210414) (0) | 2021.04.14 |
안드로이드 채팅 (1/3) - 로그인과 회원가입(210414) (0) | 2021.04.14 |