리사이클러뷰(RecyclerView)는 "사용자가 관리하는 많은 수의 데이터 집합을 개별 아이템 단위로 구성하여 화면에 출력하는 뷰그룹이며, 제한된 영역 내에서 유연하게 표시할 수 있도록 만들어 주는 위젯"이다.
리사이클러뷰(RecyclerView)는 리스트뷰와 유사한 기능을 가지고 있는데 유연함과 성능이 더해졌다. 구글에서도 리스트UI를 구성할 때 리스트뷰보단 리사이클러뷰를 권고한다.
리사이클러뷰(RecyclerView) 워크플로우
- 메인액티비티에 리사이클러뷰 추가
- 아이템 뷰 레이아웃 추가
- 리사이클러뷰 어댑터 구현
- 어댑터, 레이아웃 매니저 지정
리사이클러뷰(RecyclerView) 구성요소
*1. 리사이클러뷰 *
- 사용자 데이터를 리스트 형태로 화면에 표시하는 컨테이너 역할을 수행
2. 어댑터
- 리사이클러뷰에 표시될 아이템 뷰를 생성하는 역할을 담당. 데이터로부터 아이템 뷰를 만드는 역할을 함.
3. 레이아웃매니저
- 레이아웃매니저는 리사이클러뷰가 아이템을 화면에 표시할 때, 아이템 뷰들이 어떤 형태로 배치되는지 관리하는 역할을 함.
4. 뷰 홀더
-
화면에 표시될 아이템 뷰를 저장하는 객체
-
어댑터에 의해 관리되는데, 필요에 따라 어댑터에서 생성.
[실습하기]
[ExpandableListAdapter.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
public class ExpandableListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int HEADER = 0;
public static final int CHILD = 1;
private List<Item> data;
public ExpandableListAdapter(List<Item> data) {
this.data = data;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int type) {
View view = null;
Context context = parent.getContext();
float dp = context.getResources().getDisplayMetrics().density;
int subItemPaddingLeft = (int) (18 * dp);
int subItemPaddingTopAndBottom = (int) (5 * dp);
switch (type) {
case HEADER:
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_header, parent, false);
ListHeaderViewHolder header = new ListHeaderViewHolder(view);
return header;
case CHILD:
TextView itemTextView = new TextView(context);
itemTextView.setPadding(subItemPaddingLeft, subItemPaddingTopAndBottom, 0, subItemPaddingTopAndBottom);
itemTextView.setTextColor(0x88000000);
itemTextView.setLayoutParams(
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
return new RecyclerView.ViewHolder(itemTextView) {
};
}
return null;
}
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Item item = data.get(position);
switch (item.type) {
case HEADER:
final ListHeaderViewHolder itemController = (ListHeaderViewHolder) holder;
itemController.refferalItem = item;
itemController.header_title.setText(item.text);
if (item.invisibleChildren == null) {
itemController.btn_expand_toggle.setImageResource(R.drawable.ic_launcher_background);
} else {
itemController.btn_expand_toggle.setImageResource(R.drawable.ic_launcher_background);
}
itemController.btn_expand_toggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (item.invisibleChildren == null) {
item.invisibleChildren = new ArrayList<Item>();
int count = 0;
int pos = data.indexOf(itemController.refferalItem);
while (data.size() > pos + 1 && data.get(pos + 1).type == CHILD) {
item.invisibleChildren.add(data.remove(pos + 1));
count++;
}
notifyItemRangeRemoved(pos + 1, count);
itemController.btn_expand_toggle.setImageResource(R.drawable.ic_launcher_background);
} else {
int pos = data.indexOf(itemController.refferalItem);
int index = pos + 1;
for (Item i : item.invisibleChildren) {
data.add(index, i);
index++;
}
notifyItemRangeInserted(pos + 1, index - pos - 1);
itemController.btn_expand_toggle.setImageResource(R.drawable.ic_launcher_background);
item.invisibleChildren = null;
}
}
});
break;
case CHILD:
TextView itemTextView = (TextView) holder.itemView;
itemTextView.setText(data.get(position).text);
break;
}
}
@Override
public int getItemViewType(int position) {
return data.get(position).type;
}
@Override
public int getItemCount() {
return data.size();
}
private static class ListHeaderViewHolder extends RecyclerView.ViewHolder {
public TextView header_title;
public ImageView btn_expand_toggle;
public Item refferalItem;
public ListHeaderViewHolder(View itemView) {
super(itemView);
header_title = (TextView) itemView.findViewById(R.id.header_title);
btn_expand_toggle = (ImageView) itemView.findViewById(R.id.btn_expand_toggle);
}
}
public static class Item {
public int type;
public String text;
public List<Item> invisibleChildren;
public Item() {
}
public Item(int type, String text) {
this.type = type;
this.text = text;
}
}
}
|
cs |
[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
36
37
|
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerview = findViewById(R.id.recyclerview);
recyclerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
List<ExpandableListAdapter.Item> data = new ArrayList<>();
ExpandableListAdapter.Item places = new ExpandableListAdapter.Item(ExpandableListAdapter.HEADER, "음수");
places.invisibleChildren = new ArrayList<>();
places.invisibleChildren.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "-1"));
places.invisibleChildren.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "-2"));
places.invisibleChildren.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "-3"));
places.invisibleChildren.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "-4"));
data.add(places);
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.HEADER, "짝수"));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "2"));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "4"));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "6"));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.HEADER, "홀수"));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "1"));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "3"));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "5"));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "7"));
recyclerview.setAdapter(new ExpandableListAdapter(data));
}
}
|
cs |
[activity_main.xml]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<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" android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp" tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
|
cs |
[list_header.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
|
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:paddingLeft="13dp"
android:paddingStart="13dp"
android:paddingRight="10dp"
android:paddingEnd="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/header_title"
android:textColor="#000000"
android:textSize="18sp"
android:gravity="center_vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<ImageView
android:id="@+id/btn_expand_toggle"
android:src="@drawable/ic_launcher_background"
android:layout_width="30dp"
android:layout_height="30dp"
/>
</LinearLayout>
|
cs |
*버튼 이미지는 원하는 아이콘 다운 받아서 사용하시면 됩니다.*
Reference
https://dreamaz.tistory.com/223
반응형
'Mobile > 안드로이드' 카테고리의 다른 글
[안드로이드/android] 파파고 API 안드로이드에서 사용하기(papago api) (0) | 2020.07.21 |
---|---|
[안드로이드/android] jsoup을 이용해 웹 크롤링하기 (동행복권 당첨 숫자 가져오기) (8) | 2020.06.25 |
[안드로이드/android] 레이아웃과 속성 (0) | 2020.06.18 |
[안드로이드/android] 시작하기 (1) | 2020.06.16 |