RecyclerView란?
RecyclerView란 기본적으로 여러 가지 아이템을 나타내는 면에서는 ListView와 비슷하다.
하지만 ListView의 경우 위 아래 수직 방향으로만 아이템을 배열할 수가 있다.
아이템을 좌우 방향으로 스크롤하여 보여주고 싶다면 RecyclerView를 사용하면 된다.
RecyclerView는 이렇게 좌우 방향 스크롤 뿐만 아니라 ListView에 비해 좀 더 확장 가능한 기능을 제공한다.
따라서 ListView와 같은 단순한 형태보다 조금 더 복잡한 기능이 필요할 때 사용하면 된다.
또한 RecyclerView는 ViewHolder를 기본적으로 사용하게 되어있다.
ViewHolder란 아이템을 스크롤하여 뷰를 띄워줄 때 매번 inflate하지 않고 저장해두고 사용하기 위한 객체이다.
그럼 이제 사용법을 알아보자.
※ 이 글은 안드로이드 API 29 버전을 기준으로 구현하였으며 androidx.recyclerview를 사용하였습니다.
사용법
implementation 'androidx.recyclerview:recyclerview:1.1.0'
먼저 build.gradle에서 dependencies에 RecyclerView를 import 해준다.
package com.juhy.myapplication;
public class Customer {
public String name;
public String phone;
public Customer(String name, String phone) {
this.name = name;
this.phone = phone;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:textColor="#0000FF"
android:text="Name" />
<TextView
android:id="@+id/tv_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="#FF0000"
android:text="Phone" />
</LinearLayout>
먼저 아이템 하나의 정보를 담는 클래스와 이에 대응하는 레이아웃 파일을 만들어준다.
package com.juhy.myapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CustomerAdapter extends RecyclerView.Adapter<CustomerAdapter.ViewHolder>{
Context context;
ArrayList<Customer> items = new ArrayList<Customer>();
public CustomerAdapter(Context context){
this.context = context;
}
@Override
public int getItemCount() {
return items.size();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.customer_item, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Customer item = items.get(position);
holder.setItem(item);
}
public void addItem(Customer item){
items.add(item);
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_name;
TextView tv_phone;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tv_name = itemView.findViewById(R.id.tv_name);
tv_phone = itemView.findViewById(R.id.tv_phone);
}
public void setItem(Customer item){
tv_name.setText(item.name);
tv_phone.setText(item.phone);
}
}
}
이제 ListView와 마찬가지로 데이터와 RecyclerView를 이어줄 Adapter를 만들어주자.
Adapter는 다음과 같은 순서로 동작하게 된다.
1. 아이템이 보여지면 ViewHolder가 생성되며 레이아웃 파일을 inflate 한다. (onCreate)
2. ViewHolder 생성자에서 findViewById를 통해 View들을 inflate 한다.
3. ViewHolder와 아이템이 연결되며 View들에 데이터를 설정한다. (onBind)
따라서 이에 따라 다음 메소드들을 정의해주면 된다.
CustomerAdapter() - 생성자 호출 시 Context를 넘겨준다.
getItemCount() - 아이템의 수를 반환해준다.
onCreateViewHolder() - ViewHolder가 만들어지는 시점 / 레이아웃을 inflate
onBindViewHolder() - ViewHolder와 아이템이 연결되는 시점 / ViewHolder에 아이템 지정
ViewHolder() - 아이템 레이아웃의 View들을 findViewById를 통해 객체화
ViewHolder.setItem() - 아이템 레이아웃의 View들의 값을 설정
package com.juhy.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);
CustomerAdapter adapter = new CustomerAdapter(getApplicationContext());
adapter.addItem(new Customer("Mark", "010-1234-5678"));
adapter.addItem(new Customer("Ted", "010-1111-2222"));
adapter.addItem(new Customer("JuHy", "010-1212-3434"));
recyclerView.setAdapter(adapter);
}
}
Activity에서는 먼저 findViewById()를 통해 RecyclerView를 찾아준다.
그리고 LayoutManager를 통해 아이템들을 보여줄 형식을 지정해준다.
LinearLayoutManager.HORIZONTAL은 좌우 형태로 아이템들을 보여주는 형태이다.
그리고 Adapter를 생성하여 데이터를 추가해 준 뒤 RecyclerView에 지정해주면 된다.
실행해보면 좌우 스크롤을 통해 아이템이 나타나는 것을 볼 수 있다.
OnItemClickListener 추가하기
RecyclerView.Adapter에는 setOnItemClickListener()가 정의되어 있지 않기 때문에 직접 구현해야 한다.
OnItemClickListener listener;
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
public static interface OnItemClickListener{
public void onItemClick(ViewHolder holder, View view, int position);
}
먼저 OnItemClickListener interface와 이를 설정할 setOnItemClickListener() 함수를 만들어주자.
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Customer item = items.get(position);
holder.setItem(item);
holder.setOnItemClickListener(listener);
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_name;
TextView tv_phone;
OnItemClickListener listener;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tv_name = itemView.findViewById(R.id.tv_name);
tv_phone = itemView.findViewById(R.id.tv_phone);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = getAdapterPosition();
if(listener != null){
listener.onItemClick(ViewHolder.this, v, position);
}
}
});
}
public void setItem(Customer item){
tv_name.setText(item.name);
tv_phone.setText(item.phone);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
}
그리고 ViewHolder 클래스 내에 setOnItemClickListener() 메소드를 만들어 listener를 입력받도록 한 뒤,
생성자에서 원하는 View에 setOnClickListener()를 통해 클릭 시 onItemClick을 실행시켜준다.
마지막으로 onBind 시 ViewHolder에 setOnItemClickListener()를 통해 listener를 등록시켜주면 된다.
adapter.setOnItemClickListener(new CustomerAdapter.OnItemClickListener() {
@Override
public void onItemClick(CustomerAdapter.ViewHolder holder, View view, int position) {
Customer item = adapter.getItem(position);
Toast.makeText(getApplicationContext(), item.name + " clicked", Toast.LENGTH_SHORT).show();
}
});
이제 액티비티로 돌아와 adapter의 setOnItemClickListener()를 통해 클릭 시 이벤트를 정의하면 된다.
아이템 클릭 시 정상적으로 이름이 Toast로 나타나는 것을 볼 수 있다.
Reference
[부스트코스]안드로이드 프로그래밍
'Android > Concepts' 카테고리의 다른 글
Animation 사용법 (0) | 2020.05.07 |
---|---|
Thread Animation 만들기 (0) | 2020.05.07 |
MediaRecorder로 Audio 녹음하기 (2) | 2020.05.04 |
MediaPlayer로 Audio와 Video 파일 재생하기 (0) | 2020.05.03 |
Camera를 이용하여 사진 촬영 및 저장하기 (1) | 2020.05.02 |