RecyclerView(리사이클러뷰) 사용
리사이클러뷰 는 거의 대부분의 앱에서 사용될정도로 필수적인 뷰이기에 꼭 알고 있어야 하는 뷰입니다.
리사이클러뷰는 목록을 리스트로 보여주는 뷰로 대표적으로 카카오톡의 채팅방 리스트목록이 리사이클러뷰 입니다.
리사이클러뷰는 다른 뷰와달리 아이템뷰와 연결해줄 어댑터가 필요하기 때분에 구현하는데 조금 복잡할 수가 있습니다.
list_item_layout
<?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"
android:layout_margin="3dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#B9356DFF">
<ImageView
android:id="@+id/ImageView_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/ic_launcher_background"/>
<TextView
android:id="@+id/TextView_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"
android:textSize="17dp"
android:textColor="#FF000000"
android:layout_marginLeft="5dp"/>
</LinearLayout>
</LinearLayout>
먼저 리스트에 보여줄 아이템뷰를 만들어줍니다.
이 예제에서는 이미지뷰와 텍스트 만 사용했지만 다른 뷰처럼 자유롭게 만들어도 됩니다.
*중요한것은 최상위 레이아웃에서 4번째 라인에 layout_height의 값이 wrap_content 로 자식 레이아웃의 크기만큼만 가져야 합니다. match_parent로 할경우 아이템 뷰의 크기가 화면 전체사이즈로 만들어지게 되서 리스트가 이상하게 보여집니다.
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/RecyclerView_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/list_item_layout"
>
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
다음으로 activity_main에서 리사이클러뷰 XML코드를 작정해줍니다.
tools:listitem="@layout/list_item_layout"은 해당 리사이클러뷰에 list_item_layout 뷰를 넣어서 아이템이 추가될경우 어떻게 보이게 될지 미리 확인할 수 있는 유용한 태그 입니다.
!지금 빌드해도 실제로 이렇게 보여지지는 않습니다!
다음은 실제로 리사이클러뷰에 아이템을 추가해서 보여질 수 있도록 코드를 작성하겠습니다.
이 부분은 조금 어려울 수 있지만 그대로 따라하기만 해도 됩니다.
먼저 아이템뷰에 들어갈 데이터를 담아주는 클레스를 생성해주세요
RecyclerViewItem
package com.example.recyclerview;
public class RecyclerViewItem {
private int img;//이미지
private String text;//텍스트
public RecyclerViewItem(int img, String text){
this.img = img;
this.text = text;
}
public int getImg() {
return img;
}
public void setImg(int img) {
this.img = img;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
저의는 이미지와 텍스트만 사용하니 필드는 이미지를 담을 Int형 필드1개와 텍스트를 담을 String형 필드를 1개만 만들어줍니다. 그리고 생성자 메소드로 파라미터를 받아서 각 맴버에 담아줍니다. 그리고 저는 각 맴버의 값을 주고받을 수 있는 get, set매소드를 생성했지만 get 메소드만 사용할거기 때문에 set은 필요가 없습니다.
참고로 맴버는 다른 클레스에서 접급하지 못하도록 private를 달아주시고 모든 메소드는 public로 모든 클레스에서 접근할 수 있도록 만들어줍니다.
다음으로는 리사이클러뷰의 아이템과 연결해줄 어뎁터를 만들어줍니다.
RecyclerViewAdapter
package com.example.recyclerview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
ArrayList<RecyclerViewItem> recyclerViewItems;
public RecyclerViewAdapter(ArrayList<RecyclerViewItem> recyclerViewItems){
this.recyclerViewItems = recyclerViewItems;
}
@NonNull
@Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.list_item_layout, parent, false);
RecyclerViewAdapter.ViewHolder viewHolder = new RecyclerViewAdapter.ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerViewAdapter.ViewHolder holder, int position) {
holder.ImageView_image.setImageResource(recyclerViewItems.get(position).getImg());
holder.TextView_text.setText(recyclerViewItems.get(position).getText());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), recyclerViewItems.get(holder.getAdapterPosition()).getText(), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
return recyclerViewItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView ImageView_image;
TextView TextView_text;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ImageView_image = itemView.findViewById(R.id.ImageView_image);
TextView_text = itemView.findViewById(R.id.TextView_text);
}
}
}
RecyclerView.Adapter를 상속받습니다.
onCreateViewHolder 에서는 list_item_layout 뷰를 연결해주는 작업을 합니다.
getItemCount 여기서 return값은 ArrayList의 아이템 개수를 반환시켜줍니다.
onBindViewHolder 에서는 MainActivity 에서 onCreate 와 같은 역할을 수행하는 곳이라고 보시면 됩니다.
여기서 각 아이템에 ArrayList로 넘겨받은 RecyclerViewItem값을 이미지뷰와 텍스트뷰에 뿌려주면 됩니다.
이 곳에서도 터치 이벤트를 사용할 수 있어서 각각의 아이템을 터치했을경우 원하는 이벤트를 사용할 수 있습니다.
여기서는 아이템을 터치할경우 해당 아이템의 text를 토스트로 출력해주는 예제를 만들었습니다.
터치했을때 어떤 아이템인지는 holder.getAdapterPosition() 로 반환되는 정수값으로 구분할 수 있습니다.
ViewHolder안에서는 list_item_layout 에서 각 태그id 를 연결해줍니다.
이제 마지막으로 MainActivity에서 리사이클러뷰에 아이템을 어뎁터로 연결해주는 코드를 작성할것입니다.
package com.example.recyclerview;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView RecyclerView_1;
RecyclerViewAdapter recyclerViewAdapter;
ArrayList<RecyclerViewItem> recyclerViewItems;
RecyclerViewItem viewItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView_1 = findViewById(R.id.RecyclerView_1);
RecyclerView_1.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
recyclerViewItems = new ArrayList<>();
viewItem = new RecyclerViewItem(R.drawable.ic_launcher_background, "text");
recyclerViewItems.add(viewItem);
recyclerViewAdapter = new RecyclerViewAdapter(recyclerViewItems);
RecyclerView_1.setAdapter(recyclerViewAdapter);
}
}
setLayoutManager 에서 LinearLayoutManager 로 LinearLayout처럼 세로 또는 가로로 리스트가 만들어지게 됩니다.
파라미터로 RecyclerView.VERTICAL 를 넣어주면 리스트를 세로로 보여주고 RecyclerView.HORIZONTAL 를 넣어주면
가로로 벼여주게 됩니다. LinearLayoutManager 말고 GridLayoutManager 으로 다른 방식으로 리스트를 정렬시킬 수 있습니다.
예시로 RecyclerView_1.setLayoutManager( new GridLayoutManager(this.getApplicationContext(), 2)); 으로 변경하시면 2칸으로 나뉘어 정렬되게 됩니다.
이제 중요한 아이템에 들어갈 데이터를 ArrayList에 넣어야 합니다.
제네릭 타입으로 recyclerViewItems 를 ArrayList로 만들어서 데이터를 담을수 있도록 만들어 줍니다.
그리고 recyclerViewItems 객체를 만들어서 생성자 메소드에 파라미터로 이미지와 문자열을 넣어주고 객체를 리스트에 추가해줍니다. 그리고 추가된 리스트를 recyclerViewAdapter 어뎁터에 연결해주고 연결된 어뎁터를 리사이클러뷰 안에 넣어주면 됩니다.
리스트에 여러 아이템을 넣어주면 넣어준 아이템들이 들어간 순서대로 리사이클러뷰에 출력이 됩니다.
저또한 공부중이기에 설명도 많이 부족하고 잘봇된 부분도 있을것입니다. 틀린부분이나 미흡한 부분이 있으면 알려주시면 감사하겠습니다.
수고하셨습니다.