관리 메뉴

나만을 위한 블로그

[Android] 리사이클러뷰 아이템의 position 값을 액티비티에서 알아내고 인텐트로 넘기는 방법 본문

Android

[Android] 리사이클러뷰 아이템의 position 값을 액티비티에서 알아내고 인텐트로 넘기는 방법

참깨빵위에참깨빵_ 2020. 7. 10. 19:13
728x90
반응형

21.05.02) 인터페이스 안의 메서드 인자 변경

 

앱을 만들다 보면 액티비티에서 보여지는 리사이클러뷰 아이템의 position 값을 알고 싶은 경우가 있다.

이 값을 알기 위해선 먼저 어댑터에서 약간의 처리가 필요하다.

 

public interface ItemClickListener
    {
        void onItemClick(int position);
    }

어댑터 안에 아이템 클릭 리스너 인터페이스를 정의한다.

int position은 뷰홀더 클래스에서 재정의할 때 필요하고 내가 알고 싶은 것이 아이템의 position 값이기 때문에 꼭 넣어준다.

이 인터페이스의 참조변수는 전역변수로 어댑터 밖에 설정하고, 생성자를 만들 때 포함시켜 생성자를 만든 다음 onCreateViewHolder() 안에서도 설정해준다.

 

return new AddViewHolder(view, itemClickListener);

 

그리고 onBindViewHolder() 안에선 특정 뷰에 setTag()로 태그를 달아준다.

setTag()의 인자로는 onBindViewHolder()가 자체적으로 갖고 있는 인자인 position 값을 넣어준다.

 

holder.textview.setTag(position);

 

이렇게 하면 리사이클러뷰 안에 들어있는 각 아이템마다 position이 태그로 달리게 된다.

이후 RecyclerView.ViewHolder를 상속받는 뷰홀더 클래스의 전역변수로 아이템 클릭 리스너의 참조변수를 설정하고, 이를 생성자 안에서 처리한다. 내 경우에는 이렇게 썼다.

 

public class AddViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView name, name2;
        ItemClickListener itemClickListener;

        public AddViewHolder(View view, ItemClickListener itemClickListener)
        {
            super(view);
            name = view.findViewById(R.id.name);
            name2 = view.findViewById(R.id.name2);

            this.itemClickListener = itemClickListener;
            name.setOnClickListener(this);
        }

        @Override
        public void onClick(View v)
        {
            itemClickListener.onItemClick(getAdapterPosition());
        }
    }

getAdapterPosition()으로 어댑터가 갖고 있는 position 값을 아이템 클릭 시 전달한다.

그리고 액티비티로 돌아와서 어댑터 안의 클릭 리스너 인터페이스 참조변수를 전역 변수로 설정한 다음, 액티비티 안에서 참조변수를 통해 아이템 클릭 리스너의 행동 양식을 지정해준다.

 

itemClickListener = ((position) -> {
            int pos = (int) view.getTag();
            Log.e("아이템의 pos 값", String.valueOf(pos + 1));
            String str_pos = String.valueOf(pos + 1);
            Intent intent = new Intent(MainActivity.this, SecondActivity.class);
            intent.putExtra("pos", str_pos);
            startActivity(intent);
        });

1번 아이템을 클릭한다면 그 아이템의 태그값을 int로 캐스팅해서 int pos 변수 안에 담는다.

그리고 String.valueOf()의 인자로 pos 변수를 넣은 뒤 1을 더해준다.

1을 더해주는 이유는 리사이클러뷰 아이템의 position 값은 0부터 시작하는데, 나는 1부터 나오게 해야 했기 때문에 1을 더해준 것이다. 0부터 시작해도 상관없다면 +1을 빼주자.

String.valueOf()를 사용한 이유는 인텐트로 값을 넘긴 후 받을 때 String으로 받아야 setText()하기 편하기 때문에 썼다.

위 코드는 람다식 형태로 작성돼 있는데, 잘 모르겠다면 아래의 람다식을 적용하지 않은 코드를 쓰면 된다.

 

itemClickListener = new XXXAdapter.ItemClickListener()
        {
            @Override
            public void onItemClick(int position)
            {
                int pos = (int) view.getTag();
                Log.e("아이템의 pos 값", String.valueOf(pos + 1));
                String str_pos = String.valueOf(pos + 1);
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                intent.putExtra("pos", str_pos);
                startActivity(intent);
            }
        };

XXXAdapter 부분에는 자신이 만든 어댑터의 이름을 넣어주면 된다.

어댑터 안에 만든 클릭 리스너 인터페이스를 액티비티에서 호출했기 때문에 onItemClick() 위에 오버라이드 어노테이션이 생긴 걸 볼 수 있다.

이제 클릭 리스너 안의 인텐트를 통해 다음 액티비티로 이동 후, getIntent()로 인텐트 안의 값을 getStringExtra()로 꺼내서 로그나 토스트로 확인해보면 정상적으로 아이템의 position 값에 1이 더해져서 출력되는 걸 볼 수 있다.

반응형
Comments