RecyclerView에서 선택한 위치를 어떻게 얻습니까?
지원 라이브러리의 recyclerview 및 카드를 실험하고 있습니다. 나는 카드의 recyclerview를 가지고 있습니다. 각 카드는 제거 할 수있는 오른쪽 상단 모서리에 'x'아이콘이 있습니다.
카드 XML, list_item.xml
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/taskDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textSize="40sp"
android:text="hi"/>
<ImageView
android:id="@+id/xImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:src="@drawable/ic_remove"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
notifyItemRemoved(position)
에서 사용할 위치로 행에 태그를 지정하려고 했습니다 TaskAdapter.java
.
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder> {
private List<Task> taskList;
private TaskAdapter thisAdapter = this;
// cache of views to reduce number of findViewById calls
public static class TaskViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected TextView taskTV;
protected ImageView closeBtn;
public TaskViewHolder(View v) {
super(v);
taskTV = (TextView)v.findViewById(R.id.taskDesc);
}
@Override
public void onClick(View v) {
int position = v.getTag();
adapter.notifyItemRemoved(position);
}
}
public TaskAdapter(List<Task> tasks) {
if(tasks == null)
throw new IllegalArgumentException("tasks cannot be null");
taskList = tasks;
}
// onBindViewHolder binds a model to a viewholder
@Override
public void onBindViewHolder(TaskViewHolder taskViewHolder, int pos) {
final int position = pos;
Task currTask = taskList.get(pos);
taskViewHolder.taskTV.setText(currTask.getDescription());
taskViewHolder.closeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
thisAdapter.notifyItemRemoved(position);
}
});
}
@Override
public int getItemCount() {
return taskList.size();
}
// inflates row to create a viewHolder
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int pos) {
View itemView = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item, parent, false);
return new TaskViewHolder(itemView);
}
}
태그를 설정할 수없고 어댑터에 액세스 할 수 없기 때문에 작동하지 않습니다. onClick.
당신 onClickListener
의 s를 설정 onBindViewHolder()
하고 거기에서 위치에 액세스 할 수 있습니다. 당신이 그들을 설정 ViewHolder
하면 당신은 또한 당신이 위치를 전달하지 않는 한 어떤 위치를 클릭했는지 알 수 없습니다ViewHolder
편집하다
으로 pskink
지적 밖으로 ViewHolder
있는 getPosition()
방법 있도록 원래는 정확하고 있었다.
보기가 클릭하면 당신이 사용할 수있는 getPosition()
당신에 ViewHolder
있으며 위치를 반환
최신 정보
getPosition()
이제 더 이상 사용되지 않으며 getAdapterPosition()
Kotlin 코드 :
override fun onBindViewHolder(holder: MyHolder, position: Int) {
// - get element from your dataset at this position
val item = myDataset.get(holder.adapterPosition)
}
다른 방법 -View 클래스의 setTag () 및 getTag () 메서드를 사용합니다.
어댑터의 onBindViewHolder 메소드에서 setTag () 사용
@Override public void onBindViewHolder(myViewHolder viewHolder, int position) { viewHolder.mCardView.setTag(position); }
여기서 mCardView는 myViewHolder 클래스에 정의되어 있습니다.
private class myViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public View mCardView; public myViewHolder(View view) { super(view); mCardView = (CardView) view.findViewById(R.id.card_view); mCardView.setOnClickListener(this); } }
OnClickListener 구현에서 getTag () 사용
@Override public void onClick(View view) { int position = (int) view.getTag(); //display toast with position of cardview in recyclerview list upon click Toast.makeText(view.getContext(),Integer.toString(position),Toast.LENGTH_SHORT).show(); }
자세한 내용 은 https://stackoverflow.com/a/33027953/4658957 을 참조하십시오.
@tyczj 답변을 보완하려면 :
일반 어댑터 Pseido 코드 :
public abstract class GenericRecycleAdapter<T, K extends RecyclerView.ViewHolder> extends RecyclerView.Adapter{
private List<T> mList;
//default implementation code
public abstract int getLayout();
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(getLayout(), parent, false);
return getCustomHolder(v);
}
public Holders.TextImageHolder getCustomHolder(View v) {
return new Holders.TextImageHolder(v){
@Override
public void onClick(View v) {
onItem(mList.get(this.getAdapterPosition()));
}
};
}
abstract void onItem(T t);
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
onSet(mList.get(position), (K) holder);
}
public abstract void onSet(T item, K holder);
}
ViewHolder :
public class Holders {
public static class TextImageHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView text;
public TextImageHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(R.id.text);
text.setOnClickListener(this);
}
@Override
public void onClick(View v) {
}
}
}
어댑터 사용 :
public class CategoriesAdapter extends GenericRecycleAdapter<Category, Holders.TextImageHolder> {
public CategoriesAdapter(List<Category> list, Context context) {
super(list, context);
}
@Override
void onItem(Category category) {
}
@Override
public int getLayout() {
return R.layout.categories_row;
}
@Override
public void onSet(Category item, Holders.TextImageHolder holder) {
}
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
FrameLayout root;
public ViewHolder(View itemView) {
super(itemView);
root = (FrameLayout) itemView.findViewById(R.id.root);
root.setOnClickListener(this);
}
@Override
public void onClick(View v) {
LogUtils.errorLog("POS_CLICKED: ",""+getAdapterPosition());
}
}
개인적으로 제가 찾은 가장 간단한 방법은 다음과 같습니다.
"RecycleAdapter"클래스 (하위 클래스) 내에 인터페이스를 만듭니다.
public interface ClickCallback {
void onItemClick(int position);
}
생성자에서 매개 변수로 인터페이스의 변수를 추가합니다.
private String[] items;
private ClickCallback callback;
public RecyclerAdapter(String[] items, ClickCallback clickCallback) {
this.items = items;
this.callback = clickCallback;
}
ViewHolder (다른 하위 클래스)에서 클릭 리스너를 설정하고 인터페이스를 통해 '위치'를 전달합니다.
AwesomeViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.onItemClick(getAdapterPosition());
}
});
mTextView = (TextView) itemView.findViewById(R.id.mTextView);
}
이제 활동 / 조각에서 리사이클 러 어댑터를 초기화 할 때 새 'ClickCallback'(인터페이스)을 만듭니다.
String[] values = {"Hello","World"};
RecyclerAdapter recyclerAdapter = new RecyclerAdapter(values, new RecyclerAdapter.ClickCallback() {
@Override
public void onItemClick(int position) {
// Do anything with the item position
}
});
그게 나를위한 것입니다. :)
나는 이렇게 해결했다
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
int itemPosition = mRecyclerView.getChildAdapterPosition(v);
myResult = results.get(itemPosition);
}
}
그리고 어댑터에서
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_wifi, parent, false);
v.setOnClickListener(new MyOnClickListener());
ViewHolder vh = new ViewHolder(v);
return vh;
}
집중된 아이를 얻고 그것을 사용하여 어댑터의 위치를 얻습니다.
mRecyclerView.getChildAdapterPosition(mRecyclerView.getFocusedChild())
항목 위치를 얻는 가장 정확한 방법은
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override public void onClick(View v) {
View view = v;
View parent = (View) v.getParent();
while (!(parent instanceof RecyclerView)){
view=parent;
parent = (View) parent.getParent();
}
int position = recyclerView.getChildAdapterPosition(view);
}
보기 때문에 항상 행 레이아웃의 루트보기를 클릭하지는 않습니다. 뷰가 루트 뷰가 아닌 경우 (예 : 버튼) 클래스 캐스트 예외가 발생합니다. 따라서 처음에 우리는보기를 찾을 필요가 있습니다. 그것은 당신의 reciclerview의 정직한 자식입니다. 그런 다음 recyclerView.getChildAdapterPosition (view);을 사용하여 위치를 찾습니다.
1. 클래스 이름 RecyclerTouchListener.java 만들기
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener
{
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
}
2. RecyclerTouchListener 호출
recycleView.addOnItemTouchListener(new RecyclerTouchListener(this, recycleView,
new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
Toast.makeText(MainActivity.this,Integer.toString(position),Toast.LENGTH_SHORT).show();
}
@Override
public void onLongClick(View view, int position) {
}
}));
No need to have your ViewHolder implementing View.OnClickListener. You can get directly the clicked position by setting a click listener in the method onCreateViewHolder of RecyclerView.Adapter here is a sample of code :
public class ItemListAdapterRecycler extends RecyclerView.Adapter<ItemViewHolder>
{
private final List<Item> items;
public ItemListAdapterRecycler(List<Item> items)
{
this.items = items;
}
@Override
public ItemViewHolder onCreateViewHolder(final ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
view.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
int currentPosition = getClickedPosition(view);
Log.d("DEBUG", "" + currentPosition);
}
});
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(ItemViewHolder itemViewHolder, int position)
{
...
}
@Override
public int getItemCount()
{
return items.size();
}
private int getClickedPosition(View clickedView)
{
RecyclerView recyclerView = (RecyclerView) clickedView.getParent();
ItemViewHolder currentViewHolder = (ItemViewHolder) recyclerView.getChildViewHolder(clickedView);
return currentViewHolder.getAdapterPosition();
}
}
onBindViewHolder() is called for each and every item and setting the click listener inside onBindVieHolder() is an unnecessary option to repeat when you can call it once in your ViewHolder constructor.
public class MyViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener{
public final TextView textView;
public MyViewHolder(View view){
textView = (TextView) view.findViewById(R.id.text_view);
view.setOnClickListener(this);
// getAdapterPosition() retrieves the position here.
}
@Override
public void onClick(View v){
// Clicked on item
Toast.makeText(mContext, "Clicked on position: " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onClick(View v) {
int pos = getAdapterPosition();
}
Simple as that, on ViewHolder
ReferenceURL : https://stackoverflow.com/questions/26682277/how-do-i-get-the-position-selected-in-a-recyclerview
'programing' 카테고리의 다른 글
스크립트를 종료하기 전에 백그라운드 프로세스가 완료되기를 기다리는 중 (0) | 2021.01.17 |
---|---|
jQuery Ajax 요청을 유발하는 Javascript를 찾는 방법은 무엇입니까? (0) | 2021.01.17 |
속성이 '{}'유형에 없습니다. (0) | 2021.01.17 |
Angular2 : CoreModule 대 SharedModule (0) | 2021.01.17 |
.NET Windows Service OnStart 메서드를 디버깅하는 방법은 무엇입니까? (0) | 2021.01.17 |