[Android/Java] RecyclerView

doooly·2024년 1월 28일
0

Android

목록 보기
5/5

https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView
https://developer.android.com/guide/topics/ui/layout/recyclerview?hl=ko

🔄 RecyclerView

RecyclerView는 android에서 사용되는 대규모의 데이터를 유연하게 표현하는 위젯이자 뷰그룹입니다
listView와는 다르게, 화면에 표시되는 뷰들만 만들어내고, 셀을 재사용하기 때문에 생산성이 높습니다

아래는 recyclerView를 사용하기 위해 필요한 요소들입니다

✅ LayoutManager

아이템의 배치 형태를 지정하는 요소입니다

  • LinearLayoutManager
  • GridLayoutManager
  • StaggeredGridLayoutManager

✅ ViewHolder

한 행에 해당하는 뷰 정보를 가지고 있습니다
그렇기에 viewHolder 객체는 recyclerView에 띄울 행의 개수만큼 필요하지만,
이는 binding 참조를 viewHolder에게 넘김으로써 해결됩니다

✅ Adapter

recyclerView에 대한 응답을 가지고 있습니다
아래 3가지 메소드를 필수로 오버라이드해 리사이클러뷰에 대한 아이템뷰를 만들고 응답을 처리합니다

  • onCreateViewHolder
  • onBindViewHolder
  • getItemCount()


📋 RecyclerView 구현

1️⃣ RecyclerView component 추가

recyclerView를 구현할 Activity 명은 SearchSourceActivity 입니다
activity에 사용할 xml에 recyclerView component를 추가해줍니다

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

recyclerView의 각 행에 사용될 레이아웃을 추가해줍니다
파일의 이름은 search_recycler_view_item.xml 으로 지정해줬습니다

<?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:id="@+id/search_list"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal"
    android:paddingHorizontal="10dp"
    android:paddingStart="15dp">

    <ImageView
        android:id="@+id/line_image_view"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_gravity="center_vertical"
        android:src="@drawable/ic_line7" />

    <TextView
        android:id="@+id/line_text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:paddingStart="10dp"
        android:textColor="@color/black"
        android:textSize="17sp"
        tools:ignore="RtlSymmetry" />
</LinearLayout>



2️⃣ ViewHolder 생성

ViewHolder는 RecyclerView.ViewHolder 을 상속받아 사용합니다

각 행에 해당하는 레이아웃의 바인딩을 사용하면, 그 내부 요소들에 대한 참조를 가질 수 있습니다

    public class ViewHolder extends RecyclerView.ViewHolder {
        SearchRecyclerViewItemBinding binding;

        public ViewHolder(SearchRecyclerViewItemBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }



3️⃣ Adapter 생성

Adapter 또한 RecyclerView.Adapter 을 상속받아 사용합니다
제네릭 타입이라, 사용하는 ViewHolder 객체를 요구합니다

뷰홀더 클래스를 SearchAdapter class 내부에 만들어주고, Adapter 제네릭에 해당 뷰홀더를 건네주었습니다

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

	//터치이벤트 핸들링을 위한 커스텀 리스너
    private OnItemClickListener listener; 
    //리사이클러뷰에 띄울 리스트
    private List<Station> items;
    private Context context;
    private Station station;
    private LineNumImage lineNumImage = new LineNumImage();
    
    public SearchAdapter(Context context, List<Station> items) {
        this.context = context;
        this.items = items;
    }
    
    //필수 오버라이드 메소드 1
     @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    	//필요한 아이템 레이아웃 바인딩
        SearchRecyclerViewItemBinding binding = SearchRecyclerViewItemBinding.inflate(LayoutInflater.from(viewGroup.getContext()), viewGroup, false);
        //뷰홀더 객체 생성
        return new ViewHolder(binding);
    }
    
    //필수 오버라이드 메소드 2
      @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        station = items.get(position);
        lineNumImage.addLineNum();

        String lineNum = station.getLineNum();

		//각 행 데이터 설정
        if (LineNumImage.lineNumMap.containsKey(lineNum)) {
            holder.binding.lineImageView.setImageResource(LineNumImage.lineNumMap.get(lineNum));
        } else {
            holder.binding.lineImageView.setImageResource(R.drawable.ic_line0);
        }

        holder.binding.lineTextView.setText(station.getFullName());
        
        //clickEvent 처리(생략)
    }
    
    //필수 오버라이드 메소드 3
     @Override
    public int getItemCount() {
        return items.size();
    }
    
    /** 위에서 만든 뷰홀더 **/
    
    }

3개의 메소드를 오버라이드 해 필요한 설정을 해줍니다

  1. onCreateViewHolder()
    인자로 뷰 그룹을 건네받아 필요한 아이템을 바인딩하고,
    이 바인딩 객체을 viewHolder 생성자 넣어 뷰 홀더 객체를 생성합니다
  1. onBindViewHolder()
    position을 통해 리스트의 n번째 아이템에 대해 데이터를 설정합니다
    holder.binding을 통해 필요한 요소에 접근할 수 있습니다
  1. getItemCount()
    아이템의 개수를 리턴해줍니다



4️⃣ Activity 설정

마지막으로 recyclerView를 사용할 Activity에 만든 adapter를 연결해줍니다

public class SearchSourceActivity extends AppCompatActivity {

    ActivitySearchSourceBinding binding; //xml binding
    private RecyclerView recyclerView;
    private SearchAdapter adapter;
    
    . . .
    
    private void setRecyclerView() {
    	//recyclerView component 지정
        recyclerView = binding.searchSourceRecyclerView;

		adapter = new SearchAdapter(this, resultList);
        //layoutManager 설정
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //adapter 설정
        recyclerView.setAdapter(adapter);

		//click Listener 설정
        adapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(Station station) {
                SetRouteActivity.sourceStation = station;
                Log.d("MAKARTEST", "SearchSource : Source = " + SetRouteActivity.sourceStation);
                finish();
            }
        });
    }
    
    }



📱 결과 화면

0개의 댓글