Android/Java

[Android / Java] RecyclerView 아이템 클릭 처리하기

ghan2 2024. 6. 10. 15:51

리사이클러뷰는, 리스트뷰에 비해 훨씬 유연하고 다양한 형태로 아이템을 표시하게 만들어준다. 레이아웃매니저를 통해서 아이템을 배치하는 형태를 다양하게 구성할 수도 있고, 애니메이션 효과 등을 손 쉽게 적용해 다이나믹한 화면을 구성할 수도 있게 해준다. 그러나 이러한 장점들이, 아이템 클릭 이벤트 처리를 복잡하게 만드는 요인이 된다. 그래서 리사이클러뷰는 아이템 클릭 이벤트 리스너를 자신이 직접 다루지 않고, 아이템 뷰에서 OnClickListener를 통해 처리하게 만들었다. 

 

1. 리사이클러뷰 뷰홀더(ViewHolder)에서 아이템 클릭 이벤트 처리하기

어댑터를 통해 만들어진 각 아이템 뷰는 "뷰홀더"객체에 저장되어 화면에 표시되고, 필요에 따라 생성 또는 재활용이 된다. 즉, 아이템 클릭 이벤트도 뷰홀더에 작성해주면 된다. 클릭 이벤트는 뷰 홀더가 만들어지는 시점에 처리하면 된다.

(사진)

 

2. 아이템 위치 (Position) 알아내기

onClick()메소드로 아이템 클릭 이벤트를 처리할 수 있게 되었다. 이제는 현재 클릭된 이벤트가 발생한 아이템 위치를 알아내고 관련 처리를 해주어야 한다. 어떻게 자신의 위치를 알아낼 수 있을까? onClick() 메서드는 단지 View객체에 대한 참조만 전달될 뿐, 위치에 대한 정보는 가지고 있지 않다. 이런 경우를 위해, 리사이클러뷰의 뷰홀더에는 현재 자신의 위치를 확인할 수 있는 getAdapterPosition() 이라는 메소드가 제공되고 있다.  

 

아이템뷰를 갱신하는 과정에서, 뷰홀더가 참조하는 아이템이 어댑터에서 삭제되면 getAdapterPosition() 메서드는 NO_POSITION을 리턴하기 때문에 리턴값에 대해 검사하는 과정이 필요하다. 

 

3. 아이템 위치(position)로 데이터 리스트 접근하기

아이템 위치를 알아냈으니, 어댑터가 참조하고 있는 데이터 리스트로부터 데이터를 가져오는 것은 간단하다. 

User item = localDataSet.get(clickPos);

 

그러나 이는 어댑터 범주 안에서만 유효한 방법이라고 한다. 액티비티에서 클릭 이벤트를 처리하려면 커스텀 리스너를 정의해서 처리해야 한다. (자식이 부모의 이벤트 핸들러를 호출해야할 경우에 사용)

 

4. 커스텀 리스너(Custom Listener) 인터페이스 정의

custom listener

 

package com.example.tiaapplication;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

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

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

public class NestedScrollView extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.nestedscrollview);

        List<User> testDataSet = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            testDataSet.add(new User("친구" + i, "010-0000-000" + i));
        }
        //========================================================

        RecyclerView recyclerView = findViewById(R.id.recyclerView);
        RecyclerView recyclerView2 = findViewById(R.id.recyclerView2);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView2.setLayoutManager(new LinearLayoutManager(this));

        CustomAdapter customAdapter = new CustomAdapter(testDataSet);

        customAdapter.setOnItemClickListener((v, position) -> {
            Intent intent = new Intent(getApplicationContext(), ChattingRoom.class);
            User user = customAdapter.getItem(position);
            intent.putExtra("name", user.getName());
            startActivity(intent);
        });
        recyclerView.setAdapter(customAdapter);
        recyclerView2.setAdapter(customAdapter);

    }
}

메인 액티비티에서 커스텀 어댑터에 리스너를 부여할 수 있게 된다. 나는 클릭시에 채팅화면으로 넘어가도록 구현했다. 

 

결과

 


참고

https://recipes4dev.tistory.com/168