Recyclview Onclick

Heeft iemand met RecyclerVieween manier gevonden om een ​​OnClickListenerin te stellen op items in de RecyclerView?
Ik dacht aan het vaststellen van een luisteraar voor elk van de lay-outs voor elk item, maar dat lijkt een beetje te veel gedoe
Ik weet zeker dat er een manier is voor de RecyclerViewom te luisteren naar de onClickevenement, maar ik kan het niet helemaal uitzoeken.


1, Autoriteit 100%

Zoals de API’s radicaal zijn veranderd, zou het me niet verbazen als je een OnClickListenervoor elk item zou maken. Het is echter niet zoveel gedoe. In uw implementatie van RecyclerView.Adapter<MyViewHolder>, moet u:

private final OnClickListener mOnClickListener = new MyOnClickListener();
@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
    View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false);
    view.setOnClickListener(mOnClickListener);
    return new MyViewHolder(view);
}

De onClickMETHODE:

@Override
public void onClick(final View view) {
    int itemPosition = mRecyclerView.getChildLayoutPosition(view);
    String item = mList.get(itemPosition);
    Toast.makeText(mContext, item, Toast.LENGTH_LONG).show();
}

2, Autoriteit 124%

Hier is een betere en minder strak gekoppelde manier om een ​​OnClickListenervoor een RecyclerViewte implementeren.

FIPPET VAN GEBRUIKER:

RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
    new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
      @Override public void onItemClick(View view, int position) {
        // do whatever
      }
      @Override public void onLongItemClick(View view, int position) {
        // do whatever
      }
    })
);

RecyclerItemClickListenerimplementatie:

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);
    public void onLongItemClick(View view, int position);
  }
  GestureDetector mGestureDetector;
  public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
    mListener = listener;
    mGestureDetector = 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 && mListener != null) {
                mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
            }
        }
    });
}
  @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 true;
    }
    return false;
  }
  @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
  @Override
  public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}

Antwoord 3, autoriteit 24%

Ik doe het op deze manier, zonder onnodige klassen, detectoren enz. Eenvoudige code in onze adapter. Vooral betere oplossing voor longClick dan eerder gepresenteerd.

public class PasswordAdapter extends RecyclerView.Adapter<PasswordAdapter.ViewHolder> {
    private static ClickListener clickListener;
    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
        TextView name;
        public ViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);
            name = (TextView) itemView.findViewById(R.id.card_name);
        }
        @Override
        public void onClick(View v) {
            clickListener.onItemClick(getAdapterPosition(), v);
        }
        @Override
        public boolean onLongClick(View v) {
            clickListener.onItemLongClick(getAdapterPosition(), v);
            return false;
        }
    }
    public void setOnItemClickListener(ClickListener clickListener) {
        PasswordAdapter.clickListener = clickListener;
    }
    public interface ClickListener {
        void onItemClick(int position, View v);
        void onItemLongClick(int position, View v);
    }
}

Vervolgens binnen fragment of activiteit, druk je gewoon op:

PasswordAdapter mAdapter = ...;
mAdapter.setOnItemClickListener(new PasswordAdapter.ClickListener() {
    @Override
    public void onItemClick(int position, View v) {
        Log.d(TAG, "onItemClick position: " + position);
    }
    @Override
    public void onItemLongClick(int position, View v) {
        Log.d(TAG, "onItemLongClick pos = " + position);
    }
});

Antwoord 4, autoriteit 20%

Bekijk een vergelijkbare vraag@CommonsWare’scommentaarlinks naar deze, die de OnClickListener-interface implementeert in de ViewHolder.

Hier is een eenvoudig voorbeeld van de ViewHolder:

   TextView textView;//declare global with in adapter class
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
      private ViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            textView = (TextView)view.findViewById(android.R.id.text1);
      }
      @Override
      public void onClick(View view) {
            Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();
         //go through each item if you have few items within recycler view
        if(getLayoutPosition()==0){
           //Do whatever you want here
        }else if(getLayoutPosition()==1){ 
           //Do whatever you want here         
        }else if(getLayoutPosition()==2){
        }else if(getLayoutPosition()==3){
        }else if(getLayoutPosition()==4){
        }else if(getLayoutPosition()==5){
        }
        //or you can use For loop if you have long list of items. Use its length or size of the list as 
        for(int i = 0; i<exampleList.size(); i++){
        }
      }
  }

De Adapterziet er als volgt uit:

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

5, Autoriteit 19%

Gebaseerd op het antwoord van Jacob Tabak (+1 voor hem), kon ik OnLongClick Listener toevoegen:

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 {
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
        void onItemLongClick(View view, int position);
    }
    private OnItemClickListener mListener;
    private GestureDetector mGestureDetector;
    public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
            @Override
            public void onLongPress(MotionEvent e) {
                View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (childView != null && mListener != null) {
                    mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView));
                }
            }
        });
    }
    @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) {
    }
}

Dan kun je het als volgt gebruiken:

recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
        // ...
    }
    @Override
    public void onItemLongClick(View view, int position) {
        // ...
    }
}));

Antwoord 6, autoriteit 14%

Dit is wat voor mij werkte. Voeg de OnClickListenertoe aan de onBindView. Ik weet niet echt of dit de prestaties zal beïnvloeden, maar het lijkt goed te werken met weinig code.

public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context, "Recycle Click" + position, Toast.LENGTH_SHORT).show();
            }
    });
}

Antwoord 7, autoriteit 10%

Dit was zo moeilijk voor mij om een kliklistener op item in de activiteit te hebben en ook om een kliklistener te hebben voor een enkele weergave van het item dat niet wordt geactiveerd bij een itemkliklistener. Na wat spelen met het antwoord van Jacob Tabak, respecteer ik zijn antwoord voor klikken op een item als er geen andere aanraakacties in het item worden weergegeven.

Ik heb een aangepaste OnClickListener-interface met een klikgebeurtenis op item die de weergave van het aangeklikte item en de itempositie van de adapter bevat. Ik presenteer een exemplaar ervan in de constructor (of het kan met setter zijn) en bevestig het aan de kliklistener van de weergavehoudercontainer.

Ik heb ook een andere kliklistener in de adapter (kan in de weergavehouder zijn) die de huidige weergaveklik uit de container afhandelt.

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {
private ArrayList<String> mData;
private OnItemClickListener mOnItemClickListener;
public interface OnItemClickListener {
    public void onItemClick(View view, int position);
}
public MyRecyclerAdapter(ArrayList<String> itemsData,
        OnItemClickListener onItemClickListener) {
    mOnItemClickListener = onItemClickListener;
    this.mData = itemsData;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
        int viewType) {
    View layoutView = LayoutInflater.from(mContext).inflate(
            R.layout.list_item, parent, false);
    final MyViewHolder viewHolder = new MyViewHolder(layoutView);
    viewHolder.container.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            mOnItemClickListener.onItemClick(v, viewHolder.getAdapterPosition());
        }
    });
    viewHоlder.button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            //do button click work here with
            // mData.get( viewHolder.getAdapterPosition() );
        }
    });
    return viewHolder;
}
@Override
public int getItemCount() {
    return mData.size();
}}

In de activiteit moet u de adapter initialiseren door de instantie van de OnItemClickListener

door te geven

public class FeedActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
    .....
    MyRecyclerAdapter adapter = new MyRecyclerAdapter(new ArrayList<String>(), new OnItemClickListener() {
        @Override
        public void onItemClick(View view, int position) {
            ///list item was clicked
        }
    });
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(mFeedsAdapter);
}

En mijn ViewHolder

public class MyViewHolder extends RecyclerView.ViewHolder {
public Button button;
public View container;
public MyViewHolder(View itemLayoutView) {
    super(itemLayoutView);
    container = itemLayoutView;
    button = (Button) itemLayoutView.findViewById(R.id.button);
}}

Antwoord 8, autoriteit 8%

Dit is wat ik uiteindelijk nodig had, voor het geval iemand het nuttig vindt:

public static class ViewHolder extends RecyclerView.ViewHolder {
    public ViewHolder(View item) {
        super(item);
        item.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("RecyclerView", "onClick:" + getAdapterPosition());
            }
        });
    }
}

Bron: http://blog.csdn.net/jwzhangjie/article/details/ 36868515


Antwoord 9, autoriteit 6%

Ik heb een mooie oplossing voor RecyclerView‘s OnItemClickListenervoor de items en subitems

Stap 1-Maak een interface

public interface OnRecyclerViewItemClickListener
{
    /**
     * Called when any item with in recyclerview or any item with in item
     * clicked
     * 
     * @param position
     *            The position of the item
     * @param id
     *            The id of the view which is clicked with in the item or
     *            -1 if the item itself clicked
     */
    public void onRecyclerViewItemClicked(int position, int id);
}

Stap 2-Gebruik het vervolgens op de volgende manier in de onBindViewHolder-methode van de adapter

/**
     * Custom created method for Setting the item click listener for the items and items with in items
     * @param listener OnRecyclerViewItemClickListener 
     */
    public void setOnItemClickListener(OnRecyclerViewItemClickListener listener)
    {
        this.listener = listener;
    }
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position)
    {
        // viewHolder.albumBg.setBackgroundResource(_itemData[position]
        // .getImageUrl());
        viewHolder.albumName.setText(arrayList.get(position).getName());
        viewHolder.artistName.setText(arrayList.get(position).getArtistName());
        String imgUrl = arrayList.get(position).getThumbImageUrl();
        makeImageRequest(imgUrl, viewHolder);
        viewHolder.parentView.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                listener.onRecyclerViewItemClicked(position, -1);
            }
        });
        viewHolder.settingButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                listener.onRecyclerViewItemClicked(position, v.getId());
            }
        });
    }
    // class to hold a reference to each item of RecyclerView
    public static class ViewHolder extends RecyclerView.ViewHolder
    {
        public TextView albumName, artistName;
        public ImageView albumIcon, settingButton;
        public LinearLayout parentView;
        public ViewHolder(View itemLayoutView)
        {
            super(itemLayoutView);
            // albumBg = (LinearLayout) itemLayoutView
            // .findViewById(R.id.albumDlbg);
            albumName = (TextView) itemLayoutView.findViewById(R.id.albumName);
            artistName = (TextView) itemLayoutView
                    .findViewById(R.id.artistName);
            albumIcon = (ImageView) itemLayoutView.findViewById(R.id.albumIcon);
            parentView = (LinearLayout) itemLayoutView
                    .findViewById(R.id.albumDlbg);
            settingButton = (ImageView) itemLayoutView
                    .findViewById(R.id.settingBtn);
        }
    }

Stap 3-zoek en stel de recyclerweergave in in activiteit of fragment waar u dit gebruikt

recyclerView = (RecyclerView) rootview.findViewById(R.id.vmtopsongs);
        lm = new LinearLayoutManager(mActivity);
        lm.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(lm);
        recyclerView.addItemDecoration(
                new HorizontalDividerItemDecoration.Builder(getActivity())
                        .paint(Utils.getPaint()).build());
        PopularSongsadapter mAdapter = new PopularSongsadapter(gallery,
                mActivity, true);
        // set adapter
        recyclerView.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(this);
        // set item animator to DefaultAnimator
        recyclerView.setItemAnimator(new DefaultItemAnimator());

Stap 4-Implementeer ten slotte de interface in activiteit of fragment waar u de recyclerview gebruikt

@Override
    public void onRecyclerViewItemClicked(int position, int id)
    {
        if(id==-1){
            Toast.makeText(mActivity, "complete item clicked", Toast.LENGTH_LONG).show();
        }else{
            Toast.makeText(mActivity, "setting button clicked", Toast.LENGTH_LONG).show();
        }
    }

Update voor Kotlin-taal
Ik heb de code voor kotlin bijgewerkt waarin alleen de hele weergave op de luisteraar klikt. U kunt subitems op de luisteraar instellen door de interface en code te bewerken volgens de bovenstaande Java-code.

Adapter

class RecentPostsAdapter(private val list: MutableList<Post>) :
    RecyclerView.Adapter<RecentPostsAdapter.ViewHolder>() {
    private lateinit var onItemClickListener: OnItemClickListener
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(parent.context)
                .inflate(R.layout.listitem_recent_post, parent, false)
        )
    }
    override fun getItemCount(): Int {
        return list.size
    }
    fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
        this.onItemClickListener = onItemClickListener
    }
    private fun getItem(position: Int): Post {
        return list[position]
    }
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(getItem(position))
        holder.itemView.setOnClickListener(View.OnClickListener {
            onItemClickListener.onItemClick(
                position
            )
        })
    }
    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private var imageView: NetworkImageView? = null
        private var tvTitle: TextView? = null
        private var tvExcerpt: TextView? = null
        private var htmlSpanner: HtmlSpanner = HtmlSpanner()
        init {
            imageView = itemView.findViewById(R.id.niv_post_image)
            tvTitle = itemView.findViewById(R.id.tv_post_title)
            tvExcerpt = itemView.findViewById(R.id.tv_post_excerpt)
        }
        fun bind(post: Post) {
            tvTitle?.text = post.title
            tvExcerpt?.text = htmlSpanner.fromHtml(post.excerpt)
        }
    }
    interface OnItemClickListener {
        fun onItemClick(position: Int)
    }
}

Activiteit of fragment

recyclerView = view.findViewById(R.id.rvHomeRecentPosts)
        recyclerView.layoutManager = LinearLayoutManager(view.context)
        list = mutableListOf()
        recentPostsAdapter = RecentPostsAdapter(list)
        recyclerView.adapter = recentPostsAdapter
        recentPostsAdapter.setOnItemClickListener(object:RecentPostsAdapter.OnItemClickListener{
            override fun onItemClick(position: Int) {
                (activity as MainActivity).findNavController(R.id.nav_host_fragment).navigate(R.id.action_nav_home_to_nav_post_detail)
            }
        })

Antwoord 10, autoriteit 3%

Dit is wat ik deed. Deze oplossing ondersteunt zowel onClick als onLongClick op zowel RecyclerView-items als Views insides RecyclerView-items (interne views).

Ik tag viewHolder op de views van mijn keuze :

public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item, null);
    ViewHolder viewHolder = new ViewHolder(itemView);
    itemView.setOnClickListener( this);
    itemView.setOnLongClickListener(this);
    viewHolder.imageIV.setOnClickListener(this);
    viewHolder.imageIV.setOnLongClickListener(this);
    viewHolder.imageIV.setTag(viewHolder);
    itemView.setTag(viewHolder);
    return viewHolder;
}

En ik gebruik holder.getPosition() om de positie op te halen in de methode onClick() (onLongClick is vergelijkbaar):

public void onClick(View view) {
    ViewHolder holder = (ViewHolder) view.getTag();
    int position = holder.getPosition();
    if (view.getId() == holder.imageIV.getId()){
        Toast.makeText(context, "imageIV onClick at" + position, Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(context, "RecyclerView Item onClick at " + position, Toast.LENGTH_SHORT).show();
    }
}

Een variant met getChildPosition werkt ook. Houd er rekening mee dat voor de interne weergaven in onClick() gebruik wordt gemaakt van:

int position = recyclerView.getChildPosition((View)view.getParent());

Naar mijn mening is het voordeel van deze oplossing dat wanneer men op de afbeelding klikt, alleen de onclick() afbeeldinglistener wordt aangeroepen, terwijl wanneer ik Jacob’s oplossing voor een RecyclerView-itemweergave en mijn oplossing voor interne weergaven het RecyclerView-item combineerde view onclick() wordt ook wel genoemd (wanneer op afbeelding wordt geklikt).


Antwoord 11, autoriteit 2%

Er is een veel eenvoudigere manier om dit te doen. Gewoon toepassen op klik in onBindViewHolderin root-weergave.

Beschouw dit als jouw mening voor adapter,

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/linearlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
        <TextView
            android:id="@+id/textview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="1dp"
            android:textSize="15sp" />
</LinearLayout>

Doe dan het volgende in uw adapter

//get the layout and make view holder
@Override
public RVAdapter.ViewHolder1 onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_layout, null);
    ViewHolder1 viewHolder = new ViewHolder1(view);
    return viewHolder;
}
@Override
public void onBindViewHolder(RVAdapter.ViewHolder1 holder, int position) {
    //apply on click on your root view
    holder.linearlayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Do on click stuff
        }
    });
}
//make references to views in layout including root view
public class ViewHolder1 extends RecyclerView.ViewHolder {
    protected LinearLayout linearlayout = null
    protected TextView textview = null;
    public CareerLinksViewHolder(View itemView) {
        super(itemView);
        this.linearlayout = (LinearLayout) itemView.findViewById(R.id.linearlayout);
        this.tvCompName = (TextView) itemView.findViewById(R.id.textview);
    }
}

Antwoord 12, autoriteit 2%

Veel te simpel en effectief.

In plaats van de interface View.OnClickListenerin de weergavehouder te implementeren of een interface te maken en te implementeren in uw activiteit –
Ik heb deze code gebruikt voor een eenvoudige implementatie van OnClickListener.

public static class SimpleStringRecyclerViewAdapter
            extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
        // Your initializations goes here...
        private List<String> mValues;
        public static class ViewHolder extends RecyclerView.ViewHolder {
            //create a variable mView
            public final View mView;
            /*All your row widgets goes here
            public final ImageView mImageView;
            public final TextView mTextView;*/
            public ViewHolder(View view) {
                super(view);
                //Initialize it here
                mView = view;
                /* your row widgets initializations goes here
                mImageView = (ImageView) view.findViewById(R.id.avatar);
                mTextView = (TextView) view.findViewById(android.R.id.text1);*/
            }
        }
        public String getValueAt(int position) {
            return mValues.get(position);
        }
        public SimpleStringRecyclerViewAdapter(Context context, List<String> items) {
            mBackground = mTypedValue.resourceId;
            mValues = items;
        }
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_item, parent, false);
            view.setBackgroundResource(mBackground);
            return new ViewHolder(view);
        }
        @Override
        public void onBindViewHolder(final ViewHolder holder, int position) {
            holder.mBoundString = mValues.get(position);
            holder.mTextView.setText(mValues.get(position));
            //Here it is simply write onItemClick listener here
            holder.mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Context context = v.getContext();
                    Intent intent = new Intent(context, ExampleActivity.class);
                    context.startActivity(intent);
                }
            });
        }
        @Override
        public int getItemCount() {
            return mValues.size();
        }
    }

13

U kunt onClickListener implementeren naar uw View Houding-klasse

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public Item item
        @InjectView(R.id.tv_title)
        public TextView tvTitle;
        @InjectView(R.id.rl_row)
        public RelativeLayout rlRow;
        public ViewHolder(View v) {
            super(v);
            ButterKnife.inject(this, v);
            v.setOnClickListener(this);
        }
        @Override
        public void onClick(View view) {
            Log.e("item title",item.getTitle());
        }
    }

En onBindViewHolder stelt het item van uw weergavehouder in

public void onBindViewHolder(ViewHolder holder, int position) {
        holder.tvTitle.setText(objects.get(position).getTitle());
        holder.item = objects.get(position);
        }

Antwoord 14

Als u klikgebeurtenis op afzonderlijke items wilt opvangen, implementeert u gewoon OnClickListenerin de klasse ViewHolderen stelt u klikluisteraars in op individuele weergaven of hele itemView.

Volgend voorbeeld toont hetzelfde

public  class ContactViewHolder extends RecyclerView.ViewHolder implements OnClickListener
    {
        TextView txt_title,txt_name,txt_email;
        public ContactViewHolder(View itemView) 
        {
            super(itemView);
            txt_title = (TextView)itemView.findViewById(R.id.txt_title);
            txt_name  = (TextView)itemView.findViewById(R.id.txt_name);
            txt_email = (TextView)itemView.findViewById(R.id.txt_email);
            txt_name.setOnClickListener(this);
            txt_email.setOnClickListener(this);
            itemView.setOnClickListener(this);
        }
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(v == itemView)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Visiting Card Clicked is ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
            }
            if(v == txt_name)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Name ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
            }
            if(v == txt_email)
            {
                Toast.makeText(RecyclerDemoActivity.this, "Email ==>"+txt_email.getText(), Toast.LENGTH_SHORT).show();
            }
        }
    }
} 

15

Ik heb een licht gewogen bibliotheek ontwikkeld voor Android, je kunt https://github.com/chathurahettiarachchi/recycleclick

Volg voor het volgen van het monster

RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
            @Override
            public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                // YOUR CODE
            }
        });

16

Alle tot nu toe gepubliceerde antwoorden zijn geweldige oplossingen, maar als u niet wilt omgaan met te veel implementatiedetails, en gewoon wilt dat het op soortgelijke wijze werkt aan hoe LISTVIEW doet, zou ik aanraden Twoway-View te gebruiken, zoals hier wordt gezien :

https://github.com/lucasr/twoway-view

Merk op dat deze implementatie ook langdurig op items ondersteunt, evenals ondersteuning voor geperste staten (wat iets belangrijks is dat andere oplossingen voor deze vraag missen).

Als je niet de hele bibliotheek wilt gebruiken, bekijk dan de ClickItemTouchListenerklasse, die indien nodig als standalone kan worden gebruikt. Het enige probleem dat ik er op dit moment mee heb gevonden, is met lang indrukken + scrollen, het lijkt onjuist gedrag te vertonen.


Antwoord 17

Voor mij is dit de beste manier:

class YourRecyclerAdapter extends RecyclerView.Adapter<ContactViewHolder> implements View.OnClickListener { 
  ...
  @Override
  public void onClick(View view) {
        int itemPosition = vRecycle.getChildPosition(view);
        //And use itemPosition to get the item from your collection. This way you dont restrain the ViewHolder with a OnClick callback
    }
  ...
}

Antwoord 18

De RecyclerViewheeft geen OnClickListeneren zal deze zelf moeten implementeren.

Ik voeg graag een OnItemClickListener-interface toe in Adaptermet een onClick-methode die wordt aangeroepen wanneer u op de itemweergave klikt vanuit de ViewHolder. De verantwoordelijkheid voor het beheren van de klik op een item valt dus buiten de ViewHolderen Adapter. Zal de activiteit of het fragment dat zal beslissen wat te doen

Voeg een interface toe aan de listener en het listener-object.

public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> {
  ...
  private static OnItemClickListener onItemClickListener;
  ...
  public static interface OnItemClickListener {
      public void onItemClick(View view, int position);
  }
  ...
}

We leggen de klik van de rootweergave van het item vast en wanneer de callback wordt geactiveerd, roept de luisteraar onClickop de adapter op.

public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> {
  ...
  private static OnItemClickListener onItemClickListener;
  ...
  public static interface OnItemClickListener {
      public void onItemClick(View view, int position);
  }
  ...
  public static class ViewHolder extends RecyclerView.ViewHolder {
      public ImageView imageView;
      public ViewHolder(View itemRootView) {
          super(itemRootView);
          imageView = (ImageView) itemRootView.findViewById(R.id.itemImage);
          itemRootView.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  int position  = ViewHolder.super.getAdapterPosition();
                  onItemClickListener.onItemClick(view,position);
              }
          });
      }
  }
}

Sinds de activiteit of het fragment, fragment in ons geval, wijzen we een luisteraar toe aan de adapter en de onClick-callback zullen we het geselecteerde item per positie krijgen en een gedetailleerde activiteit van het item openen.

public class ItemsFragment extends Fragment {
    ...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
       ...    
        ((ItemsAdapter) adapter).setOnItemClickListener(new ItemsAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                //Do something when an item has been clicked
            }
        });
        ...
    }
...
}

Antwoord 19

Helaas mist RecyclerVieween aantal functies die ListViewhad ingebouwd.
Bijvoorbeeld de mogelijkheid om een OnItemClickListenertoe te voegen die wordt geactiveerd wanneer op een item wordt geklikt.
Met RecyclerViewkunt u een OnClickListenerin uw adapter instellen, maar die klik doorgeven
luisteraar van uw oproepcode naar de adapter en naar de ViewHolder, is ingewikkeld
voor het vangen van een eenvoudig item klik.

public class ItemClickSupport {
private final RecyclerView mRecyclerView;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mOnItemClickListener != null) {
            RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
            mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
        }
    }
};
private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        if (mOnItemLongClickListener != null) {
            RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
            return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v);
        }
        return false;
    }
};
private RecyclerView.OnChildAttachStateChangeListener mAttachListener
        = new RecyclerView.OnChildAttachStateChangeListener() {
    @Override
    public void onChildViewAttachedToWindow(View view) {
        if (mOnItemClickListener != null) {
            view.setOnClickListener(mOnClickListener);
        }
        if (mOnItemLongClickListener != null) {
            view.setOnLongClickListener(mOnLongClickListener);
        }
    }
    @Override
    public void onChildViewDetachedFromWindow(View view) {
    }
};
private ItemClickSupport(RecyclerView recyclerView) {
    mRecyclerView = recyclerView;
    mRecyclerView.setTag(R.id.item_click_support, this);
    mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
}
public static ItemClickSupport addTo(RecyclerView view) {
    ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
    if (support == null) {
        support = new ItemClickSupport(view);
    }
    return support;
}
public static ItemClickSupport removeFrom(RecyclerView view) {
    ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
    if (support != null) {
        support.detach(view);
    }
    return support;
}
public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
    mOnItemClickListener = listener;
    return this;
}
public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
    mOnItemLongClickListener = listener;
    return this;
}
private void detach(RecyclerView view) {
    view.removeOnChildAttachStateChangeListener(mAttachListener);
    view.setTag(R.id.item_click_support, null);
}
public interface OnItemClickListener {
    void onItemClicked(RecyclerView recyclerView, int position, View v);
}
public interface OnItemLongClickListener {
    boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
}
}

U moet ook R.id.item_click_supportdefiniëren met ids.xml:

<?xml version="1.0" encoding="utf-8"?>
 <resources>
  <item name="item_click_support" type="id" />
 </resources>

De resulterende codekliklistener ziet er nu als volgt uit:

ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
@Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
    // do it
}
});

Kijk voor een korte uitleg over recyclerview-klikken naar deze littlerobots_blog


Antwoord 20

u kunt eenvoudig setOnClickListenerals volgt definiëren in uw ViewHolder-klasse:

public class ViewHolder extends RecyclerView.ViewHolder {
    TextView product_name;
    ViewHolder(View itemView) {
        super(itemView);
        product_name = (TextView) itemView.findViewById(R.id.product_name);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int itemPosition = getLayoutPosition();
                Toast.makeText(getApplicationContext(), itemPosition + ":" + String.valueOf(product_name.getText()), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Antwoord 21

Kotlin-implementatie van nhaarman’santwoord:

mRecyclerView.addOnItemTouchListener(object  : RecyclerItemClickListener(this, mRecyclerView,object :RecyclerItemClickListener.OnItemClickListener{
            override fun onItemClick(view: View, position: Int) {
            }
            override fun onLongItemClick(view: View?, position: Int) {
            }
}){})

RecyclerItemClickListener.java :

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
open class RecyclerItemClickListener(context: Context, recyclerView: RecyclerView, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener {
    private var mGestureDetector: GestureDetector
    interface OnItemClickListener {
        fun onItemClick(view: View, position: Int)
        fun onLongItemClick(view: View?, position: Int)
    }
    init {
        mGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
            override fun onSingleTapUp(e: MotionEvent): Boolean {
                return true
            }
            override fun onLongPress(e: MotionEvent) {
                val child = recyclerView.findChildViewUnder(e.x, e.y)
                if (child != null && mListener != null) {
                    mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child))
                }
            }
        })
    }
    override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
        val childView = view.findChildViewUnder(e.x, e.y)
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildAdapterPosition(childView))
            return true
        }
        return false
    }
    override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {}
    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
}

Antwoord 22

Dit is wat ik deed Meer lezen & download de essentie hier

Hier hetzelfde toevoegen

CustomItemClickListener.java

public interface CustomItemClickListener {
 public void onItemClick(View v, int position);
}

ItemsListAdapter.java

public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> {
ArrayList<ItemListSingleItem> data;
Context mContext;
CustomItemClickListener listener;
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
    final ViewHolder mViewHolder = new ViewHolder(mView);
    mView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            listener.onItemClick(v, mViewHolder.getAdapterPosition());
        }
    });
    return mViewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.itemTitle.setText(Html.fromHtml(data.get(position).getTitle()));
    if (!TextUtils.isEmpty(data.get(position).getThumbnailURL())) {
      // I Love picasso library :) http://square.github.io/picasso/
        Picasso.with(mContext).load(data.get(position).getThumbnailURL()).error(R.drawable.ic_no_image).
                placeholder(R.drawable.ic_no_image).
                transform(new RoundedCornersTransformation(5, 0)).
                into(holder.thumbnailImage);
    } else {
        holder.thumbnailImage.setImageResource(R.drawable.ic_no_image);
    }
}
@Override
public int getItemCount() {
    return data.size();
}
public ItemsListAdapter(Context mContext, ArrayList<ItemsListSingleItem> data, CustomItemClickListener listener) {
    this.data = data;
    this.mContext = mContext;
    this.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
    public TextView itemTitle;
    public ImageView thumbnailImage;
    ViewHolder(View v) {
        super(v);
        itemTitle = (TextView) v
                .findViewById(R.id.post_title);
        thumbnailImage = (ImageView) v.findViewById(R.id.post_thumb_image);
    }
 }
}

23

Van de meeste van de bovenstaande antwoorden lijken ze hun onclicklisteners in te stellen op individuele items. De oplossing is echter op het punt om aan te bieden is heel eenvoudig, maar toch niet intuïtief voor velen. Velen vergeten dat de andere componenten altijd in een oudercomponent zijn die wordt gebruikt om items in de lijst of recyclermeningen weer te geven. Deze oplossing gaat over het instellen van een enkele onclick luisteraar naar dit ouderweergave en de beurt wordt gespeeld. De oplossing omvat ook een manier om de positie van het item te laten klappen in de lijst of recyclerweergave. Hier is onze hoofdwortelview een cardview van de Android-ondersteuningsbibliotheek. Hier is voorbeeldcode

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
public static final String LOG_TAG = ListAdapter.class.getSimpleName();
private Cursor mDataset;
private Context mContext;
private ViewHolder mViewHolder;
// Provide a suitable constructor (depends on the kind of dataset)
public ListAdapter(Context context, Cursor Dataset) {
    mDataset = Dataset;
    mContext = context;
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // create a new view
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.list_business_view, parent, false);
    mViewHolder = new ViewHolder(v);
    return mViewHolder;
}
public void setData(Cursor newdata) {
    this.mDataset = newdata;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//Bind data to other items here. To save time, i have ommited that.
           //here is where we attach a click listerner for an item in the recycler list rather than for each element of a given item.
            holder.card.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext, " Just cliked item at position " + itemPosition, Toast.LENGTH_LONG).show();
            }
        });
    }
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    if (null != mDataset) {
        return mDataset.getCount();
    }
    return 0;
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder{
    // each data item is just a string in this case
    public final TextView mBusinesssName; // View for the business name
    public final TextView mBusinessCategory; //View for the category name
    public final ImageView businessImage; // View for the business category image Image
    public final TextView mBusinessDistance; // View for the distance
    public final CardView card;
    public ViewHolder(View view) {
        super(view);
        mBusinesssName = (TextView) view.findViewById(R.id.list_item_name_textview);
        mBusinessCategory = (TextView) view.findViewById(R.id.list_item_category_textview);
        mBusinessDistance = (TextView) view.findViewById(R.id.list_item_dist_textview);
        businessImage = (ImageView) view.findViewById(R.id.list_item_icon);
        card = (CardView) view.findViewById(R.id.card_view);
    }
}
}

Antwoord 24

public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title, year, genre;
        public MyViewHolder(View view) {
            super(view);
            title = (TextView) view.findViewById(R.id.title);
            genre = (TextView) view.findViewById(R.id.genre);
            year = (TextView) view.findViewById(R.id.year);
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context, ""+getAdapterPosition(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

Antwoord 25

hier is de volledige code voor mijn aangepaste adapter. Deze code zal de rijen opblazen met lijstitems die zijn gedefinieerd in het xml-bestand met de naam “list_item”, het zal ook een klikgebeurtenis uitvoeren op alle rijen van lijstitems met respectieve posities.

public class MyCustomAdapter extends RecyclerView.Adapter`<`AdapterMyCustomAdapter.ViewHolder> {
    public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
        public onItemClickListener mListener;
        public ViewHolder(View v, onItemClickListener listener) {
            super(v);
            mListener =listener;
            v.setOnClickListener(this);
        }
        @Override
        public void onClick(View v) {
            mListener.onRecyclerItemClick(v, getPosition());
        }
        public static interface onItemClickListener {
            public void onRecyclerItemClick(View view , int position);
        }
    }
    @Override
    public int getItemCount() {
        return 5;
    }
    @Override
    public void onBindViewHolder(ViewHolder holder, int pos) {      
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item, parent, false);
    /* here list_item is an xml file we want to inflate ...it is same as we do in case of listview for customization.*/
        MyCustomAdapter.ViewHolder vh = new ViewHolder(v, new MyCustomAdapter.ViewHolder.onItemClickListener() {
            @Override
            public void onRecyclerItemClick(View view, int position) {
                System.out.println("clicked on list item at position " +position);
            } 
        });
        return vh;
    }
}

Antwoord 26

We kunnen dit doen met behulp van zwakke Java-referenties.
Semantisch gezien is de weergavehouder degene die moet reageren op de klikgebeurtenis of deze moet delegeren aan de juiste responder.

Onze doelen:

  1. De Viewholder zou niets moeten weten over de klasse die op de gebeurtenissen reageert, behalve dat het een bepaalde interface implementeert.
  2. De klikhandler zou de positie in de RecyclerView moeten krijgen van de weergave waarop is geklikt.
  3. We moeten kunnen zien op welkeweergave is geklikt in de weergavehouder.
  4. Behoud een losse koppeling tussen alle componenten en veroorzaak geen vasthoudcycli.

Stappen:

  1. Maak een interface om klikreacties te verwerken.

  2. Implementeer deze interface in de activiteit die de klik zal afhandelen.

  3. Voeg een lidvariabele toe aan de RecyclerView-adapter om de zwakke referentie vast te houden en een constructor die deze instelt.

  4. Doe hetzelfde in de RecyclerView ViewHolder en voeg een lidvariabele toe om de positie bij te houden.

  5. Stel uw on-click luisteraars in op elke gewenste weergave in de ViewHolder en bel vervolgens terug naar de responder om ze af te handelen.

  6. Wijzig uw onBindViewHolder-methode om de positie in te stellen bij het binden.

  7. Geef de beantwoorder door aan de ViewHolder.

  8. In de responder kun je nu getId() voor de weergave gebruiken om te achterhalen op welke weergave is geklikt.

En hier is een samenvatting zodat je kunt zien hoe het allemaal in elkaar past:
RecyclerView klikverwerking


Antwoord 27

Dit is wat ik doe om OnClickListeneropnieuw te gebruiken

 public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyviewHolder>
                                         implements View.OnClickListener

in ViewHoder Take itemlayout’s parent

 public class MyviewHolder extends RecyclerView.ViewHolder {
       LinearLayout linearLayout_item;
        public MyviewHolder(View itemView) {
            super(itemView);
            linearLayout_item=itemView.findViewById(R.id.linearLayout_item);
        }
    }

in onBindViewHolder tag instellen als positie

  @Override
    public void onBindViewHolder(MyviewHolder holder, int position) {
       holder.linearLayout_item.setTag(position);
       holder.linearLayout_item.setOnClickListener(this);
    }

en in onclick

@Override
public void onClick(View v) {
    int position = (int) v.getTag();
    switch (v.getId()) {
        case R.id.linearLayout_item:
            // do some thing with position 
            break;
    }
}

28

Voor mij de schone manier om dat te doen is deze.

Adapter Constructor

private class EnvironmentTypeRecyclerViewAdapter extends RecyclerView.Adapter<EnvironmentTypeRecyclerViewAdapter.ViewHolder>
{
     private final EnvironmentTypeRecyclerViewAdapterListener mEnvironmentTypeRecyclerViewAdapterListener;
     private List<Environment> mEnvironmentsData;
     public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
     {
         public ViewHolder(View v)
         {
             super(v);
             v.setOnClickListener(this);
         }
         @Override
         public void onClick(View v)
         {
              Environment environment = mEnvironmentsData.get(getAdapterPosition());
              if (mEnvironmentTypeRecyclerViewAdapterListener != null && environment != null) {
                      mEnvironmentTypeRecyclerViewAdapterListener.onListItemSelected(environment);      
              }
        }
        public EnvironmentTypeRecyclerViewAdapter(List<SmallCellEnvironment> environments, EnvironmentTypeRecyclerViewAdapterListener environmentTypeRecyclerViewAdapterListener)
        {
            mEnvironmentTypeRecyclerViewAdapterListener = environmentTypeRecyclerViewAdapterListener;
            mEnvironmentsData = environments;
        }
}

De gekoppelde interface

private interface EnvironmentTypeRecyclerViewAdapterListener
{
    void onListItemSelected(Environment environment);
}

Other episodes