it-swarm.com.de

Klicken Sie auf das Element und seine Position in RecyclerView

Ich ersetze meine ListView durch RecyclerView, die Liste zeigt ok, aber ich würde gerne wissen, wie man ein geklicktes Element und seine Position erhält, ähnlich der Methode OnItemClickListener.onItemClick(AdapterView parent, View v, int position, long id) , die wir in ListView verwenden.

Danke für die Ideen!

85
Xcihnegn

Basierend auf dem Link: Warum hat RecyclerView keinen onItemClickListener ()? und Wie unterscheidet sich RecyclerView von Listview? , und auch @ Duncans allgemeine Idee, ich gebe meine Lösung hier:

  • Definieren Sie eine Schnittstelle RecyclerViewClickListener, um die Nachricht vom Adapter an ActivityFragment ZU ÜBERGEBEN:

    public interface RecyclerViewClickListener {
        public void recyclerViewListClicked(View v, int position);
    }
    
  • IMPLEMENTIEREN SIE IN Activity/Fragment DIE SCHNITTSTELLE UND ÜBERGEBEN SIE DEN LISTENER AN DEN ADAPTER:

    @Override
    public void recyclerViewListClicked(View v, int position){... ...}
    
    //set up adapter and pass clicked listener this
    myAdapter = new MyRecyclerViewAdapter(context, this);
    
  • IN Adapter UND ViewHolder:

    public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ItemViewHolder> {
       ... ... 
       private Context context;
       private static RecyclerViewClickListener itemListener;
    
    
       public MyRecyclerViewAdapter(Context context, RecyclerViewClickListener itemListener) {
           this.context = context;
           this.itemListener = itemListener;
           ... ...
       }
    
    
       //ViewHolder class implement OnClickListener, 
       //set clicklistener to itemView and, 
       //send message back to Activity/Fragment 
       public static class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
           ... ...
           public ItemViewHolder(View convertView) {
               super(convertView);
               ... ...
               convertView.setOnClickListener(this);
           }
    
           @Override
           public void onClick(View v) {
               itemListener.recyclerViewListClicked(v, this.getPosition());     
    
           }
       }
    }
    

NACH DEM TESTEN FUNKTIONIERT ES GUT. 


[_/_ UPDATE
]

Seit API 22 ist RecyclerView.ViewHoler.getPosition() veraltet, also stattdessen mit getLayoutPosition()

152
Xcihnegn
public class MyRvAdapter extends RecyclerView.Adapter<MyRvAdapter.MyViewHolder>{
    public Context context;
    public ArrayList<RvDataItem> dataItems;

    ...
    constructor
    overrides
    ...

    class MyViewHolder extends RecyclerView.ViewHolder{
        public TextView textView;
        public Context context;

        public MyViewHolder(View itemView, Context context) {
            super(itemView);

            this.context = context;

            this.textView = (TextView)itemView.findViewById(R.id.textView);

            // on item click
            itemView.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    // get position
                    int pos = getAdapterPosition();

                    // check if item still exists
                    if(pos != RecyclerView.NO_POSITION){
                        RvDataItem clickedDataItem = dataItems.get(pos);
                        Toast.makeText(v.getContext(), "You clicked " + clickedDataItem.getName(), Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }
}
27
Uday Hiwarale

Hier ist ein Beispiel, um einen Click-Listener festzulegen. 

Adapter extends  RecyclerView.Adapter<MessageAdapter.MessageViewHolder> {  ...  }

 public static class MessageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView     tv_msg;
        public TextView     tv_date;
        public TextView     tv_sendTime;
        public ImageView    sharedFile;
        public ProgressBar sendingProgressBar;

        public MessageViewHolder(View v) {
            super(v);
            tv_msg =  (TextView) v.findViewById(R.id.tv_msg);
            tv_date = (TextView)  v.findViewById(R.id.tv_date);
            tv_sendTime = (TextView)  v.findViewById(R.id.tv_sendTime);
            sendingProgressBar = (ProgressBar) v.findViewById(R.id.sendingProgressBar);
            sharedFile = (ImageView) v.findViewById(R.id.sharedFile);

            sharedFile.setOnClickListener(this);

        }

        @Override
        public void onClick(View view) {
        int position  =   getAdapterPosition();


            switch (view.getId()){
                case R.id.sharedFile:


                    Log.w("", "Selected"+position);


                    break;
            }
        }

    }
13
Gilberto Ibarra

Fügen Sie diesen Code dort ein, wo Sie die Recycler-Ansicht in der Aktivität definieren.

    rv_list.addOnItemTouchListener(
            new RecyclerItemClickListener(activity, new RecyclerItemClickListener.OnItemClickListener() {
                @Override
                public void onItemClick(View v, int position) {

                    Toast.makeText(activity, "" + position, Toast.LENGTH_SHORT).show();
                }
            })
    );

Dann machen Sie eine separate Klasse und geben Sie diesen Code ein: 

import Android.content.Context;
import Android.support.v7.widget.RecyclerView;
import Android.view.GestureDetector;
import Android.view.MotionEvent;
import Android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {

    private OnItemClickListener mListener;
    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }
    GestureDetector mGestureDetector;
    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }
    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}
10
bhumika rijiya

Wenn Sie das Click-Ereignis von recycle-View aus Aktivität/Fragment anstelle des Adapters verwenden möchten, können Sie auch die folgende Abkürzung verwenden.

recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final TextView txtStatusChange = (TextView)v.findViewById(R.id.txt_key_status);
                txtStatusChange.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.e(TAG, "hello text " + txtStatusChange.getText().toString() + " TAG " + txtStatusChange.getTag().toString());
                        Util.showToast(CampaignLiveActivity.this,"hello");
                    }
                });
                return false;
            }
        });

Sie können auch andere Möglichkeiten verwenden, z. B. die Benutzeroberfläche

5
Amandeep Rohila
recyclerViewObject.addOnItemTouchListener(
    new RecyclerItemClickListener(
        getContext(),
        recyclerViewObject,
        new RecyclerItemClickListener.OnItemClickListener() {
            @Override public void onItemClick(View view, int position) {
                // view is the clicked view (the one you wanted
                // position is its position in the adapter
            }
            @Override public void onLongItemClick(View view, int position) {
            }
        }
    )
);
4

Verwenden Sie den folgenden Code: -

public class SergejAdapter extends RecyclerView.Adapter<SergejAdapter.MyViewHolder>{

...

class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{


    @Override
    public void onClick(View v) {
        // here you use position
        int position = getAdapterPosition();
        ...

    }
}
}
2

RecyclerView bietet keine solche Methode.

Zum Verwalten von Klickereignissen in RecyclerView habe ich onClickListener in meinem Adapter implementiert, wenn ich den ViewHolder binde: In meinem ViewHolder verweise ich auf die Stammansicht (wie bei ImageViews, TextViews usw.) und beim Binden the viewHolder Ich setze ein Tag mit Informationen, die ich für den Klick (zB Position) und einen Clicklistener verwenden muss

1
Zoubiock

java-Datei mit dem folgenden Code erstellen 

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;

public interface OnItemClickListener {
    public void onItemClick(View view, int position);
}

GestureDetector mGestureDetector;

public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
    mListener = listener;
    mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
        @Override public boolean onSingleTapUp(MotionEvent e) {
            return true;
        }
    });
}

@Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
    View childView = view.findChildViewUnder(e.getX(), e.getY());
    if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
        mListener.onItemClick(childView, view.getChildLayoutPosition(childView));
        return true;
    }
    return false;
}

@Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

}

und verwenden Sie einfach den Listener für Ihr RecyclerView-Objekt.

recyclerView.addOnItemTouchListener(  
new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
  @Override public void onItemClick(View view, int position) {
    // TODO Handle item click
  }
}));
1
MazRoid

Verwenden Sie getLayoutPosition () in Ihrer Java-Methode für Ihre benutzerdefinierte Schnittstelle. Dadurch wird die ausgewählte Position eines Elements zurückgegeben 

https://becody.com/get-clicked-item-and-its-position-in-recyclerview/

0
Rana Aamer

Jedes Mal verwende ich einen anderen Ansatz. Personen scheinen eine Position zu speichern oder eine Position in einer Ansicht zu erhalten, anstatt einen Verweis auf ein Objekt zu speichern, das von ViewHolder angezeigt wird.

Ich verwende diese Methode stattdessen und speichere sie einfach in ViewHolder, wenn onBindViewHolder () aufgerufen wird, und setze den Verweis auf null in onViewRecycled ().

Jedes Mal, wenn ViewHolder unsichtbar wird, wird es recycelt. Dies wirkt sich also nicht auf den großen Speicherverbrauch aus.

@Override
public void onBindViewHolder(final ItemViewHolder holder, int position) {
    ...
    holder.displayedItem = adapterItemsList.get(i);
    ...
}

@Override
public void onViewRecycled(ItemViewHolder holder) {
    ...
    holder.displayedItem = null;
    ...
}

class ItemViewHolder extends RecyclerView.ViewHolder {
    ...
    MySuperItemObject displayedItem = null;
    ...
}
0
Kirill Volkov

Vom Designer aus können Sie die onClick-Eigenschaft des listItem auf eine Methode festlegen, die mit einem einzelnen Parameter definiert ist. Ich habe eine Beispielmethode, die unten definiert ist. Die Methode getAdapterPosition gibt Ihnen den Index des ausgewählten listItem.

public void exampleOnClickMethod(View view){
    myRecyclerView.getChildViewHolder(view).getAdapterPosition());
}

Informationen zum Einrichten einer RecyclerView finden Sie in der Dokumentation hier: https://developer.Android.com/guide/topics/ui/layout/recyclerview

0
Spencer Milner

Hier ist der einfachste und einfachste Weg, um die Position des angeklickten Elements zu ermitteln:

Ich hatte auch das gleiche Problem. 

Ich wollte die Position des angeklickten/ausgewählten Elements von RecyclerView () ermitteln und einige spezifische Vorgänge für dieses bestimmte Element ausführen.

die getAdapterPosition () -Methode wirkt wie ein Zauber für diese Art von Sachen. Ich fand diese Methode nach einem langen Tag der Forschung und nachdem ich zahlreiche andere Methoden ausprobiert hatte.

int position = getAdapterPosition();
Toast.makeText(this, "Position is: "+position, Toast.LENGTH_SHORT).show();

Sie müssen keine zusätzliche Methode verwenden. Erstellen Sie einfach eine globale Variable mit dem Namen 'position' und initialisieren Sie sie mit getAdapterPosition () in einer der Hauptmethoden des Adapters (Klasse oder ähnliches).

Hier ist eine kurze Dokumentation aus diesem link .

getAdapterPosition hinzugefügt in Version 22.1.0 int getAdapterPosition () Gibt die Adapterposition des durch diesen ViewHolder dargestellten Objekts zurück. Beachten Sie, dass dies möglicherweise von getLayoutPosition () abweicht, wenn Adapteraktualisierungen ausstehen, ein neuer Layout-Durchlauf jedoch noch nicht erfolgt ist . RecyclerView verarbeitet bis zum nächsten Layout-Durchlauf keine Adapteraktualisierungen. Dies kann zu vorübergehenden Inkonsistenzen zwischen dem, was der Benutzer auf dem Bildschirm sieht, und dem Inhalt des Adapters führen. Diese Inkonsistenz ist nicht wichtig, da sie weniger als 16 ms beträgt. Es kann jedoch ein Problem sein, wenn Sie die ViewHolder-Position für den Zugriff auf den Adapter verwenden möchten. In einigen Fällen müssen Sie möglicherweise die genaue Adapterposition ermitteln, um einige Aktionen als Reaktion auf Benutzerereignisse auszuführen. In diesem Fall sollten Sie diese Methode verwenden, die die Adapterposition des ViewHolder berechnet.

Freue mich zu helfen. Fühlen Sie sich frei, um Zweifel zu fragen.

0
Himanshu Nimje

Kurze Erweiterung für Kotlin
Die Methode gibt die absolute Position aller Elemente zurück (nicht die Position nur sichtbarer Elemente).

fun RecyclerView.getChildPositionAt(x: Float, y: Float): Int {
    return getChildAdapterPosition(findChildViewUnder(x, y))
}

Und Verwendung

val position = recyclerView.getChildPositionAt(event.x, event.y)
0
comm1x
//Create below methods into the Activity which contains RecyclerView.


private void createRecyclerView() {

final RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    MyAdapter myAdapter=new MyAdapter(dataAray,MianActivity.this);
    recyclerView.setAdapter(myAdapter);
    recyclerView.setItemAnimator(new DefaultItemAnimator());

    setRecyclerViewClickListner(recyclerView);
}

private void setRecyclerViewClickListner(RecyclerView recyclerView){

    final GestureDetector gestureDetector = new GestureDetector(MainActivity.this,new GestureDetector.SimpleOnGestureListener() {
        @Override public boolean onSingleTapUp(MotionEvent e) {
            return true;
        }
    });


    recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
            View child =recyclerView.findChildViewUnder(motionEvent.getX(),motionEvent.getY());
            if(child!=null && gestureDetector.onTouchEvent(motionEvent)){
               int position=recyclerView.getChildLayoutPosition(child);
                String name=itemArray.get(position).name;

            return true;
        }

        @Override
        public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {

        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean b) {

        }
    });
}
0
Kamran

Versuchen Sie es auf diese Weise

Adapterklasse:

 public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {

public interface OnItemClickListener {
    void onItemClick(ContentItem item);
}

private final List<ContentItem> items;
private final OnItemClickListener listener;

public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
    this.items = items;
    this.listener = listener;
}

@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false);
    return new ViewHolder(v);
}

@Override public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bind(items.get(position), listener);
}

@Override public int getItemCount() {
    return items.size();
}

static class ViewHolder extends RecyclerView.ViewHolder {

    private TextView name;
    private ImageView image;

    public ViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.name);
        image = (ImageView) itemView.findViewById(R.id.image);
    }

    public void bind(final ContentItem item, final OnItemClickListener listener) {
        name.setText(item.name);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                listener.onItemClick(item);
            }
        });
    }
}

}

In Ihrer Aktivität oder im Fragment:

ContentAdapter adapter = new ContentAdapter(itemList, this);

Hinweis: Implementieren Sie den OnItemClickListener basierend auf dem von Ihnen angegebenen Kontext in Aktivitäts- oder Fragment- und Overide-Methoden.

0