RecyclerView에 대해 알아보자! | Android Study

hoya·2021년 6월 30일
3

Android Study

목록 보기
1/19
post-thumbnail

🙄 RecyclerView?

RecyclerView 는 이미지나 텍스트를 리스트화해서 스크롤하며 볼 수 있게 해주는 컨테이너이다.

기존에 사용하던 ListView 와 비슷하지만, 정확히는 ListView 의 확장판이라고 이야기할 수 있다. ListView 의 확장판이니 당연히, 대부분 RecyclerView 로 대체된 상태이다.

RecyclerView 는 ListView 보다 향상된 성능을 제공하며, Adpater의 ViewHolder를 이용, RecyclerView 내의 View를 재활용하여 사용한다.

  • ViewHolder를 사용하는 이유는? -> 맨 처음 화면에 보이는 뷰 객체를 홀딩(기억)하고 있어야 하기 때문에 ViewHolder를 사용한다.

ListView 는 사용자가 스크롤 할 때마다 위에 있던 뷰는 삭제되고, 맨 아래의 뷰는 생성되길 반복하여 cost가 매우 높아지게 되는 반면,

RecyclerView에서는 아이템이 100000개를 넘어가더라도 화면에 보이는 정도의 View만 생성하고, 스크롤 할 때마다 삭제하지 않고 가장 아래의 아이템쪽으로 객체를 이동시켜 재사용하게 된다.


🙃 실습

📌 1. 레이아웃 영역 준비

1-1. 아이템 레이아웃 설정

데이터 하나하나가 어떻게 들어갈 것인지 틀을 우선 정해주어야 한다. 기존 레이아웃을 작성할 때와 같이 자신의 입맛에 맞게 작성하면 된다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/layout_selector"
    android:id="@+id/item_board">

    <TextView
        android:id="@+id/item_board_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8sp"
        android:layout_marginLeft="8sp"
        android:textSize="24sp"
        android:textStyle="bold"
        android:textColor="@color/colorWhite"
        tools:text="TITLE" />

    <TextView
        android:id="@+id/item_board_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/colorGray"
        android:textSize="16sp"
        android:layout_marginLeft="8sp"
        android:maxLines="1"
        android:ellipsize="end"
        tools:text="Contents" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8sp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/item_board_time"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:textColor="@color/colorGray"
            android:textSize="16sp"
            tools:text="Time" />

        <TextView
            android:id="@+id/item_board_writer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:textColor="@color/colorGray"
            android:textSize="16sp"
            tools:text="Writer" />

        <View
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/board_thumup" />

		<!-- 중략 -->		

    </LinearLayout>

</LinearLayout>

완성된 틀은 다음과 같다.


1-2. 메인 액티비티에 RecyclerView 추가

사용할 액티비티에서 RecyclerView 를 추가한다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".BoardActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

📌 2. 모델 생성

RecyclerView 에 들어갈 데이터들을 정리한다. getter와 setter를 통해 데이터의 입출력이 이루어질 것이다.

package kr.ac.castcommunity.cc.models;

public class Board {

    private String title;
    private String contents;
    private String time;
    private String writer;


    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
  
    public String getContents() {
        return contents;
    }

    public void setContents(String contents) {
        this.contents = contents;
    }
    
    public String getTime() {
    	return time;
    }
    
    public void setTime(String time) {
    	this.time = time;
    }

    public String getWriter() {
        return writer;
    }

    public void setWriter(String writer) {
        this.writer = writer;
    }
}

📌 3. Adapter 생성

가장 핵심적인 부분이다. 우리가 위에서 작성했던 아이템 레이아웃과 데이터를 실제로 연결하는 역할을 수행한다.

package kr.ac.castcommunity.cc.adapters;

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.List;

import kr.ac.castcommunity.cc.R;
import kr.ac.castcommunity.cc.models.Board;

public class BoardAdapter extends RecyclerView.Adapter<BoardAdapter.BoardViewHolder> {
    // 해당 어댑터의 ViewHolder를 상속받는다.
    private List<Board> datas;

     public BoardAdapter(List<Board> datas) {
        this.datas = datas;
    }

    @Override
    public BoardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // ViewHodler 객체를 생성 후 리턴한다.
         return new BoardViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_board, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull BoardViewHolder holder, int position) {
        // ViewHolder 가 재활용 될 때 사용되는 메소드
        Board data = datas.get(position);
        holder.title.setText(data.getTitle());
        holder.contents.setText(data.getContents());
    }

    @Override
    public int getItemCount() {
        return datas.size(); // 전체 데이터의 개수 조회
    }

    // 아이템 뷰를 저장하는 클래스
    public class BoardViewHolder extends RecyclerView.ViewHolder {
         // ViewHolder 에 필요한 데이터들을 적음.
         private TextView title;
         private TextView contents;

        public BoardViewHolder(@NonNull View itemView) {
            super(itemView);
            // 아이템 뷰에 필요한 View
            title = itemView.findViewById(R.id.item_board_title);
            contents = itemView.findViewById(R.id.item_board_content);
        }
    }
}

액티비티와 리사이클러뷰를 이어주는 역할을 수행하는 어댑터 클래스이다. ViewHolder 가 어떤 역할을 하는지 상세히 살펴보는 것이 좋다.


📌 4. RecyclerView 에 Adapter 와 LayoutManager 지정

준비는 모두 끝났으니 실제 RecyclerView 에 연결만 해주면 끝이다.

package kr.ac.castcommunity.cc;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

import kr.ac.castcommunity.cc.adapters.BoardAdapter;
import kr.ac.castcommunity.cc.models.Board;

public class BoardActivity extends AppCompatActivity {

    private RecyclerView mPostRecyclerView;

    private BoardAdapter mAdpater;
    private List<Board> mDatas;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.board);

        mPostRecyclerView = findViewById(R.id.recyclerView);
        mDatas = new ArrayList<>(); // 샘플 데이터 추가
        mDatas.add(new Board("title","contents","time",20,10)); 
        mDatas.add(new Board("title","contents","time",20,10)); 
        mDatas.add(new Board("title","contents","time",20,10)); 
        mDatas.add(new Board("title","contents","time",20,10)); 
        mDatas.add(new Board("title","contents","time",20,10)); 

        // Adapter, LayoutManager 연결
        mAdpater = new BoardAdapter(mDatas);
        mPostRecyclerView.setAdapter(mAdpater);
        mPostRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }



}


😎 결과

새로운 미니 프로젝트는 에브리타임을 모델링하여 만들어질 예정이다. 그 과정에서 안드로이드 게시판을 만들기 위해 ListView 를 알아보다가, 더 개선된 RecyclerView 에 관해 기억을 남기기 위해 해당 글을 포스팅한다.


참고 및 출처

리사이클러뷰 생성예제
리사이클러뷰 만들기
서버없이 안드로이드 완결판 2시간만에 앱 만들기(YOUTUBE)

profile
즐겁게 하자 🤭

0개의 댓글