RecyclerView로 목록 만들기
App/Android

RecyclerView로 목록 만들기

RecyclerView는 Listview의 기능을 모두 갖고 있으면서도, 더 발전된 항목이라 Listview보다 사용을 추천한다고 한다.

 

1.App단의 Gradle에 라이브러리를 추가해야한다.

 implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha05'

 

 

2.  Activity의 레이아웃은 비교적 간단하다. 화면을 RecyclerView로 꽉 채우면 된다.

 

-res/layout/activity_news.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/myRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">

</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

 

 

3. 그 다음으로 RecyclerView의 각 row(행)을 나타내는 레이아웃을 정의해야한다.

 

-res/layout/row_news.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="200dp"
   android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
<!--겹쳐지는 레이아웃은 relative layout-->
    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="100dp">
<ImageView
    android:id="@+id/mImageView"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="@null"
    android:src="@drawable/header"/>

    <TextView
        android:id="@+id/mTextViewTitle"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:paddingLeft="6dp"
        android:paddingRight="6dp"
        android:layout_marginTop="5dp"
        android:gravity="center"
        android:textColor="@color/white"
        android:textSize="18sp" />
    </RelativeLayout>
    <TextView
        android:id="@+id/mTextViewContent"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:background="#15000000"
        android:textSize="15sp"
        android:ellipsize="end"
        android:text="The Title Song of this Album is 'Oh My!'"/>
</LinearLayout>

 

 

4. 해당 액티비티에서 xml 레이아웃의 RecyclerView를 가지고 Adapter를 설정한다.

=> 이때, LayoutManager에 따라서 RecyclerView에 보여지는 아이템의 배치 방법이 달라진다.

=> 대부분의 경우에는 그냥 일렬로 나열하면 되므로 LinearLayoutManager를 사용하면 된다.

 

package com.example.practice;

import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;

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

import com.google.android.material.textfield.TextInputEditText;

import java.util.ArrayList;

public class NewsActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private String[] myDataset={"1","2"};
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_news);
           mRecyclerView=(RecyclerView) findViewById(R.id.myRecyclerView);
        //xml 레이아웃의 recyclerview를 가져와서 adapter를 설정한다.

        // 리사이클러뷰에 LinearLayoutManager 객체 지정.=> 일렬로 늘어놓으면 되므로
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this)) ;

        // 리사이클러뷰에 어댑터를 세팅한다. 이때, 액티비티에서 원하는 String 배열을 넘겨준다.
        mAdapter = new CustomAdapter(myDataset) ;
        mRecyclerView.setAdapter(mAdapter) ;
    }}

 

 

5. 마지막으로 adapter를 정의해야 한다.

  1) 우선 CustomAdapater는 Recycler.Adapater<RecyclerView.ViewHolder>를 상속받아서 정의하면 된다.

  2)  CustomAdapter생성자는 myDataset을 인자로 가지는데, NewsActivity.java에서 뷰를 생성할 때 표시하고자 하는 데이터를 전달했었다.

  

  3) 그 다음 ViewHolder에 각 뷰를 보관해야 한다. ViewHolder 객체는 레이아웃의 태그 필드 안에 각 구성 요소 뷰를 저장하므로 반복적으로 조회하지 않고도 즉시 액세스할수 있다.

 

   - 매 리스트의 row마다 findViewById()를 호출하면 매우 큰 비용이 들기 시작할 것이다. 스크롤을 내릴때마다 시간도 오래 들고, 속도 저하를 초래하게 된다.

 =>따라서 각 뷰 객체를 뷰 홀더에 보관함으로써 findViewById와 같은 반복적으로 호출되는 메서드를 효과적으로 줄여 속도 향상에 도움을 주게 된다.

 

 

 ## RecyclerView에서 필수로 오버라이딩 해야 하는 세가지 메서드

  •  onCreateViewHolder = ViewHolder 객체를 생성한다
  • onBindViewHolder= ViewHolder에 데이터를 넣는 작업 수행
  • getItemCount = data의 개수를 반환해준다.
package com.example.practice;

import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

    //viewHolder란 각 뷰들을 보관하는 Holder객체를 의미한다.
    //Viewholder는 태그 필드 안에 각 구성 요소 뷰들을 저장하므로 반복적으로 조회하지않고 즉시 액세스 가능하다.
    private String[] localDataSet;

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder).
     */
    //item view를 저장하는 ViewHolder 클래스
    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final TextView mTextViewTitle;
        private final TextView mTextViewContent;
        private final ImageView mImageView;

        public ViewHolder(View view) {
            super(view);
            // Define click listener for the ViewHolder's View

            //view 객체에 대한 참조
            mTextViewTitle = view.findViewById(R.id.mTextViewTitle);
            mTextViewContent=view.findViewById(R.id.mTextViewContent);
            mImageView=view.findViewById(R.id.mImageView);
        }

        public TextView getTextView() {
            return mTextViewContent;
        }
    }

    /**
     * Initialize the dataset of the Adapter.
     *
     * @param dataSet String[] containing the data to populate views to be used
     * by RecyclerView.
     */
    //생성자에서 데이터 객체를 전달받는다. 자료형은 임의로 결정 가능.
    public CustomAdapter(String[] dataSet) {
        localDataSet = dataSet;
    }

    // Create new views (invoked by the layout manager)
    //아이템 뷰를 위한 뷰홀더 객체를 생성하여 리턴한다.
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        // Create a new view, which defines the UI of the list item
        //LayoutInflater = 안드로이드에서 view를 생성하는 방법
                View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.row_news, viewGroup, false);

        return new ViewHolder(view);
    }

    // Replace the contents of a view (invoked by the layout manager)
    //position에 해당하는 데이터를 뷰홀더의 아이템뷰에 표시 (view의 내용을 localDataSet으로 교환)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.mTextViewTitle.setText(localDataSet[position]);
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return localDataSet.length;
    }
}