Question RecyclerView onClick


Quelqu'un at-il utilisé RecyclerView trouvé un moyen de définir un onClickListener aux articles dans le RecyclerView? J'ai pensé à mettre un auditeur à chacune des mises en page pour chaque article, mais cela semble un peu trop de tracas Je suis sûr qu'il y a un moyen pour le RecyclerView écouter le onClick événement mais je ne peux pas tout à fait comprendre.


414
2018-06-28 21:27


origine


Réponses:


Comme les API ont radicalement changé, cela ne me surprendrait pas si vous créiez OnClickListener pour chaque article. Cependant, ce n'est pas vraiment un problème. Dans votre mise en œuvre de RecyclerView.Adapter<MyViewHolder>, tu aurais dû:

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

le onClick méthode:

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

387
2018-06-28 22:15



Voici une façon meilleure et moins étroitement couplée de mettre en OnClickListener pour un RecyclerView.

Extrait d'utilisation:

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 la mise en oeuvre:

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

528
2017-10-04 20:22



Basé sur la réponse de Jacob Tabak (+1 pour lui), j'ai pu ajouter un écouteur 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) {
    }
}

Ensuite, vous pouvez l'utiliser comme ceci:

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

90
2017-11-09 09:09



Découvrez un similaire question  @ CommonsWare's des liens de commentaire vers ce, qui met en œuvre OnClickListener interface dans le viewHolder.

Voici un exemple simple de ViewHolder:

    TextView textView;//declare global with in adapter class

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

      private ViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            textView = (TextView)view.findViewById(android.R.id.text1);

      }

      @Override
      public void onClick(View view) {
            Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();

         //go through each item if you have few items within recycler view
        if(getLayoutPosition()==0){
           //Do whatever you want here

        }else if(getLayoutPosition()==1){ 
           //Do whatever you want here         

        }else if(getLayoutPosition()==2){

        }else if(getLayoutPosition()==3){

        }else if(getLayoutPosition()==4){

        }else if(getLayoutPosition()==5){

        }

        //or you can use For loop if you have long list of items. Use its length or size of the list as 
        for(int i = 0; i<exampleList.size(); i++){

        }


      }
  }

le Adapter alors ressemble à ceci:

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

86
2017-07-14 21:37



Je le fais de cette façon, sans classes indues, détecteurs etc. Code simple à l'intérieur de notre adaptateur. Solution particulièrement meilleure pour longClick que présenté auparavant.

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

Puis à l'intérieur du fragment ou de l'activité, appuyez simplement sur:

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

81
2017-07-28 08:38



C'est ce qui a fonctionné pour moi. Joindre le OnClickListener au onBindView. Je ne sais pas vraiment si cela aura un impact sur la performance, mais cela semble fonctionner correctement avec peu de code.

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

51
2017-11-02 16:06



Cela a été si difficile pour moi d'avoir un écouteur de clic sur l'élément dans l'activité et également d'avoir un écouteur de clic pour une vue unique de l'élément qui ne se déclenchera pas sur l'écouteur de clic d'élément. Après avoir joué avec la réponse de Jacob Tabak, je respecte sa réponse à l'item. Cliquez sur si aucune autre action tactile à l'intérieur de l'élément n'est présentée.

J'ai une coutume OnClickListener interface qui a un événement de clic sur l'élément qui contient la vue de l'élément cliqué et la position de l'élément à partir de l'adaptateur. J'en présente une instance dans le constructeur (ou peut l'être avec setter) et l'attache à l'écouteur de clic du conteneur du view view.

J'ai également un autre écouteur de clic dans l'adaptateur (peut être dans le support de vue) qui manipulera le clic courant de vue du récipient.

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

    MyViewHolder viewHolder = new MyViewHolder(layoutView);

    return viewHolder;
}

@Override
public void onBindViewHolder(MyViewHolder viewHolder,
        final int position) {

        viewHolder.container.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mOnItemClickListener.onItemClick(v, position);
            }
        });

        viewHilder.button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //do button click work here
            }
        });

}

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

Dans l'activité, vous devez initialiser l'adaptateur en transmettant l'instance du 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);
}

Et mon ViewHolder

public class MyViewHolder extends RecyclerView.ViewHolder {

public Button button;
public View container;

public MyViewHolder(View itemLayoutView) {
    super(itemLayoutView);

    container = itemLayoutView;
    button = (Button) itemLayoutView.findViewById(R.id.button);
}}

37
2018-02-03 16:42



J'ai une bonne solution pour RecyclerViewde onItemClickListener pour les articles et les sous-éléments

Étape 1- Créer une interface

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

Étape 2- Ensuite, utilisez-le dans l'adaptateur onBindViewHolder méthode de la manière suivante

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

    }

Étape 3- trouver et configurer la vue recycleur dans l'activité ou le fragment où vous utilisez cette

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

Étape 4- Enfin, implémentez l'interface dans l'activité ou le fragment où vous utilisez le 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();
        }
    }

23
2017-10-09 07:03