안드로이드 리사이클러뷰 클릭 이벤트(RecyclerView Click Event)

Intro

Recyclerview의 클릭 이벤트 처리

RecyclerView 클릭 이벤트

Recycler ViewList VIew와 다르게 뷰에서 클릭 이벤트를 다루지않고 아이템 뷰에서의 이벤트를 통해 처리한다.

따라서 뷰홀더가 생성되는 시점에 이벤트 리스너를 추가한다.

public class ViewHolder extends RecyclerView.ViewHolder 
{

    ViewHolder(View itemView)
    {
        super(itemView);

        itemView.setOnClickListener(new View.OnClickListener() 
        {
                @Override
                public void onClick(View v) 
                {
                    int pos = getAdapterPosition();
                    if (pos != RecyclerView.NO_POSITION) 
                    {
                    // click event
                    }
                }
        });
    }
}

getAdapterPosition()를 이용하면 클릭된 아이템의 위치를 가져올 수 있다. 이때 NO_POSTION인지 검사하여 갱신 과정에서 포지션이 없는 경우를 방지한다.

RecyclerView 외부 클릭이벤트 처리

클릭 이벤트를 어댑터에서 처리 하지않고, 외부(액티비티,프래그먼트)에서 처리하고자할 때 방법

어댑터 내 커스텀 리스너 인터페이스 정의

public interface OnItemClickListener
{
    void onItemClick(View v, int pos);
}

리스너 객체를 적달하는 메서드와 전달된 객체를 저장할 변수 추가

// 리스너 객체 참조를 저장하는 변수
private OnItemClickListener mListener = null;

// OnItemClickListener 객체 참조를 어댑터에 전달하는 메서드
public void setOnItemClickListener(OnItemClickListener listener)
{
    this.mListener = listener;
}

아이템 클릭 이벤트 핸들러 메서드에서 리스너 객체 메서드 호출

public class ViewHolder extends RecyclerView.ViewHolder
{
    public TextView textView1;

    ViewHolder(View itemView)
    {
        super(itemView);

        itemView.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {

                int pos = getAdapterPosition();
                // 리스너 객체의 메서드 호출
                if (pos != RecyclerView.NO_POSITION)
                {
                    mListener.onItemClick(v, pos);
                }

            }
        });
        
        textView1 = itemView.findViewById(R.id.text1);
    }
}

액티비티(또는 프래그먼트)에서 커스텀 리스너 객체 생성 및 전달

textAdapter.setOnItemClickListener(new TextAdapter.OnItemClickListener()
{
    @Override
    public void onItemClick(View v, int pos)
    {
        // 실행 내용
    }
});

예제

어댑터

 // 커스텀 리스너 인터페이스
public interface OnItemClickListener
{
    void onItemClick(View v, int pos);
}

public interface OnItemLongClickListener
{
    void onItemLongClick(View v, int pos);
}

// 리스너 객체 참조를 저장하는 변수
private OnItemClickListener mListener = null;
private OnItemLongClickListener mLongListener = null;

public void setOnItemClickListener(OnItemClickListener listener)
{
    this.mListener = listener;
}

public void setOnItemLongClickListener(OnItemLongClickListener listener)
{
    this.mLongListener = listener;
}

//
public TextAdapter(ArrayList<String> list)
{
    mData = list;
}

// ViewHolder (화면에 표시될 아이템뷰 저장)
public class ViewHolder extends RecyclerView.ViewHolder
{
    public TextView textView1;

    ViewHolder(View itemView)
    {
        super(itemView);

        itemView.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {

                int pos = getAdapterPosition();
                if (pos != RecyclerView.NO_POSITION)
                {
                    mListener.onItemClick(v, pos);
                }

            }
        });

        itemView.setOnLongClickListener(new View.OnLongClickListener()
        {
            @Override
            public boolean onLongClick(View v)
            {
                int pos = getAdapterPosition();
                if (pos != RecyclerView.NO_POSITION)
                {
                    mLongListener.onItemLongClick(v, pos);
                }
                return true;
            }
        });


        textView1 = itemView.findViewById(R.id.text1);
    }
}

이벤트를 처리할 Fragment

// 메모 클릭 이벤트(수정)
textAdapter.setOnItemClickListener(new TextAdapter.OnItemClickListener()
{
        @Override
        public void onItemClick(View v, int pos)
        {
            Intent intent = new Intent(getActivity(), addschedule.class);
            intent.putExtra("SelectedDate", mTime);

            String[] params = {mTime};
            Cursor cursor = (Cursor) dbHelper.getReadableDatabase().query(MemoContract.MemoEntry.TABLE_NAME, null, "date=?", params, null, null, null);
            cursor.moveToPosition(pos);
            
            int id = cursor.getInt(cursor.getColumnIndexOrThrow(MemoContract.MemoEntry._ID));
            String title = cursor.getString(cursor.getColumnIndexOrThrow(MemoContract.MemoEntry.COLUMN_NAME_TITLE));
            String contents = cursor.getString(cursor.getColumnIndexOrThrow(MemoContract.MemoEntry.COLUMN_NAME_CONTENTS));
            
            intent.putExtra("id",id);
            intent.putExtra("title",title);
            intent.putExtra("contents",contents);
            startActivityForResult(intent, REQUEST_CODE_INSERT);
        }
    });

// 일정 삭제(롱클릭)
textAdapter.setOnItemLongClickListener(new TextAdapter.OnItemLongClickListener()
{
    @Override
    public void onItemLongClick(View v, int pos)
    {

        //AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.Dialog);


        String[] params = {mTime};
        Cursor cursor = (Cursor) dbHelper.getReadableDatabase().query(MemoContract.MemoEntry.TABLE_NAME, null, "date=?", params, null, null, null);
        cursor.moveToPosition(pos);
        final int id = cursor.getInt(cursor.getColumnIndexOrThrow(MemoContract.MemoEntry._ID));

        builder.setTitle("일정 삭제");
        builder.setMessage("일정을 삭제하시겠습니까?");
        builder.setPositiveButton("삭제", new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                int deletedCount = db.delete(MemoContract.MemoEntry.TABLE_NAME,MemoContract.MemoEntry._ID+"="+id,null);

                if(deletedCount==0)
                {
                    Toast.makeText(getActivity(), "삭제 실패", Toast.LENGTH_SHORT).show();
                }
                else
                {
                    getMemoCursor();
                    Toast.makeText(getActivity(), "일정이 삭제되었습니다", Toast.LENGTH_SHORT).show();
                }
            }
        });
        builder.setNegativeButton("취소",null);
        builder.show();
    }
});

일반 클릭은 수정을 위해 일정 추가 액티비티로 아이템 정보를 intent하여 실행하도록 구성했고

롱클릭은 해당되는 아이템을 테이블에서 삭제하는 다이얼로그가 띄워지도록 했다.

실행 결과

일반 클릭(수정)

1

롱 클릭(삭제)

2

참고자료

https://recipes4dev.tistory.com/168

댓글남기기