RecyclerView onClick


583

Kullanan herhangi biri , öğelerinde RecyclerViewbir onClickListeneröğeyi ayarlamak için bir yol buldu RecyclerViewmu? Her öğe için düzenlerin her birine bir dinleyici ayarlamayı düşündüm ama bu biraz fazla güçlük gibi görünüyor Ben olayı RecyclerViewdinlemek için bir yol olduğundan eminim onClickama oldukça anlayamıyorum.



4
RecyclerViewDemo Daha fazla ücretsiz eylem sağlamak için arayüzler kullanarak bu projeyi harika buldum.
MewX


Basit ve kullanımı kolay - github.com/rahulkapoor1/ClickableAdapter
Rahul

stackoverflow.com/a/31199564/5788247
Shomu

Yanıtlar:


477

API'ler kökten değiştiğinden, OnClickListenerher bir öğe için bir tane oluştursaydınız beni şaşırtmaz . Gerçi bu kadar zor değil. Uygulamanızda RecyclerView.Adapter<MyViewHolder>şunlara sahip olmalısınız:

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

onClickyöntem:

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

32
tıklamasındaki bir satırı silmek istersem ne olur?
Piyush Kukadiya

20
Bu cevabı bağladığınız cevaptan daha iyi seviyorum. Kim bir jest dinleyici yazmak ve bunu ele almak için kutu algılama hit istiyor. Google
Lo-Tan

17
getChildPosition (görüntüle) kullanımdan kaldırıldı yöntemi
Jigar

45
Parçacıklarınızın hangi sınıflarda olduğunu söylemenin bir sakıncası var mı? onClick(), ait OnClickListenerHERHANGİ BİR Görünüm eklenebilir. Burada tüm soru hangisi! Lütfen bir çaba gösterin, bir yöntem sadece bir adla değil, aynı zamanda en azından bir sınıfla da tanımlanır. Kodunuzun bağdaştırıcıya ekleneceğini söylemezseniz, cevabınız gerçekten yardımcı olmaz.
Vince

16
OnClick yöntemi RecyclerView'ı tutan parçada mı olmalıdır? Çünkü MyOnClickListener sınıfınızda mRecyclerView'e başvuruyorsunuz. Bu nesneye referansı nereden aldınız?
Ced

606

İşte bir OnClickListenerfor a uygulamak için daha iyi ve daha az sıkı bir şekilde bir yoludur RecyclerView.

Kullanım pasajı:

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

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

85
Bu, hangi düğmenin veya görünümün (öğenin içinde) tıklandığı hakkında hiçbir ipucu sağlamaz. Ancak genel öğe tıklaması için bu sorun değil.
Niranjan

27
ngen'in yorumu doğrudur - öğe görünümündeki belirli bir öğeye bir onClick dinleyicisi eklemek istiyorsanız, bunu muhtemelen bağdaştırıcınızda, onBindViewHolder'da veya izleyicinizin kendisinde yapmalısınız.
Jacob Tabak

16
Bu yöntemle ilgili bir sorun, bir etkinliğe başlamak gibi birkaç yüz milisaniye süren bir şey yaptığınızdır. Öğe tıklandığında ve tıklatılan bir animasyona sahip olduğunda, animasyonu tıklayıp görmek arasında fark edilir bir gecikme olur.
Gak2

20
Bu çözüm son derece hantal, 'klik' işlenirken biraz gecikme var ve his sadece iyi değil
wasyl

6
Herkes bana GestureDetector ile bu çözüm sadece onBindViewHolder () içinde ilgili öğeye adaptör içinde "setOnClickListener" kullanmaktan daha iyi bir çözüm olması gerekiyordu açıklayabilir misiniz? Bu şekilde en azından GestureDetector çözümüne göre daha az koda ihtiyacım var. Bir açıklama için teşekkürler.
e-doğa

115

Bu şekilde, gereksiz sınıflar, dedektörler vb. Olmadan yapıyorum. LongClick için özellikle daha önce sunulandan daha iyi bir çözüm.

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

Sonra parça veya aktivite içinde, sadece vurmak:

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

OurAdapter.clickListener yerine bence Marurban PasswordAdapter.clickListener anlamına gelir ve TrainingAdapter.ClickListener () yerine PasswordAdapter.ClickListener () olmalıdır. Bunun dışında harika bir çözüm Marurban! benim için çalıştı
nommer

onItemClick dinleyicisi de uzun tıklama ile etkinleştiriliyor.
Rashad.Z

10
En iyi performans için ViewHolder statik olmalıdır. bu iyi bir cevap değil.
Gilberto Ibarra

10
Statik clickListener bir bellek sızıntısı oluşturur. Dinleyiciyi statik olmayan olarak bildirin ve bunun yerine ViewHolder'a bağlayın.
BladeCoder

1
@AJW En basit yol dinleyiciyi erken başlatmak ve bunu Adaptör yapıcısına ve sonra ViewHolder yapıcısına argüman olarak iletmektir.
BladeCoder

97

Benzer bir göz atın soru CommonsWare en @ için yorum bağlantılarından bu uygular OnClickListeneriçinde arayüz viewHolder.

İşte basit bir örnek 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++){

        }


      }
  }

AdapterSonra şöyle görünür:

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

14
Bu yanlış yöne gidiyor gibi görünüyor. Başka bir parça / etkinlikte geri dönüşüm görünümünü yeniden kullanmanız gerekiyorsa, bağdaştırıcı / görüntüleyici, artık içerdikleri yerine tıklamaların mantığını tanımlamaktadır. Tıklamalar gerçekten doğrudan veya dolaylı olarak içeren örnek tarafından ele alınmalıdır. Öyle görünüyor ki, bir dokunma dinleyicisi bu konuda ilerlemenin tek etkili yolu.
ian.shaun.thomas

18
@tencent Sorunun nasıl olduğunu göremiyorum. ViewHolder öğesinin kendisi, öğenin kendisi tıklatıldığında hangi verilerin seçildiğine ilişkin tüm bilgileri içeriyorsa, kabın tek sorumluluğu, belirli bir ithth öğesinin seçimini işlemek yerine N öğelerinin görüntülenmesidir. N elemanlarının. ListViewEğer sadece basit satırdan daha fazlasını karmaşık nesnelerin listesini oluşturmak için olsaydı zaten sorunlu oldu. ListView'da öğeyi nereye tıkladığınıza bağlı olarak farklı olayları işlemeniz gerekirse ne olur? Sarhoşsun. Burada her dinleyiciniz var.
EpicPandaForce

2
Bu konuda @EpicPandaForce ile hemfikirim. Commonsware'in RecyclerViews'deki tıklamaları ele alma kitabının bölümünü okuduktan sonra da bu cevabı oylamaya geldim. Şimdiye kadar benim için harika çalıştı.
AdamMc331

1
findViewById burada yalnızca görünüm tutucu oluşturmada kullanılır (dolayısıyla onCreateViewHolder). Görünüm sahibi, bir öğenin tutucuya her bağlanışında, ilk oluşturmada değil görünümün bulunmasını önlemeyi amaçlamaktadır.
stuckj

2
getPosition()kullanımdan kaldırıldı, kullanın getAdapterPosition()veya getLayoutPosition()bunun yerine.
K Neeraj Lal

94

Jacob Tabak'ın cevabına (onun için +1) dayanarak, onLongClick dinleyicisini ekleyebildim:

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

O zaman bu şekilde kullanabilirsiniz:

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

1
Uygulamama uyum sağlamak ve kodu Java / Android standartlarına göre hizalamak ve biçimlendirmek için biraz zaman aldı, ancak sonunda iyi çalıştı.
milosmlar

Uzun tıklama için bir animasyonu nasıl eklersiniz?
Jon

1
@ Eng.Fouad tıklama efekti bunu kullanarak çalışmıyor, ancak tıklama dinleyicisini adaptör tıklama efekti olarak ayarlarsak, bunun için herhangi bir çözüm çalışır
ingsaurabh

4
Ayrıca geçersiz public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
kılmalısınız

Nedense tıklanan bir görünüm döndürmez. Benim durumumda bir onay kutusunu tıklıyorum ama verilen görünüm farklı bir şey. Kontrol etme view.getId() == R.id.selection
şeklim

63

Bu benim için işe yaradı. Takın OnClickListeneriçin onBindView. Bunun performansı etkileyip etkilemeyeceğini gerçekten bilmiyorum, ancak küçük kodlarla iyi çalışıyor gibi görünüyor.

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

5
benim durumumda holder.itemView.setOnClickListener (..)
D4rWiNS

18
benim durumumda 'görünüm' yerine 'itemView' olarak adlandırılıyor, sadece yeni başlayanlar için söyleniyor, bazıları neyi kopyaladıklarını anlamıyor ve neden çalışmadığını
anlayamıyorum

3
Bu mizanpaj konumu
Bubunyo Nyavor

1
benim için bu sadece tıklanan öğe için değil son görünür öğe için geçerli gibi görünüyor
Nasz Njoka Sr.

2
Bu çözüm benim için en iyisi gibi görünüyor, ancak bu @bolot'un performans sıcaklıklarındaki cevabından nasıl farklı? View.OnClickListener'ı doğrudan onClick yöntemini ayrı ayrı tüküren ViewHolder sınıfına uyguladı. Hangisi en iyi çözüm olurdu?
Edmond Tamas

46

Bu, etkinlikte öğe tıklama dinleyicisine sahip olmak ve ayrıca öğe tıklama dinleyicisinde tetiklenmeyecek öğenin tek bir görünümü için tıklama dinleyicisine sahip olmak benim için çok zordu. Jacob Tabak'ın cevabı ile oynadıktan sonra, öğenin içindeki başka dokunma eylemleri sunulmazsa, öğe tıklamasıyla ilgili cevabına saygı duyuyorum.

Bir gelenekim var OnClickListenerTıklatılan öğenin görünümünü ve bağdaştırıcıdan öğe konumunu tutan madde tıklama olayı olan arabirim var. Bunun bir örneğini yapıcıda (veya ayarlayıcı ile birlikte) sunuyorum ve görünüm tutucu kapsayıcısı tıklama dinleyicisine ekliyorum.

Ayrıca, bağdaştırıcıda mevcut Görünüm tıklamasını işleyecek başka bir tıklama dinleyicisine (görünüm tutucuda olabilir) sahibim.

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

Etkinlikte, bağdaştırıcının 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);
}

Ve ViewHolder'ım

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

Bu yaklaşım benim için iyi çalıştı - bu, ızgara görünümü içinde değil, etkinlikteki tıklamaları ele alabileceğiniz anlamına gelir
leafcutter

3
Sana nerede para verebilirim. 4 saat arama yaptıktan sonra yazınızı okudum. Bunu göndermek için ayırdığınız zaman için teşekkürler.
Brandon

3
Bu kulağa aptalca geliyor, ancak bunun bellek gibi bir verimliliği veya sorunu var mı? Bir görünüm her çizildiğinde tıklama dinleyicisini atadığımız için doğru mu?
rgv

1
@Raghav evet her görünüm bağlandığında yeni bir tıklama dinleyicisi atanır, ancak bu standart akıştır. Ancak mOnItemClickListener, adaptör için yalnızca bir kez oluşturulur ve her öğe tıklamasında görünüm ve konumu farklıdır;)
Sir NIkolay Cesar İlk

3
Uygulama performansını öldürmek ve aşırı bellek kullanımı için harika bir örnek! Bu örnekle, bir anda işe yaramayacak ve garip olarak erişilmesi gereken yüzlerce işe yaramaz nesne oluşturmak için kaydırma yapmanız yeterlidir. @NoobDogg doğru. OnBindView'da hiçbir ClickListener oluşturulamaz. Bir tıklama dinleyicisi onCreateView'de (veya tutucu yapıcısında) bir kez oluşturulmalıdır ve bu adaptörle ekrana ihtiyaç duyduğumuzda var olur.
Mykola Tychyna

36

İhtiyacım olan şey budur, eğer birisi onu yararlı bulursa:

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

    }
}

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


Denediğim tüm versiyonlardan, bu benim çalıştığım versiyon. Ama bu şekilde yapmak uygun mu? Yoksa en iyi uygulama gibi daha iyi bir yol var mı?
Matthias Loibl

1
Anlayabildiğim kadarıyla, tek yol buydu. Daha fazla ayrıntı için buna göz atın! stackoverflow.com/a/24933117/1508887
Fifer Koyun

Onclick yönteminin içinden yeni parçayı nasıl açabilirim?
Hash

5
getAdapterPosition (), getPosition () yerine geçer
Kennedy Nyaga

27

Ben güzel çözüm RecyclerViews' onItemClickListeneröğeleri ve alt öğesi için

Adım 1- Bir arayüz oluşturun

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

Adım 2- Sonra adaptörün onBindViewHolderyönteminde aşağıdaki şekilde kullanın

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

    }

Aşama 3- Bunu kullandığınız etkinlik veya parçada geri dönüşümcü görünümünü bulun ve ayarlayın

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

Adım 4- Son olarak arayüzü geri dönüşüm görünümünü kullandığınız etkinlik veya parçaya uygulayın

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

2
Bu en iyi çözümdür, çünkü genellikle onItemClickListener'ımızdaki etkinlik / parçadan çok fazla özelliğe ihtiyacımız var ve bunu doğrudan izleyiciden çağırmak mantıklı değil (her bir adaptör için özel bir kurucu oluşturmak zorunda kalacağım). Bu arada, kodunuz biraz geniş, en önemli parçaya (setOnItemClickListener) kesmenizi öneririm.
16'da sagits

Bu, satır / öğeyi alt öğelerden ayırmak için iyi bir basit yaklaşımdır
Nigel Savage

17

İşte yaptığım şey. Bu çözüm, RecyclerView Öğelerinin ve Görünümlerinin hem onClick hem de onLongClick'i RecyclerView Öğeleri (iç görünümler) içinde destekler.

Ben seçimimi görünümleri viewHolder etiket:

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

Ve onClick () yöntemindeki konumu almak için holder.getPosition () kullanıyorum (onLongClick benzerdir):

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

GetChildPosition ile bir varyant da çalışır. Dahili görünümler için onClick () 'de şunu kullanın:

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

Aklıma göre, bu çözümün avantajı, görüntüye bir tıklandığında sadece onclick () görüntü dinleyicisinin çağrılmasıdır, oysa Jacob'un bir RecyclerView Item görünümü için çözümünü ve dahili görünümler için çözümümü RecyclerView Item görünümü onclick ( ) olarak da adlandırılır (resme tıklandığında).


11

Bunu yapmanın çok daha kolay bir yolu var. Sadece onBindViewHolderkök görünümde tıklama üzerine uygulayın .

Bunun adaptör görünümünüz olduğunu düşünün,

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

Ardından adaptörünüzde aşağıdakileri yapın

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

9

Bir geçebilir clickListeneriçin Adapter.

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

sonra şuraya iletin Adapter:

MainAdapter mainAdapter = new MainAdapter(this, mItemClick);

In Adapters' 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;
}

holderDeğerleri niyetten nasıl geçirirsiniz ?
RoCk RoCk

8

Android için hafif ağırlıklı bir kütüphane geliştirdim, https://github.com/ChathuraHettiarachchi/RecycleClick adresini ziyaret edebilirsiniz.

ve aşağıdaki örnek için takip edin

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

Onaylayabilir, bu kütüphane harika! Kullanımı çok kolay, iyi iş!
peterkodermac

7

OnClickListener'ı ViewHolder sınıfınıza uygulayabilirsiniz

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

Ve onBindViewHolder görünüm sahibinizin öğesini ayarladı

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

7

Çok basit ve etkili.

View.OnClickListenerGörünüm tutucu içinde arayüz uygulamak veya aktivitenizde arayüz oluşturmak ve arayüz uygulamak yerine, bu kodu basit OnClickListeneruygulama için kullandım .

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

3
Bu yaygın bir kötü uygulamadır, çünkü çok kolay görünüyor. Bir nesne her bağlandığında (ve bir geri dönüşüm cihazındaki her öğe birçok kez bağlanabilir) yeni bir iç dinleyici oluşturuyorsunuz, bu da a) performans b) çöp toplama için kötüdür. Bunun yerine bir yerde (dinleyicide, bağdaştırıcıda, üst parçada veya etkinlikte) ONE dinleyici oluşturmalı ve bunu onCreateViewHolder'daki izleyici yapıcısındaki öğelere eklemelisiniz. Bu, hangi öğenin tıklayıcı olduğunu bulmak zorunda kalmanın karmaşıklığına sahiptir, ancak etiketler aracılığıyla kolayca çözülebilir veya tutucuya daha fazla bilgi eklenebilir.
GuillermoMP

6

Şimdiye kadar gönderilen tüm cevaplar harika çözümlerdir, ancak çok fazla uygulama ayrıntısıyla uğraşmak istemiyorsanız ve sadece ListView'ın yaptığı gibi çalışmasını istiyorsanız, burada görüldüğü gibi TwoWay-View kullanmanızı tavsiye ederim:

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

Bu uygulamanın aynı zamanda öğelere uzun süreli basmanın yanı sıra preslenmiş devletler için desteği de desteklediğini unutmayın (bu sorunun diğer çözümlerinin eksik olması önemli bir şeydir).

Kitaplığın tamamını kullanmak istemiyorsanız, gerekirse bağımsız olarak kullanılabilen ClickItemTouchListener sınıfına bakın . Şu anda onunla bulduğum tek sorun uzun basın + kaydırma ile, yanlış davranış var gibi görünüyor.


6

Eğer Bireysel öğeler üzerinde yakalamak click olayı istiyorsanız o zaman sadece uygulamak OnClickListeneriçinde ViewHoldersınıf ve ardından tek tek görünümlere veya bütün tıklama dinleyicileri ayarlayın itemView.

Aşağıdaki örnek aynı şeyi gösterir

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

    }
} 

5

Benim için bu en iyi yol:

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

3
getChildPosition () kesildi
Nasz Njoka Sr.

5

RecyclerViewBir yoktur OnClickListenerve bunu kendimiz uygulamak zorunda kalacaktır.

' Dan öğe görünümüne tıkladığınızda çağrılan bir yöntemle bir OnItemClickListenerarayüz eklemek istiyorum . Böylece, bir öğeye tıklamayı yönetme sorumluluğu veAdapteronClickViewHolderViewHolderAdapter . Ne yapılacağına karar verecek aktivite veya fragman

Dinleyiciye ve dinleyici nesnesine bir arabirim ekleyin.

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

  ...

  private static OnItemClickListener onItemClickListener;

  ...

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

  ...
}

Öğenin kök görünümünün tıklamasını ve geri arama tetiklendiğinde onClickadaptördeki dinleyici çağrısını yakalarız.

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

Aktivite veya parça, bizim durumumuzda parça olduğundan, adaptöre bir dinleyici atarız ve onClick geri araması, seçilen öğeyi konuma göre alır ve öğenin ayrıntılı bir etkinliğini açacağız.

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

5

Ne yazık ki RecyclerView, ListViewyerleşik olan birkaç özellik eksik . Örneğin OnItemClickListener, bir öğe tıklandığında tetiklenen bir ekleme yeteneği . bağdaştırıcınızda RecyclerViewbir ayar yapmanızı sağlar OnClickListener, ancak bu tıklama dinleyicisini arama kodunuzdan bağdaştırıcıya ve cihazına aktarmak, ViewHolderbasit bir öğe tıklatması yakalamak için karmaşıktır.

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

Ayrıca R.id.item_click_supportids.xml kullanarak tanımlamanız gerekir :

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

Ortaya çıkan kod tıklama dinleyicisi şimdi şöyle görünür:

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

Geri dönüşüm görüntüleme tıklamaları hakkında Kısa Açıklama için lütfen bu küçük çocuğa bir göz atın.


5

Kolayca tanımlayabilirsiniz setOnClickListener aşağıdaki gibi sizin ViewHolder sınıfında:

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

5

İşte yaptığım şey Daha fazla bilgi için buradaki özeti indirin

Aynı şeyi buraya ekleme

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

4

Yukarıdaki cevapların çoğundan, onlicklisteners'ı ayrı ayrı öğelere ayarlıyor gibi görünüyorlar. Ancak, sunacağım çözüm çok basit ama yine de pek çok kişi için sezgisel değil. Birçoğu, diğer bileşenlerin her zaman Liste veya Geri Dönüşümcü görünümlerinde öğeleri görüntülemek için kullanılan bir üst bileşende olduğunu unutur. Bu çözüm, bu ana görünüme tek bir onclick dinleyici ayarlamakla ilgilidir ve dönüş oynatılır. Çözüm ayrıca, tıklanan öğenin konumunu listeden veya geri dönüşümcü görünümünden geçirmenin bir yolunu da içerir. Burada, ana rootview'imiz android destek kütüphanesinden bir CardView. İşte örnek kod

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

    }
}
}

4

Kotar'ın nhaarman cevabı uygulaması :

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

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

3

İşte benim özel bağdaştırıcım için tam kod Bu kod satırları "list_item" adlı xml dosyasında tanımlanan liste öğeleri ile şişirir ve aynı zamanda ilgili pozisyonlara sahip tüm liste öğeleri satırlarında click olayı gerçekleştirir.

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

2

Bunu Java zayıf referanslarını kullanarak yapabiliriz. Anlamsal olarak, görünüm sahibi, tıklama etkinliğine yanıt vermesi veya doğru yanıtlayıcıya devretmesi gereken kişidir.

Hedeflerimiz:

  1. Viewholder, olaylara yanıt veren sınıf hakkında belirli bir arabirim uygulaması dışında hiçbir şey bilmemelidir.
  2. Tıklama işleyici, tıklanan görünümün RecyclerView öğesindeki konumu almalıdır.
  3. Hangisini fark edebilmeliyizGörünüm tutucuda görünümün tıklandığını .
  4. Tüm bileşenler arasında gevşek bağlantıyı koruyun ve tutma döngülerine neden olmayın.

Adımlar:

  1. Tıklama yanıtlarını işlemek için bir arayüz oluşturun.

  2. Bu arabirimi, tıklamayı işleyecek olan Etkinliğe uygulayın.

  3. Zayıf başvuruyu ve bunu ayarlayan yapıcıyı tutmak için RecyclerView Bağdaştırıcısına bir üye değişkeni ekleyin.

  4. Aynısını RecyclerView ViewHolder'da yapın ve konumu izlemek için bir üye değişkeni ekleyin.

  5. Tıklama dinleyicilerinizi ViewHolder'da istediğiniz herhangi bir görünümde ayarlayın, ardından bunları işlemek için yanıtlayana geri arama yapın.

  6. Bağlama sırasında konumu ayarlamak için onBindViewHolder yönteminizi değiştirin.

  7. Yanıtlayıcıyı ViewHolder'a aktarın.

  8. Yanıtlayıcıda, artık hangi görünümün tıklandığını bulmak için görünümdeki getId () yöntemini kullanabilirsiniz.

Ve işte bir Gist, böylece hepsinin nasıl birbirine uyduğunu görebilirsiniz: RecyclerView tıklama yönetimi


2

Çok fazla yanıtın olduğunun farkındayım, ancak bunun benim uygulanmasını da sağlayabileceğimi düşündüm. (Yanıtladığım başka bir soru hakkında tüm ayrıntıları bulabilirsiniz ).

Bu nedenle, bir tıklama dinleyicisi eklemek için iç ViewHoldersınıfınızın uygulaması gerekir View.OnClickListener. Bir set Bunun nedeni OnClickListeneriçin itemViewbir parametre ViewHolderbireyin yapıcı. Ne demek istediğimi göstereyim:

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

Eklemeniz gereken tek şey, sizin için özel bir arayüz Adapterve bir ayarlayıcı yöntemidir:

private OnEntryClickListener mOnEntryClickListener;

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

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

Dolayısıyla, yeni, tıklama desteklemeniz Adaptertamamlandı.

Şimdi kullanalım ...

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

Temel olarak normal bir Adapteryöntem oluşturmaktır, ancak kullanıcı belirli bir liste öğesini tıkladığında ne yapacağınızı kontrol etmek için oluşturduğunuz ayarlayıcı yönteminizi kullanmanız gerekir.

GitHub'daki bu Gist'te yaptığım bir dizi örneği de inceleyebilirsiniz:

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


GetLayoutPosition () yerine getAdapterPosition () kullanmalısınız
BladeCoder

2

Yeniden kullanmak için yaptığım şey bu OnClickListener

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

in ViewHoder Itemlayout üst öğesini al

  public class MyviewHolder extends RecyclerView.ViewHolder {

       LinearLayout linearLayout_item;

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

onBindViewHolder set etiketinde konum olarak

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

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

ve Onclick'te

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

2

Benim için bunu yapmanın temiz yolu bu.

Adaptör yapıcı

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

Bağlantılı Arayüz

private interface EnvironmentTypeRecyclerViewAdapterListener
{
    void onListItemSelected(Environment environment);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.