RecyclerView란 무엇일까요?
본격적인 예제에 들어가기 전에, 안드로이드에서 RecyclerView가 무엇인지 먼저 짚고 넘어가겠습니다. RecyclerView는 ListView의 한층 발전된 형태로, ViewHolder 디자인 패턴을 기반으로 동작하는 안드로이드의 핵심 UI 컴포넌트입니다. RecyclerView를 활용하면 그리드 형태와 리스트 형태의 아이템을 모두 효율적으로 표시할 수 있습니다.
이번 글에서는 학생의 이름과 나이를 표시하는 학생 기록 앱을 직접 만들어 보면서, RecyclerView 각 항목에 랜덤 배경색을 설정하는 방법을 단계별로 알아보겠습니다.
1단계 — 새 프로젝트 만들기
Android Studio에서 File → New Project로 이동한 뒤, 새 프로젝트 생성에 필요한 정보를 모두 입력하여 프로젝트를 생성합니다.
2단계 — build.gradle에 RecyclerView 라이브러리 추가
build.gradle 파일을 열고 RecyclerView 라이브러리 의존성을 추가합니다.
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.andy.tutorialspoint"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:recyclerview-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}3단계 — activity_main.xml 레이아웃 작성
res/layout/activity_main.xml 파일에 다음 코드를 추가합니다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</RelativeLayout>위 코드에서는 RelativeLayout을 부모 레이아웃으로 삼아 RecyclerView를 화면에 배치했습니다.
4단계 — MainActivity.java 작성
src/MainActivity.java 파일에 다음 코드를 작성합니다.
package com.example.andy.tutorialspoint;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private StudentAdapter studentAdapter;
private List<studentData> studentDataList =new ArrayList<>();
@TargetApi(Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recycler_view);
studentAdapter=new StudentAdapter(studentDataList);
RecyclerView.LayoutManager manager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(studentAdapter);
StudentDataPrepare();
}
@RequiresApi(api = Build.VERSION_CODES.N)
private void StudentDataPrepare() {
studentData data=new studentData("sai",25);
studentDataList.add(data);
data=new studentData("sai",25);
studentDataList.add(data);
data=new studentData("raghu",20);
studentDataList.add(data);
data=new studentData("raj",28);
studentDataList.add(data);
data=new studentData("amar",15);
studentDataList.add(data);
data=new studentData("bapu",19);
studentDataList.add(data);
data=new studentData("chandra",52);
studentDataList.add(data);
data=new studentData("deraj",30);
studentDataList.add(data);
data=new studentData("eshanth",28);
studentDataList.add(data);
Collections.sort(studentDataList, new Comparator() {
@Override
public int compare(studentData o1, studentData o2) {
return o1.name.compareTo(o2.name);
}
});
}
}위 코드에서는 RecyclerView를 초기화하고 StudentAdapter를 연결했습니다. 어댑터에는 ArrayList 형태의 studentDataList를 전달했으며, 이 리스트에는 학생의 이름과 나이 정보가 담겨 있습니다.
RecyclerView 아이템을 정렬하기 위해 Collections 프레임워크의 sort 메서드를 다음과 같이 활용했습니다.
Collections.sort(studentDataList, new Comparator<studentData>() {
@Override
public int compare(studentData o1, studentData o2) {
return o1.name.compareTo(o2.name);
}
});위 코드는 이름(name)을 기준으로 리스트의 요소들을 비교하고 정렬합니다.
5단계 — StudentAdapter.java 작성
다음은 수정된 src/StudentAdapter.java 파일의 내용입니다.
package com.example.andy.tutorialspoint;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
import java.util.Random;
class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.MyViewHolder> {
List<studentData> studentDataList;
public StudentAdapter(List<studentData> studentDataList) {
this.studentDataList=studentDataList;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.student_list_row, viewGroup, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder viewHolder, int i) {
studentData data=studentDataList.get(i);
Random rnd = new Random();
int currentColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
viewHolder.parent.setBackgroundColor(currentColor);
viewHolder.name.setText(data.name);
viewHolder.age.setText(String.valueOf(data.age));
}
@Override
public int getItemCount() {
return studentDataList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView name,age;
LinearLayout parent;
public MyViewHolder(View itemView) {
super(itemView);
parent=itemView.findViewById(R.id.parent);
name=itemView.findViewById(R.id.name);
age=itemView.findViewById(R.id.age);
}
}
}어댑터 클래스에는 아래와 같이 네 가지 핵심 요소가 있습니다.
onCreateViewHolder() — 뷰 홀더를 생성하고 해당 뷰를 반환하는 메서드입니다.
onBindViewHolder() — 생성된 뷰 홀더에 데이터를 바인딩하는 메서드입니다.
getItemCount() — 리스트의 크기를 반환하는 메서드입니다.
MyViewHolder 클래스 — RecyclerView.ViewHolder를 상속하는 내부 클래스로, 뷰 홀더 역할을 수행합니다.
RecyclerView 항목에 랜덤 배경색을 적용하기 위해, 안드로이드에 미리 정의되어 있는 Random 클래스로 무작위 색상을 생성한 뒤, 아래 코드와 같이 뷰 아이템의 부모 레이아웃(parent)에 색상을 지정했습니다.
Random rnd = new Random(); int currentColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)); viewHolder.parent.setBackgroundColor(currentColor);
6단계 — student_list_row.xml 작성
다음은 수정된 res/layout/student_list_row.xml 파일의 내용입니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:weightSum="1"
android:layout_height="wrap_content">
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_weight="0.5"
android:gravity="center"
android:textSize="15sp"
android:layout_height="100dp" />
<TextView
android:id="@+id/age"
android:layout_width="0dp"
android:layout_weight="0.5"
android:gravity="center"
android:textSize="15sp"
android:layout_height="100dp" />
</LinearLayout>위 리스트 아이템 뷰에는 이름과 나이를 각각 표시하는 두 개의 TextView를 배치했습니다.
7단계 — studentData.java 작성
다음은 수정된 src/studentData.java 파일의 내용입니다.
package com.example.andy.tutorialspoint;
class studentData {
String name;
int age;
public studentData(String name, int age) {
this.name=name;
this.age=age;
}
}위 코드는 학생 데이터 객체(studentData)를 정의합니다. 이제 애플리케이션을 실행해 보겠습니다. 실제 안드로이드 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바의 Run 아이콘을 클릭하세요. 모바일 기기를 선택하면 기기 화면에 아래와 같은 기본 화면이 표시됩니다.

위 결과에서 알파벳 순(A부터)으로 정렬된 데이터와 함께 각 항목마다 서로 다른 랜덤 배경색이 적용된 것을 확인할 수 있습니다. 이제 아래로 스크롤하면 다음과 같은 결과가 나타납니다.
