RecyclerView
일단 recyclerView는 여러 정보들을 item으로 묶어서 각각 표시해주는 그런 것 같다. 예를 들어서 받은 이메일들이 위아래로 쭉 정렬돼있는 것 등을 구현할 때 사용되는 거 같다.
recyclerView를 사용하기 위해서 build.gradle (:app)에 dependencies {}에
implementation 'androidx.recyclerview:recyclerview:1.2.1' 을 추가해서 그 토대를 만들어줬다.
1 메인 activity layout 만들기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:scrollbarFadeDuration="0"
android:scrollbarSize="5dp"
android:scrollbarThumbVertical="@android:color/darker_gray"
android:scrollbars="vertical">
</androidx.recyclerview.widget.RecyclerView>
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/btn_add"
android:layout_weight="8"
android:text="추가"/>
|
cs |
recyclerview를 위한 위젯을 만들고 (1~10)
Button을 만들어서 recyclerview에 item들을 추가할 수 있게 했다. (12~17)
2 item layout 만들기
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
|
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/iv_profile"
android:src="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="mandu"
android:id="@+id/tv_name"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="예에에ㅔ"
android:id="@+id/tv_content"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
|
cs |
그 결과로 밑의 사진과 같은 결과를 만들었다.
3 MainData 즉 Data를 쉽게 저장하는 class 만들기
1
2
3
4
5
6
7
8
9
10
11
12
|
public MainData(int iv_profile, String tv_name, String tv_content) {
this.iv_profile = iv_profile;
this.tv_name = tv_name;
this.tv_content = tv_content;
}
public int getIv_profile() {
return iv_profile;
}
public void setIv_profile(int iv_profile) {
this.iv_profile = iv_profile;
}
...
|
cs |
1~5 이 class를 객체화할 때 세 가지의 정보를 parameter로 받아서 저장한다.
6~11에서 get.~~~, set~~~ 함수를 통해서 정보를 반환하거나 저장한다. 다른 정보에 대해서도 똑같은 함수를 만들었다.
4 adapter 만들기
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
|
private ArrayList<MainData> arrayList;
public MainAdapter(ArrayList<MainData> arrayList) { // 이 객체를 생성할 때 arrayList를 받아오게한다.
this.arrayList = arrayList;
}
@NonNull
@org.jetbrains.annotations.NotNull
@Override // 아까만든 item layout을 이용해서 정보를 담을 ViewHolder을 만든다. 그 viewHolder은 CustomViewHolder이라는 이름으로 저 밑에서 정의한다.
public MainAdapter.CustomViewHolder onCreateViewHolder(@NonNull @org.jetbrains.annotations.NotNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
CustomViewHolder holder = new CustomViewHolder(view);
return holder;
}
@Override //holder 안의 데이터를 실질적으로 저장한다.
public void onBindViewHolder(@NonNull @org.jetbrains.annotations.NotNull MainAdapter.CustomViewHolder holder, int position) {
holder.iv_profile.setImageResource(arrayList.get(position).getIv_profile()); //arrayList에서 받아온 정보를 holder에 저장한다.
holder.tv_name.setText(arrayList.get(position).getTv_name());
holder.tv_content.setText(arrayList.get(position).getTv_content());
holder.itemView.setTag(position);
holder.itemView.setOnClickListener(new View.OnClickListener() { //터치를 했을 때 toast를 뜨게 만든다.
@Override
public void onClick(View view) {
String curName = holder.tv_name.getText().toString();
Toast.makeText(view.getContext(), curName, Toast.LENGTH_SHORT).show();
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { //길게 눌렀을 때 밑에 구현 remove()함수를 실행시킨다.
@Override
public boolean onLongClick(View view) {
remove(holder.getAdapterPosition());
return true;
}
});
}
@Override
public int getItemCount() { // arrayList의 원소 갯수를 반환한다. 오류를 막기위해 arrayList가 null일 때는 0을 반환한다.
return (null != arrayList ? arrayList.size() : 0);
}
public void remove(int position) { //position에 있는 원소를 제거한다. 오류 가능성이 높은 작업이기에 try catch문으로 방지한다.
try {
arrayList.remove(position);
notifyItemRemoved(position); //새로 고침
} catch (IndexOutOfBoundsException ex) {
ex.printStackTrace();
}
}
public class CustomViewHolder extends RecyclerView.ViewHolder { //ViewHoldet을 정의한다.
protected ImageView iv_profile;
protected TextView tv_name;
protected TextView tv_content;
public CustomViewHolder(@NonNull @NotNull View itemView) { // 이 class를 객체화된 View인 itemView를 parameter로 받고 그의 위젯들을 연결해준다.
super(itemView);
this.iv_profile = (ImageView) itemView.findViewById(R.id.iv_profile);
this.tv_name = (TextView) itemView.findViewById(R.id.tv_name);
this.tv_content = (TextView) itemView.findViewById(R.id.tv_content);
}
}
|
cs |
이 class는 RecyclerView.Adapter<MainAdapter.CustomViewHolder>을 상속한다.
adapter에 꼭 구현되어야 할 것은
먼저 onCreateViewHolder()을 이용해서 viewHolder을 만들어서 반환해야 한다. (7~16)
그 holder의 정의는 따로 class를 만들어서 할 수도 있다. holder은 LayoutInflater을 이용해서 layout xml파일을
View 객체로 만들어서 그 객체의 저장할 데이터들을 변수로 만들고 View객체의 위젯에 연결해줘야 한다. (59~71)
그 후에는 onBindViewHolder()을 이용해서 holder에 정보를 저장한다던가 상호작용을 정의해준다거나 하는 것을 해야 한다. (18~43)
그리고 getItemCount() 함수를 정의해서 item의 수를 반환하게 해야 한다. (45~48)
arrayList()로 정보를 전달받고 저장하는 것이 필수는 아닌 것 같지만 편하기에 보통 그렇게 쓰는 것 같다. 그렇기에
className()으로 생성자를 정의해서 parameter로 arrayList를 받아오는 것도 중요한 것 같다. (3~5)
그리고 부가적인 것들로는 remove() 함수 정도인 것 같다.
5 MainActivity class 만들기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
recyclerView = (RecyclerView)findViewById(R.id.rv); //만들어놓은 위젯이랑 연결
linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
arrayList = new ArrayList<>(); //배열 만들기
mainAdapter = new MainAdapter(arrayList); //adapter 객체화
recyclerView.setAdapter(mainAdapter); //위젯에 adapter 설정
Button btn_add = (Button)findViewById(R.id.btn_add); //버튼 눌렀을 때 이벤트
btn_add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MainData mainData = new MainData(R.mipmap.ic_launcher, "mandu", "예에에ㅔ"); //MainData의 형태로 정보를 저장
arrayList.add(mainData); //배열에 정보 추가
mainAdapter.notifyDataSetChanged(); //새로고침 (적용)
}
});
|
cs |
2 앞에서 만들었던 recyclerView 위젯을 변수에 저장해줬다.
3~4 그리고 각각의 item들을 어떤 식으로 나열할지 정하기 위해서 linearLayoutManager을 만들고 recyclerView에 추가해준다. (defealt값이 vertical인 것이고 바꾸고 싶다면 linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL) 이런 식으로 바꾸면 된다.)
6~9 adapter을 만들기 위해서 배열을 만들고 아까 만든 adapter class를 객체화해서 변수에 저장해준다. 그리고 그것을 recyclerView에 추가해준다.
11~19 버튼을 눌렀을 때 이벤트를 설정해줬다. 아까 만든 mainData class를 이용해서 정보를 저장해주고 그것을 배열에 넣어준다. 그 배열에 추가한 것을 적용하기 위해서 mainAdapter을 새로고침 해준다.
그렇게 하면 밑의 사진과 같이 추가 버튼을 누르면 item들이 하나씩 늘어나고 item을 오래 누르면 그 item은 없어질 것이다. 그리고 저 item에 다른 정보를 넣고 싶다면 바로 위의 코드에서 MainData class를 객체화하는 부분에서 그 원하는 정보를 넣는다면 적용될 것이다.
'Android App' 카테고리의 다른 글
RecyclerViewWithEditText in Android Studio (0) | 2021.08.02 |
---|---|
Fragment 전환 in Android Studio (0) | 2021.08.02 |
camera, startActivityForResult() 대체, intent.resolveActivity(getPackageManager()) return null in Android Studio (0) | 2021.08.02 |
webViewWithEditText in Android Studio (0) | 2021.08.02 |
sharedPreferences, webView, Navigation in Android Studio (0) | 2021.07.19 |