Custom Adapter를 사용하여 RecyclerView를 구현하는 방법을 설명합니다.
최초작성 2018. 7. 23
최종작성 2019. 8. 22
실행화면입니다. 데이터 추가 버튼을 눌러주면 아이템이 RecyclerView에 추가됩니다.
![](https://lh5.googleusercontent.com/hfWpVlWSZlEK3UKpymR7td3vq_tzKPh_QPqXrowkAZo4eWIZu_UnYwXgeEfI86hr1v1S_N_F0JRU5_33XoXoTVAbnDWKmvAh_J0hRBVmTqjyz-RRKKQ3hvWtYDu1av_hVkfoC3td)
화면 크기보다 많은 데이터가 추가되면 오른쪽에 스크롤바를 항상 보여주도록 했습니다.
관련 코드는 activity_main.xml에서 다음 두 줄 입니다.
android:scrollbarFadeDuration="0" android:scrollbarSize="5dp" |
![](https://lh5.googleusercontent.com/xQ6vBQm8tpS7YzdgwqjulFgM4uLPlAnMXuCWWevl44cSnEAOPyHpx7AVxMnf2IDZCEdMercsEJ3EQXpNJ0wFuXTcnag88B7jM2jLdU-kHARzeGO8Wrk1JBQcuMJk5WdAxq6YAQX9)
1. build.gradle (Module: app)
RecyclerView를 사용하려면 build.gradle에 androidx.recyclerview:recyclerview를 추가해야 합니다.
추가 후 오른쪽 위에 보이는 Sync Now를 클릭해야 프로젝트에 반영 됩니다.
![](https://lh3.googleusercontent.com/-tuvGJBS6QI3-N0WLpOI94kfvIThWir5zn6vMy5WDxUNm44TtHymVZzwA3Ru0EQcwRmYnkT5hJLjpu0kvlQLb3tBtCEssrR2XLm1lwilPoT78AqfVNC9UHb_0RZ8f6uyoKI8Ijss)
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에 아이템이 추가되도록 하기 위해 사용됩니다.
![](https://lh5.googleusercontent.com/uIdbhVNetb6J36sgFTBUgiqZW4UzDhlFM7BnH_5wJjzodnXT8DtTW3HX9FJx7zvmcXii2a4Jn5EDnrCjGo5e_hzY9rZLPRaiUoUIISw76jnVvt3EvqT7mE6MzwpfciExIzLh-wIh)
![](https://lh5.googleusercontent.com/bOJ1-ApO3BcUWW0ZwHuFcFwg15OoXDsJs3xm2KZai_BD-4Vsq8vVgw_YI1DGzTJya4XucjkTE2QjzEItwa6EYxuYOXwA3-uwWFZDyYt3lCAdo4sIoAhNd9sCjXqJ75uw4YMy26bF)
<?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 개수에 맞추어야 합니다.
![](https://lh3.googleusercontent.com/inIsaYa2Dhdwrw2fG5I772pkNXowTJXMUTr3k4KqGf3I_SBGRStAI1q7cOAWH5-57ZOL5SBUQU2iqKhOp7M9Hz0B1miK5NYYIpin2p1phUvpubww2WrOkrk2icgN7iRZmbQciPpx)
예제에서는 다음 3가지 데이터를 사용합니다.
package com.tistory.webnautes.userecyclerview;
public class Dictionary { private String id; private String English; private String Korean; } |
Getter, Setter 메소드, 생성자 메소드를 생성하는 방법을 설명합니다.
변수 선언 아래쪽 줄에 생성된 코드가 입력되도록 해당 위치에서 마우스 우클릭하여 보이는 메뉴에서 Generate를 선택합니다.
![](https://lh5.googleusercontent.com/0d0glNPqn48mb7musjYivbL3DfAlOjpw0rkJuC8UWT_NPPW748u3dUOU3OOVx3w2Pj2k6EZf18G0wMeZvmOa6JRZKTjJvmLv_dse0ndExwH-CTQ4EGKMSCtZ4DYmEp-QRW000F-y)
바로 보이는 메뉴에서 Getter and Setter를 선택합니다.
![](https://lh5.googleusercontent.com/S8EZmndRcek03YtPvknkPYRyx4wPCGhQiQs3anpQiT8Wp71j6aqMqRnMpQdekZDYpea5jYZN4BZD_tdDW-nUL0hLpYkhqzjD9ONwBFlyAoqLczVz6VFEQEtT94gcJPbg991mO3hZ)
Ctrl 키를 누른채 마우스 왼쪽 버튼으로 항목을 모두 선택합니다.
![](https://lh3.googleusercontent.com/W7FbcGnMtwFl0pvYZ2xesuBXo9tDKxXdyZCYJpjxqRWpLuvRypaeUaRiCWGWArNEfTUahDg6cv1z-CheJT5pVngr7x_e7Bhj1g7a2NfIw9jw1UaR9ifBSfN-bAR76v8KUN5evnvN)
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를 선택합니다.
![](https://lh3.googleusercontent.com/cn0u7FO054UWMpoIiMSQHu7LFpVSO3a1JhkHkpcqf8-iHnAGq67xFm4B7vvD0cBmEUFcPgoUT1fMKGlSedhkj3Cy9_k4a7JoFVeKBvT7E3Pvapr4-Zcj6ohVmLgqGB2QJUJRLmc-)
항목 3개를 모두 선택하고 OK버튼을 클릭합니다.
![](https://lh6.googleusercontent.com/9YgO00MBeXEexqAiOX2EzNZvzRwFEwRLCaGr75elqgpz6nuIzxzdqECK4tBvPw7-vXsnRT_8l46xsH767n5f0nU7LuVBbPEICGne9D0B4l7pLaUfB_5eZ_RuYji5lLO0HWOoocqc)
생성자가 추가되었습니다.
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