안드로이드 리사이클러뷰 클릭 이벤트(RecyclerView Click Event)
Intro
Recyclerview의 클릭 이벤트 처리
RecyclerView 클릭 이벤트
Recycler View
는 List 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하여 실행하도록 구성했고
롱클릭은 해당되는 아이템을 테이블에서 삭제하는 다이얼로그가 띄워지도록 했다.
실행 결과
일반 클릭(수정)
롱 클릭(삭제)
댓글남기기