Custom Adapter를 사용하여 RecyclerView를 구현하는 방법을 설명합니다.
최초작성 2018. 7. 23
최종작성 2019. 8. 22
실행화면입니다. 데이터 추가 버튼을 눌러주면 아이템이 RecyclerView에 추가됩니다.
화면 크기보다 많은 데이터가 추가되면 오른쪽에 스크롤바를 항상 보여주도록 했습니다.
관련 코드는 activity_main.xml에서 다음 두 줄 입니다.
android:scrollbarFadeDuration="0" android:scrollbarSize="5dp" |
1. build.gradle (Module: app)
RecyclerView를 사용하려면 build.gradle에 androidx.recyclerview:recyclerview를 추가해야 합니다.
추가 후 오른쪽 위에 보이는 Sync Now를 클릭해야 프로젝트에 반영 됩니다.
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.recyclerview:recyclerview:1.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } |
2. activity_main.xml
레이아웃에 RecyclerView와 버튼을 추가했습니다.
버튼은 누를 때 마다 RecyclerView에 아이템이 추가되도록 하기 위해 사용됩니다.
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerview_main_list" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintVertical_weight="9" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/button_main_insert" android:scrollbarFadeDuration="0" android:scrollbarSize="5dp" android:scrollbarThumbVertical="@android:color/darker_gray" android:scrollbars="vertical"/>
<Button android:id="@+id/button_main_insert" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintVertical_weight="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/recyclerview_main_list" android:text="데이터 추가"/>
</androidx.constraintlayout.widget.ConstraintLayout> |
3. item_list.xml
layout 폴더에 추가합니다. RecyclerView의 한 줄에 세 개의 컬럼을 보여주기 위해 사용됩니다.
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" tools:context=".MainActivity">
<TextView android:id="@+id/id_listitem" android:layout_width="0dp" app:layout_constraintHorizontal_weight="1" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/english_listitem" app:layout_constraintHorizontal_chainStyle="spread" android:padding="5dp" android:textAlignment="center" android:text="123" android:textStyle="bold"/>
<TextView android:id="@+id/english_listitem" android:layout_width="0dp" app:layout_constraintHorizontal_weight="2" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@id/id_listitem" app:layout_constraintRight_toLeftOf="@id/korean_listitem" android:padding="5dp" android:layout_margin="10dp" android:textAlignment="center" android:text="english" android:textStyle="bold"/>
<TextView android:id="@+id/korean_listitem" android:layout_width="0dp" app:layout_constraintHorizontal_weight="2" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toRightOf="@id/english_listitem" android:padding="5dp" android:layout_margin="10dp" android:textAlignment="center" android:text="phone" android:textStyle="bold" />
</androidx.constraintlayout.widget.ConstraintLayout> |
4. Dictionary.java
RecyclerView의 한 줄에 보여줄 데이터를 클래스로 선언합니다. item_list.xml에서 정의한 TextView 개수에 맞추어야 합니다.
예제에서는 다음 3가지 데이터를 사용합니다.
package com.tistory.webnautes.userecyclerview;
public class Dictionary { private String id; private String English; private String Korean; } |
Getter, Setter 메소드, 생성자 메소드를 생성하는 방법을 설명합니다.
변수 선언 아래쪽 줄에 생성된 코드가 입력되도록 해당 위치에서 마우스 우클릭하여 보이는 메뉴에서 Generate를 선택합니다.
바로 보이는 메뉴에서 Getter and Setter를 선택합니다.
Ctrl 키를 누른채 마우스 왼쪽 버튼으로 항목을 모두 선택합니다.
Getter, Setter 메소드가 추가되었습니다.
package com.tistory.webnautes.userecyclerview;
public class Dictionary {
private String id; private String English; private String Korean;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getEnglish() { return English; }
public void setEnglish(String english) { English = english; }
public String getKorean() { return Korean; }
public void setKorean(String korean) { Korean = korean; } } |
코드가 입력될 위치에서 마우스 우클릭하여 보이는 메뉴에서 Generate를 선택합니다. 그리고 바로 보이는 메뉴에서 Constructor를 선택합니다.
항목 3개를 모두 선택하고 OK버튼을 클릭합니다.
생성자가 추가되었습니다.
package com.tistory.webnautes.userecyclerview;
public class Dictionary {
private String id; private String English; private String Korean;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getEnglish() { return English; }
public void setEnglish(String english) { English = english; }
public String getKorean() { return Korean; }
public void setKorean(String korean) { Korean = korean; }
public Dictionary(String id, String english, String korean) { this.id = id; English = english; Korean = korean; } } |
5. CustomAdapter.java
ArrayList에 있는 Dictionary 클래스 타입의 데이터를 RecyclerView에 보여주는 처리를 합니다.
package com.tistory.webnautes.endlessloading;
import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private ArrayList<Dictionary> mList;
public class CustomViewHolder extends RecyclerView.ViewHolder { protected TextView id; protected TextView english; protected TextView korean;
public CustomViewHolder(View view) { super(view); this.id = (TextView) view.findViewById(R.id.id_listitem); this.english = (TextView) view.findViewById(R.id.english_listitem); this.korean = (TextView) view.findViewById(R.id.korean_listitem); } }
public CustomAdapter(ArrayList<Dictionary> list) { this.mList = list; }
@Override public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.item_list, viewGroup, false);
CustomViewHolder viewHolder = new CustomViewHolder(view);
return viewHolder; }
@Override public void onBindViewHolder(@NonNull CustomViewHolder viewholder, int position) {
viewholder.id.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25); viewholder.english.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25); viewholder.korean.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
viewholder.id.setGravity(Gravity.CENTER); viewholder.english.setGravity(Gravity.CENTER); viewholder.korean.setGravity(Gravity.CENTER);
viewholder.id.setText(mList.get(position).getId()); viewholder.english.setText(mList.get(position).getEnglish()); viewholder.korean.setText(mList.get(position).getKorean()); }
@Override public int getItemCount() { return (null != mList ? mList.size() : 0); }
}
|
6. MainActivity.java
package com.tistory.webnautes.endlessloading;
import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.view.View; import android.widget.Button; import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private ArrayList<Dictionary> mArrayList; private CustomAdapter mAdapter; private int count = -1;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview_main_list); LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(mLinearLayoutManager);
mArrayList = new ArrayList<>();
mAdapter = new CustomAdapter( mArrayList); mRecyclerView.setAdapter(mAdapter);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), mLinearLayoutManager.getOrientation()); mRecyclerView.addItemDecoration(dividerItemDecoration);
Button buttonInsert = (Button)findViewById(R.id.button_main_insert); buttonInsert.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {
count++;
Dictionary data = new Dictionary(count+"","Apple" + count, "사과" + count);
//mArrayList.add(0, dict); //RecyclerView의 첫 줄에 삽입 mArrayList.add(data); // RecyclerView의 마지막 줄에 삽입
mAdapter.notifyDataSetChanged(); } });
}
} |
관련 포스트
Android RecyclerView 아이템 클릭 이벤트 구현
https://webnautes.tistory.com/1300
Android RecyclerView에 데이터를 추가/편집/삭제하는 예제
https://webnautes.tistory.com/1222