RecyclerView onClick

583

Adakah yang menggunakan RecyclerViewmenemukan cara untuk mengatur onClickListeneritem ke dalam RecyclerView? Saya berpikir untuk mengatur pendengar untuk setiap tata letak untuk setiap item tapi itu tampaknya sedikit terlalu merepotkan saya yakin ada cara bagi RecyclerViewuntuk mendengarkan onClickacara tersebut tetapi saya tidak bisa mengetahuinya.

CurtJRees
sumber
4
RecyclerViewDemo Saya menemukan proyek ini hebat, menggunakan antarmuka untuk memberikan lebih banyak tindakan gratis.
MewX
2
lihat tutorial ini wiki.workassis.com/android-recyclerview-example
Bikesh M
Sederhana dan mudah digunakan - github.com/rahulkapoor1/ClickableAdapter
Rahul
stackoverflow.com/a/31199564/5788247
Shomu

Jawaban:

477

Karena API telah berubah secara radikal, itu tidak akan mengejutkan saya jika Anda membuat OnClickListeneruntuk setiap item. Itu tidak terlalu merepotkan. Dalam implementasi RecyclerView.Adapter<MyViewHolder>Anda, Anda harus memiliki:

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);
}

The onClickMetode:

@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();
}
nhaarman
sumber
32
bagaimana jika saya ingin menghapus satu baris pada kliknya?
Piyush Kukadiya
20
Saya suka jawaban ini lebih baik daripada yang Anda tautkan. Siapa yang ingin menulis pendengar gerakan dan tekan kotak deteksi untuk menangani ini. Google--
Lo-Tan
17
getChildPosition (view) adalah metode yang tidak digunakan lagi
Jigar
45
Apakah Anda keberatan menceritakan di kelas mana cuplikan Anda berada? onClick(), milik OnClickListenerdapat dilampirkan ke ANY View. Seluruh pertanyaan di sini adalah yang mana! Tolong usahakan, metode tidak hanya diidentifikasi dengan nama, tetapi juga setidaknya oleh kelas. Jika Anda tidak mengatakan kode Anda akan ditambahkan ke adaptor, jawaban Anda tidak terlalu membantu.
Vince
16
Haruskah metode onClick berada di fragmen yang menampung RecyclerView? Karena Anda mereferensikan mRecyclerView di kelas MyOnClickListener Anda. Dari mana Anda mendapatkan referensi ke objek itu?
Ced
606

Berikut ini adalah lebih baik dan kurang cara ketat ditambah untuk menerapkan OnClickListeneruntuk RecyclerView.

Cuplikan penggunaan:

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
      }
    })
);

RecyclerItemClickListener penerapan:

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){}
}
Yakub Tabak
sumber
85
Ini tidak akan memberikan petunjuk apa pun tentang tombol atau tampilan mana (dalam item) yang diklik. Tapi untuk klik item keseluruhan, ini bagus.
Niranjan
27
komentar ngen benar - jika Anda ingin melampirkan pendengar onClick ke item tertentu dalam tampilan item, Anda mungkin harus melakukannya di adaptor Anda, di onBindViewHolder, atau di viewholder Anda sendiri.
Jacob Tabak
16
Satu masalah dengan metode ini adalah ketika Anda melakukan sesuatu yang memerlukan beberapa ratus milidetik seperti memulai suatu kegiatan. Ketika item diklik, dan memiliki animasi yang diklik ada penundaan nyata antara mengklik dan melihat animasi.
Gak2
20
Solusi ini terasa sangat kikuk, ada beberapa penundaan saat memproses 'klik' dan rasanya tidak hanya ok
wasyl
6
Adakah yang bisa menjelaskan kepada saya mengapa solusi ini dengan GestureDetector seharusnya menjadi solusi yang lebih baik daripada hanya menggunakan "setOnClickListener" di dalam onBindViewHolder () di adaptor ke elemen yang sesuai? Dengan cara ini setidaknya saya memerlukan lebih sedikit kode daripada dengan solusi GestureDetector. Terima kasih atas penjelasannya.
e-nature
115

Saya melakukannya dengan cara ini, tanpa kelas yang tidak semestinya, detektor dll. Kode sederhana di dalam adaptor kami. Terutama solusi yang lebih baik untuk longClick daripada yang disajikan sebelumnya.

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);
    }
}

Kemudian di dalam fragmen atau aktivitas, tekan saja:

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);
    }
});
Marurban
sumber
alih-alih OurAdapter.clickListener saya pikir Marurban berarti PasswordAdapter.clickListener dan bukannya TrainingAdapter.ClickListener (), harus menjadi PasswordAdapter.ClickListener (). Selain itu, solusi hebat Marurban! bekerja untuk saya
nommer
pendengar onItemClick juga diaktifkan pada klik panjang.
Rashad.Z
10
ViewHolder harus statis untuk kinerja terbaik. ini bukan jawaban yang bagus.
Gilberto Ibarra
10
ClickListener statis membuat kebocoran memori. Deklarasikan pendengar sebagai non-statis dan ikat ke ViewHolder sebagai gantinya.
BladeCoder
1
@AJW Cara paling sederhana adalah menginisialisasi pendengar lebih awal dan meneruskannya sebagai argumen ke konstruktor Adaptor dan kemudian konstruktor ViewHolder.
BladeCoder
97

Lihat pertanyaan serupa @ tautan komentar CommonsWare untuk ini , yang mengimplementasikan OnClickListenerantarmuka dalam viewHolder.

Berikut ini contoh sederhana dari 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++){

        }


      }
  }

The Adapterkemudian terlihat seperti ini:

    @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);
    }
belot
sumber
14
Ini tampaknya salah arah. Jika Anda perlu menggunakan kembali recyclerview dalam fragmen / aktivitas lain, adaptor / penonton sekarang mendefinisikan logika klik alih-alih apa pun yang mengandung mereka. Klik harus benar-benar ditangani secara langsung atau tidak langsung oleh instance yang berisi. Tampaknya pendengar sentuhan adalah satu-satunya cara efektif untuk melakukan ini.
ian.shaun.thomas
18
@tencent Saya tidak melihat bagaimana itu masalahnya. Jika ViewHolder itu sendiri berisi semua informasi sehubungan dengan data apa yang dipilih ketika elemen itu sendiri diklik, maka satu-satunya tanggung jawab wadah adalah tampilan elemen N, daripada menangani pemilihan elemen ke-i tertentu keluar dari elemen N. Itu ListViewsudah bermasalah jika Anda harus membuat daftar objek yang lebih rumit daripada hanya baris sederhana. Bagaimana jika Anda perlu menangani berbagai peristiwa tergantung di mana Anda mengklik item di ListView? Anda kacau. Di sini, Anda memiliki masing-masing pendengar.
EpicPandaForce
2
Saya setuju dengan @EpicPandaForce untuk yang satu ini. Saya juga datang untuk memvotasikan jawaban ini setelah membaca bagian buku Commonsware tentang penanganan klik di RecyclerViews. Sejauh ini, hasilnya sangat bagus untuk saya.
AdamMc331
1
findViewById hanya digunakan pada pembuatan pemegang tampilan di sini (karenanya onCreateViewHolder). Pemegang tampilan dimaksudkan untuk mencegah menemukan tampilan setiap kali item terikat pada pemegang, bukan pada penciptaan awal.
stuckj
2
getPosition()sudah usang, gunakan getAdapterPosition()atau getLayoutPosition()sebagai gantinya.
K Neeraj Lal
94

Berdasarkan jawaban Jacob Tabak (+1 untuknya), saya dapat menambahkan pendengar onLongClick:

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) {
    }
}

Maka Anda dapat menggunakannya seperti ini:

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) {
        // ...
    }
}));
Eng.Fouad
sumber
1
Butuh waktu beberapa saat untuk beradaptasi dengan aplikasi saya, dan menyelaraskan dan memformat kode ke standar Java / Android, tetapi akhirnya bekerja dengan baik.
milosmns
Bagaimana Anda menambahkan animasi untuk klik panjang?
Jon
1
@Eng.Fouad klik efek tidak berfungsi dengan menggunakan ini, meskipun jika kita mengatur klik pendengar dalam efek klik adaptor bekerja solusi untuk ini
ingsaurabh
4
Anda juga harus menggantipublic void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
Paolo Rotolo
Untuk beberapa alasan itu tidak mengembalikan tampilan yang diklik. Dalam kasus saya, saya mengklik kotak centang tetapi tampilan yang diberikan adalah sesuatu yang berbeda. Cara saya memeriksa:view.getId() == R.id.selection
dVaffection
63

Inilah yang bekerja untuk saya. Lampirkan OnClickListenerke onBindView. Saya tidak benar-benar tahu apakah ini akan mempengaruhi kinerja, tetapi tampaknya berfungsi dengan baik dengan sedikit kode.

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();
            }
    });
}
Bubunyo Nyavor
sumber
5
dalam case.itemView.setOnClickListener case saya (..)
D4rWiNS
18
ini dinamai 'itemView' alih-alih 'view' dalam kasus saya, hanya mengatakan untuk pemula, beberapa dari mereka tidak mengerti apa yang mereka salin, dan tidak tahu mengapa tidak bekerja
D4rWiNS
3
Posisi tata letaknya
Bubunyo Nyavor
1
bagi saya ini sepertinya hanya berlaku untuk barang yang terlihat terakhir bukan barang yang diklik
Nasz Njoka Sr.
2
Solusi ini tampaknya yang terbaik bagi saya, tetapi bagaimana ini berbeda dari jawaban @bolot dalam hal kinerja? Dia telah mengimplementasikan View.OnClickListener langsung pada kelas ViewHolder, yang kemudian memuntahkan metode onClick secara terpisah. Solusi mana yang terbaik?
Edmond Tamas
46

Ini sangat sulit bagi saya untuk memiliki pendengar klik item dalam aktivitas dan juga memiliki pendengar klik untuk tampilan tunggal item yang tidak akan memicu pendengar klik item. Setelah bermain-main dengan jawaban Jacob Tabak, saya menghargai jawabannya pada klik item jika tidak ada tindakan sentuh lain di dalam item yang disajikan.

Saya memiliki OnClickListenerantarmuka khusus yang memiliki aktivitas klik item yang menahan tampilan item yang diklik dan posisi item dari adaptor. Saya menyajikan contoh itu di konstruktor (atau bisa dengan setter) dan melampirkannya ke pendengar klik wadah penampung klik.

Saya juga memiliki pendengar klik lain di Adaptor (Dapat di view view) yang akan menangani klik Lihat saat ini dari wadah.

 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();
}}

Dalam aktivitas tersebut Anda perlu menginisialisasi adaptor dengan melewatkan instance dari OnItemClickListener

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);
}

Dan ViewHolder saya

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);
}}
Sir NIkolay Cesar Yang Pertama
sumber
Pendekatan ini bekerja dengan baik untuk saya - itu berarti Anda dapat menangani klik dalam aktivitas daripada di dalam tampilan kisi
leafcutter
3
Di mana saya bisa memberi Anda uang. 4 jam mencari dan kemudian saya membaca posting Anda. Terima kasih atas waktu yang Anda ambil untuk memposting ini.
Brandon
3
Ini kedengarannya bodoh tetapi, apakah ini memiliki memori atau efisiensi seperti masalah? Karena kami menugaskan pendengar klik setiap kali tampilan digambar kan?
rgv
1
@Raghav ya setiap kali melihat sedang mengikat pendengar klik baru ditugaskan, tapi ini adalah aliran standar. Tetapi mOnItemClickListener dibuat hanya sekali untuk adaptor, hanya tampilan dan posisinya berbeda pada setiap klik item;)
Sir NIkolay Cesar The First
3
Contoh yang bagus untuk mematikan kinerja aplikasi dan membuat memori berlebihan! Dengan contoh ini, Anda hanya perlu menggulir untuk membuat ratusan objek yang tidak berguna, yang sebentar lagi tidak berguna dan harus diakses sebagai garbige. @NoobDogg benar. Tidak ada ClickListeners yang belum dibuat di onBindView. Pendengar klik harus dibuat sekali di onCreateView (atau pemegang konstruktor), dan ada saat kita membutuhkan layar dengan adaptor ini.
Mykola Tychyna
36

Inilah yang akhirnya saya butuhkan, kalau-kalau ada yang merasa berguna:

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());
            }
        });

    }
}

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

Domba Fifer
sumber
Dari semua versi yang saya coba, ini yang saya coba. Tapi apakah tidak apa-apa, melakukannya seperti itu? Atau ada cara yang lebih baik, seperti praktik terbaik?
Matthias Loibl
1
Sejauh yang saya tahu, ini adalah satu-satunya cara. Lihat ini untuk detail lebih lanjut! stackoverflow.com/a/24933117/1508887
Fifer Sheep
Bagaimana saya bisa membuka fragmen baru dari dalam metode onclick?
hash
5
getAdapterPosition () menggantikan getPosition ()
Kennedy Nyaga
27

Saya punya solusi yang bagus untuk RecyclerView's onItemClickListeneruntuk item dan subitems

Langkah 1- Buat antarmuka

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);
}

Langkah 2- Kemudian gunakan dalam onBindViewHoldermetode adaptor dengan cara berikut

/**
     * 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);
        }

    }

Langkah 3- temukan dan atur tampilan pendaur ulang dalam aktivitas atau fragmen tempat Anda menggunakannya

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());

Langkah 4- Akhirnya implementasikan antarmuka dalam aktivitas atau fragmen tempat Anda menggunakan recyclerview

@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();
        }
    }
Gopal Singh Sirvi
sumber
2
Ini adalah solusi terbaik karena kami biasanya membutuhkan banyak properti dari aktivitas / fragmen di onItemClickListener kami, dan tidak ada gunanya menyebutnya langsung dari pemirsa (saya harus membuat konstruktor khusus untuk setiap adaptor). By the way, kode Anda sedikit extense, saya sarankan Anda untuk memotongnya ke bagian paling penting (setOnItemClickListener).
sagits
ini adalah pendekatan sederhana yang baik untuk membedakan baris / item dari sub-item
Nigel Savage
17

Inilah yang saya lakukan. Solusi ini mendukung onClick dan onLongClick pada Item RecyclerView dan Tampilan di dalamnya Item RecyclerView (tampilan internal).

Saya memberi tag viewHolder pada pandangan pilihan saya:

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;
}

Dan saya menggunakan holder.getPosition () untuk mengambil posisi dalam metode onClick () (onLongClick serupa):

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();
    }
}

Varian dengan getChildPosition juga berfungsi. Harap perhatikan bahwa untuk tampilan internal, di onClick () gunakan:

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

Menurut saya, manfaat dari solusi ini adalah bahwa ketika seseorang mengklik gambar, hanya pendengar gambar onclick () yang dipanggil sedangkan ketika saya menggabungkan solusi Jacob untuk tampilan Item RecyclerView dan solusi saya untuk tampilan internal tampilan Item RecyclerView onclick ( ) juga disebut (ketika klik pada gambar).

u2gilles
sumber
11

Ada cara yang jauh lebih mudah untuk melakukan ini. Cukup gunakan klik pada onBindViewHolderpada tampilan root.

Pertimbangkan ini pandangan Anda untuk adaptor,

<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>

Kemudian lakukan mengikuti di adaptor Anda

//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);
    }
}
Sushant
sumber
9

Anda dapat meneruskan clickListenerke Adapter.

Di Anda Activity:

private View.OnClickListener mItemClick = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        Intent intent = null;
        int position = list.getChildPosition(v);
        switch (position) {
            case 0:
                intent = new Intent(MainActivity.this, LeakCanaryActivity.class);
                break;
            case 1:
                intent = new Intent(MainActivity.this, ButterKnifeFragmentActivity.class);
                break;
        }
        if (intent != null) {
            MainActivity.this.startActivity(intent);
        }
    }
};

kemudian berikan ke Adapter:

MainAdapter mainAdapter = new MainAdapter(this, mItemClick);

Dalam Adapter's onCreateViewHolder:

 @Override
public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
    View itemView = activity.getLayoutInflater().inflate(R.layout.main_adapter_item, viewGroup, false);
    ViewHolder holder = new ViewHolder(itemView);
    itemView.setOnClickListener(mItemClick);
    return holder;
}
Francis Shi
sumber
Bagaimana Anda melewati holdernilai - nilai melalui niat?
RoCk RoCk
8

Saya telah mengembangkan perpustakaan berbobot ringan untuk android, Anda dapat mengunjungi https://github.com/ChathuraHettiarachchi/RecycleClick

dan ikuti untuk sampel berikut

RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
            @Override
            public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                // YOUR CODE
            }
        });
Chathura Jayanath
sumber
Dapat mengonfirmasi, perpustakaan ini hebat! Sangat mudah digunakan, kerja bagus!
peterkodermac
7

Anda bisa mengimplementasikan OnClickListener ke kelas ViewHolder Anda

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());
        }
    }

Dan onBindViewHolder mengatur item pemegang tampilan Anda

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

Terlalu sederhana dan efektif.

Alih-alih mengimplementasikan antarmuka View.OnClickListenerdi dalam penampil tampilan atau membuat dan antarmuka dan mengimplementasikan antarmuka dalam aktivitas Anda - saya menggunakan kode ini untuk OnClickListenerimplementasi yang sederhana .

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();
        }
    }
Manikanta
sumber
3
Ini adalah praktik buruk yang umum karena terlihat terlalu mudah. Anda membuat pendengar dalam yang baru setiap kali sebuah objek diikat (dan setiap item dalam pendaur ulang dapat diikat berkali-kali) yang buruk untuk a) kinerja b) pengumpulan sampah. Alih-alih, Anda harus membuat SATU pendengar di suatu tempat (di viewholder, di adaptor, di fragmen atau aktivitas atas) dan cukup menambahkannya ke item di konstruktor viewholder aktif di onCreateViewHolder. Ini memiliki kompleksitas tambahan karena harus mencari tahu item mana yang diklik, tetapi dapat dipecahkan dengan mudah melalui tag atau menambahkan lebih banyak info ke pemegang.
GuillermoMP
6

Semua jawaban yang diposting sejauh ini adalah solusi yang bagus, namun jika Anda tidak ingin berurusan dengan terlalu banyak detail implementasi, dan hanya ingin bekerja dengan cara yang mirip dengan ListView, saya akan merekomendasikan menggunakan TwoWay-View, seperti yang terlihat di sini:

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

Perhatikan bahwa implementasi ini juga mendukung tekan lama pada item, serta dukungan untuk negara-negara yang ditekan (yang merupakan sesuatu yang penting yang tidak dimiliki solusi lain untuk pertanyaan ini).

Jika Anda tidak ingin menggunakan seluruh pustaka, lihat kelas ClickItemTouchListener , yang dapat digunakan sebagai mandiri jika diperlukan. Satu-satunya masalah yang saya temukan dengan itu saat ini adalah dengan lama tekan + gulir, tampaknya memiliki perilaku yang salah.

Jawnnypoo
sumber
6

Jika Anda ingin menangkap event klik Pada item Individual maka cukup terapkan OnClickListenerdi ViewHolderkelas dan kemudian atur klik pendengar pada tampilan individual atau keseluruhan itemView.

Contoh berikut menunjukkan hal yang sama

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();
            }
        }

    }
} 
HemangNirmal
sumber
5

Bagi saya, ini adalah cara terbaik:

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
    }
  ...
}
4gus71n
sumber
3
getChildPosition () dipenggal
Nasz Njoka Sr.
5

Tidak RecyclerViewmemiliki OnClickListenerdan harus mengimplementasikannya sendiri.

Saya ingin menambahkan OnItemClickListenerantarmuka Adapterdengan onClickmetode yang dipanggil ketika Anda mengklik tampilan item dari menu ViewHolder. Dengan demikian tanggung jawab mengelola klik pada item berada di luar ViewHolderdan Adapter. Akankah aktivitas atau fragmen yang akan memutuskan apa yang harus dilakukan

Tambahkan antarmuka ke objek pendengar dan pendengar.

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

  ...

  private static OnItemClickListener onItemClickListener;

  ...

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

  ...
}

Kami menangkap klik tampilan root item dan ketika panggilan balik dipicu onClickpanggilan pendengar pada adaptor.

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);
              }
          });
      }
  }
}

Karena aktivitas atau fragmen, fragmen dalam kasus kami, kami menetapkan pendengar ke adaptor dan panggilan balik onClick, kami akan mendapatkan item yang dipilih berdasarkan posisi dan membuka aktivitas detail item.

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
            }
        });
        ...
    }
...
}
xurxodev
sumber
5

Sayangnya RecyclerViewada beberapa fitur yang hilang ListView. Misalnya kemampuan untuk menambahkan OnItemClickListeneryang memicu ketika suatu item diklik. RecyclerViewmemungkinkan Anda untuk mengatur OnClickListenerdalam adaptor Anda, tetapi meneruskan pendengar klik itu dari kode panggilan Anda, ke adaptor dan ke ViewHolder, rumit untuk menangkap klik item sederhana.

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);
}
}

Anda juga perlu mendefinisikan R.id.item_click_supportmenggunakan ids.xml:

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

Listener klik kode yang dihasilkan sekarang terlihat seperti ini:

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

Untuk Penjelasan Singkat tentang klik recyclerview, silakan lihat littlerobots_blog ini

anand krish
sumber
5

Anda dapat dengan mudah mendefinisikan setOnClickListener di kelas ViewHolder Anda sebagai berikut:

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();
            }
        });
    }
}
Arash Hatami
sumber
5

Inilah yang saya lakukan Baca lebih lanjut & unduh intinya di sini

Menambahkan yang sama di sini

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);
    }
 }
}
Muhammad Riyaz
sumber
4

Dari sebagian besar jawaban di atas, mereka tampaknya mengatur onclicklisteners mereka untuk masing-masing item. Namun, solusi yang akan saya tawarkan sangat sederhana tetapi belum intuitif bagi banyak orang. Banyak yang lupa bahwa komponen lain selalu dalam komponen induk yang digunakan untuk menampilkan item dalam tampilan Daftar atau Pendaur Ulang. Solusi ini hanya tentang menyetel pendengar onclick tunggal ke tampilan induk ini dan giliran dimainkan. Solusi ini juga mencakup cara untuk melewatkan posisi item yang diklik dari daftar atau tampilan pendaur ulang. Di sini, rootview utama kami adalah CardView dari perpustakaan dukungan android. Berikut ini contoh kode

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);

    }
}
}
larrytech
sumber
4

Implementasi Kotlin dari jawaban nhaarman :

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) {}
}
Nilesh Deokar
sumber
3
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();
                }
            });
        }
    }
Pengecualian Null Pointer
sumber
3

di sini adalah kode lengkap untuk adaptor kustom saya, kode ini akan mengembang baris dengan item daftar didefinisikan dalam file xml bernama "list_item" itu juga akan melakukan event klik pada semua item daftar baris dengan posisi masing-masing.

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;
    }
}
Lone_iqbal
sumber
2

Kita dapat melakukan ini menggunakan referensi lemah Java. Semantik, pemegang tampilan adalah yang harus menanggapi acara klik atau mendelegasikannya ke responden yang benar.

Tujuan kita:

  1. Penonton harus tahu apa-apa tentang kelas yang merespons acara kecuali bahwa itu mengimplementasikan antarmuka tertentu.
  2. Pawang klik harus mendapatkan posisi di RecyclerView dari pandangan yang diklik.
  3. Kita harus dapat melihat tampilan mana yang diklik pada pemegang tampilan.
  4. Pertahankan lepasnya kopling di antara semua komponen dan jangan menyebabkan siklus penahan.

Langkah:

  1. Buat antarmuka untuk menangani respons klik.

  2. Terapkan antarmuka ini dalam Aktivitas yang akan menangani klik.

  3. Tambahkan variabel anggota dalam Adaptor RecyclerView untuk menahan Referensi Lemah dan konstruktor yang menetapkannya.

  4. Lakukan hal yang sama di RecyclerView ViewHolder dan tambahkan variabel anggota untuk melacak posisi.

  5. Atur pendengar klik Anda pada tampilan yang Anda inginkan di ViewHolder, lalu panggil balik ke responden untuk menanganinya.

  6. Ubah metode onBindViewHolder Anda untuk mengatur posisi saat mengikat.

  7. Lewatkan responden ke ViewHolder.

  8. Di responden, Anda sekarang dapat menggunakan getId () pada tampilan untuk mengetahui tampilan mana yang diklik.

Dan inilah Intis sehingga Anda dapat melihat bagaimana semuanya cocok: penanganan klik RecyclerView

Rajiev Timal
sumber
2

Saya sadar ada banyak jawaban, tetapi saya pikir saya mungkin hanya memberikan implementasi saya juga. (Rincian lengkap dapat ditemukan pada pertanyaan lain yang saya jawab ).

Jadi, untuk menambahkan pendengar klik, ViewHolderkelas batin Anda perlu diimplementasikan View.OnClickListener. Hal ini karena Anda akan mengatur OnClickListenerdengan itemViewparameter ViewHolder's konstruktor. Biarkan saya menunjukkan kepada Anda apa yang saya maksud:

public class ExampleClickViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    TextView text1, text2;

    ExampleClickViewHolder(View itemView) {
        super(itemView);

        // we do this because we want to check when an item has been clicked:
        itemView.setOnClickListener(this);

        // now, like before, we assign our View variables
        title = (TextView) itemView.findViewById(R.id.text1);
        subtitle = (TextView) itemView.findViewById(R.id.text2);
    }

    @Override
    public void onClick(View v) {
        // The user may not set a click listener for list items, in which case our listener
        // will be null, so we need to check for this
        if (mOnEntryClickListener != null) {
            mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
        }
    }
}

Satu-satunya hal lain yang perlu Anda tambahkan adalah antarmuka khusus untuk Anda Adapterdan metode penyetel:

private OnEntryClickListener mOnEntryClickListener;

public interface OnEntryClickListener {
    void onEntryClick(View view, int position);
}

public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
    mOnEntryClickListener = onEntryClickListener;
}

Jadi pendukung klik baru Anda Adaptersudah lengkap.

Sekarang, mari kita gunakan ...

    ExampleClickAdapter clickAdapter = new ExampleClickAdapter(yourObjects);
    clickAdapter.setOnEntryClickListener(new ExampleClickAdapter.OnEntryClickListener() {
        @Override
        public void onEntryClick(View view, int position) {
            // stuff that will happen when a list item is clicked
        }
    });

Ini pada dasarnya bagaimana Anda mengatur normal Adapter, kecuali bahwa Anda menggunakan metode setter yang Anda buat untuk mengontrol apa yang akan Anda lakukan ketika pengguna mengklik item daftar tertentu.

Anda juga dapat melihat sekumpulan contoh yang saya buat pada Intisari ini di GitHub:

https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07

Farbod Salamat-Zadeh
sumber
Anda harus menggunakan getAdapterPosition () alih-alih getLayoutPosition ()
BladeCoder
2

Inilah yang saya lakukan untuk digunakan kembali OnClickListener

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

di ViewHoder Ambil induk itemlayout

  public class MyviewHolder extends RecyclerView.ViewHolder {

       LinearLayout linearLayout_item;

        public MyviewHolder(View itemView) {
            super(itemView);
            linearLayout_item=itemView.findViewById(R.id.linearLayout_item);
        }
    }

di onBindViewHolder atur tag sebagai posisi

   @Override
    public void onBindViewHolder(MyviewHolder holder, int position) {

       holder.linearLayout_item.setTag(position);
       holder.linearLayout_item.setOnClickListener(this);
    }

dan di 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;
    }
}
Manohar Reddy
sumber
2

Bagi saya cara bersih untuk melakukannya adalah yang ini.

Konstruktor adaptor

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;
        }
}

Antarmuka Tertaut

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