RecyclerView onClick


583

를 사용 RecyclerView하는 사람 이 onClickListener에서 항목 을 설정하는 방법을 찾았 RecyclerView습니까? 각 항목의 각 레이아웃에 리스너를 설정하는 것을 생각했지만 약간 번거 로움이 많이 생겼 RecyclerView습니다.onClick 이벤트 하게 알 수는 없습니다.



4
RecyclerViewDemo 인터페이스를 사용하여 더 많은 무료 작업을 제공하는이 프로젝트가 훌륭하다는 것을 알았습니다.
MewX


간단하고 사용하기 쉬운 -github.com/rahulkapoor1/ClickableAdapter
Rahul

stackoverflow.com/a/31199564/5788247
Shomu

답변:


477

API가 급격히 변경되었으므로 OnClickListener각 항목에 대해 를 작성해도 놀라지 않을 것 입니다. 그래도 그렇게 번거롭지는 않습니다. 의 구현에는 RecyclerView.Adapter<MyViewHolder>다음이 있어야합니다.

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

onClick방법 :

@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
클릭시 행을 삭제하려면 어떻게해야합니까?
Piyush Kukadiya

20
나는 당신이 연결 한 것 보다이 대답을 더 좋아합니다. 이 문제를 처리하기 위해 제스처 리스너 및 적중 상자 감지를 작성하려는 사람. Google--
Lo-Tan

17
getChildPosition (view)은 사용되지 않습니다.
Jigar

45
스 니펫이 어떤 클래스에 속하는지 말씀해 주시겠습니까? onClick()에 속하는 OnClickListener모든 뷰에 첨부 할 수 있습니다. 여기서 모든 질문은 어느 것입니까! 방법은 이름뿐만 아니라 최소한 클래스로 식별됩니다. 코드가 어댑터에 추가된다고 말하지 않으면 대답이 실제로 도움이되지 않습니다.
빈스

16
onClick 메서드가 RecyclerView를 보유하는 조각에 있어야합니까? MyOnClickListener 클래스에서 mRecyclerView를 참조하기 때문입니다. 해당 객체에 대한 참조를 어디서 얻었습니까?
Ced

606

OnClickListenerfor 를 구현하는 더 좋고 덜 밀접하게 결합 된 방법 이 RecyclerView있습니다.

사용법 스 니펫 :

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 이행:

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
어떤 버튼이나보기 (항목 내)를 클릭했는지에 대한 단서는 제공하지 않습니다. 그러나 전체 항목 클릭의 경우 괜찮습니다.
Niranjan

27
ngen의 의견은 정확합니다. onClick 리스너를 항목보기 내의 특정 항목에 연결하려면 어댑터, onBindViewHolder 또는보기 표시기 자체에서 수행해야합니다.
Jacob Tabak

16
이 방법의 한 가지 문제점은 활동 시작과 같이 수백 밀리 초가 걸리는 작업을 수행 할 때입니다. 항목을 클릭하고 애니메이션을 클릭하면 애니메이션을 클릭하고 보는 것 사이에 눈에 띄는 지연이 있습니다.
Gak2

20
이 솔루션은 매우
어색한

6
GestureDetector가있는이 솔루션이 왜 해당 요소에 대한 어댑터의 onBindViewHolder () 내부에서 "setOnClickListener"를 사용하는 것보다 더 나은 솔루션인지 설명 할 수 있습니까? 이 방법으로 적어도 GestureDetector 솔루션보다 적은 코드가 필요합니다. 설명해 주셔서 감사합니다.
e-nature

115

나는 과도한 클래스, 탐지기 등이없는 방식 으로이 작업을 수행합니다. 어댑터 내부의 간단한 코드. 이전에 제시된 것보다 longClick에 대한 더 나은 솔루션.

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

그런 다음 조각이나 활동 내부에서 다음을 누르십시오.

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 대신 Marurban은 PasswordAdapter.clickListener를 의미하고 TrainingAdapter.ClickListener () 대신 PasswordAdapter.ClickListener () 여야한다고 생각합니다. 그 외에는 훌륭한 솔루션 Marurban! 나를 위해 일했다
nommer

긴 클릭시 onItemClick 리스너도 활성화됩니다.
Rashad.Z

10
최상의 성능을 위해서는 ViewHolder가 정적이어야합니다. 이것은 좋은 대답이 아닙니다.
Gilberto Ibarra

10
정적 clickListener는 메모리 누수를 만듭니다. 리스너를 정적이 아닌 것으로 선언하고 대신 ViewHolder에 바인딩하십시오.
BladeCoder

1
@AJW 가장 간단한 방법은 리스너를 초기에 초기화하여 인수로 어댑터 생성자에 전달한 다음 ViewHolder 생성자에 전달하는 것입니다.
BladeCoder 11

97

유사한 확인 질문 CommonsWare의 @ 의견 링크 구현 OnClickListener에 인터페이스를 viewHolder.

다음은 간단한 예입니다 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++){

        }


      }
  }

그러면 Adapter다음과 같이 보입니다.

    @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
이것은 잘못된 방향으로 가고있는 것 같습니다. 다른 프래그먼트 / 액티비티에서 recyclerview를 재사용해야하는 경우 이제 어댑터 / 뷰어 홀더는 클릭이 포함 된 것이 아니라 클릭의 논리를 정의합니다. 클릭은 포함하는 인스턴스에 의해 직접 또는 간접적으로 처리되어야합니다. 터치 리스너가 이에 대한 유일한 효과적인 방법 인 것 같습니다.
ian.shaun.thomas

18
@ tencent 나는 그것이 어떻게 문제인지 알지 못한다. ViewHolder 자체에 요소 자체를 클릭 할 때 선택된 데이터와 관련된 모든 정보가 포함 된 경우 컨테이너의 유일한 책임은 특정 i 번째 요소의 선택을 처리하는 것이 아니라 N 요소를 표시하는 것입니다. N 원소의. 은 ListView그냥 단순한 행보다 더 복잡 객체의 목록을 작성해야한다면 이미 문제가 있었다. ListView에서 항목을 클릭 한 위치에 따라 다른 이벤트를 처리해야하는 경우 어떻게합니까? 넌 망했어. 여기에는 각 청취자가 있습니다.
EpicPandaForce

2
나는 이것에 대해 @EpicPandaForce에 동의합니다. 또한 RecyclerViews에서 클릭 처리에 대한 Commonsware의 책 섹션을 읽은 후이 답변을지지했습니다. 지금까지 큰 도움이되었습니다.
AdamMc331 3

1
findViewById는 여기에서 뷰 홀더 작성시에만 사용됩니다 (따라서 onCreateViewHolder). 뷰 홀더는 항목을 처음 만들 때가 아니라 홀더에 바인딩 될 때마다 뷰를 찾지 못하도록하기위한 것입니다.
stuckj

2
getPosition()더 이상 사용되지 getAdapterPosition()않거나 getLayoutPosition()대신 사용하십시오.
K Neeraj Lal

94

Jacob Tabak의 답변 (+ 1)을 기반으로 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) {
    }
}

그런 다음 다음과 같이 사용할 수 있습니다.

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
내 앱에 적응하고 Java / Android 표준에 맞게 코드를 정렬하고 형식을 지정하는 데 시간이 걸렸지 만 결국 제대로 작동했습니다.
milosmns

긴 클릭에 대한 애니메이션을 어떻게 추가합니까?
Jon

1
@ Eng.Fouad 클릭 효과는 이것을 사용하여 작동하지 않습니다. 어댑터 클릭 효과에서 클릭 리스너를 설정하면 이에 대한 해결책이 작동합니다
ingsaurabh

4
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
Paolo Rotolo

어떤 이유로 클릭 된보기를 반환하지 않습니다. 필자의 경우 확인란을 클릭했지만 주어진보기는 ​​다릅니다. 내가 확인하는 방법 :view.getId() == R.id.selection
dVaffection

63

이것이 나를 위해 일한 것입니다. 를 연결 OnClickListener받는 onBindView. 이것이 이것이 성능에 영향을 줄지 모르겠지만 작은 코드로 잘 작동하는 것 같습니다.

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
내 경우에 holder.itemView.setOnClickListener (..)
D4rWiNS

18
내 경우에는 'view'대신 'itemView'라는 이름이 붙여져 있습니다. 초보자를 위해 말하면 일부는 복사하는 내용을 이해하지 못하고 왜 작동하지 않는지 알 수 없습니다.
D4rWiNS

3
레이아웃 위치
Bubunyo Nyavor

1
나를 위해 이것은 클릭 한 항목이 아닌 마지막으로 보이는 항목에만 적용되는 것 같습니다
Nasz Njoka Sr.

2
이 솔루션은 나에게 가장 좋은 것처럼 보이지만 성능 저하에서 @bolot의 답변과 어떻게 다릅니 까? 그는 onClick 메소드를 개별적으로 추출하는 것보다 ViewHolder 클래스에서 직접 View.OnClickListener를 구현했습니다. 가장 좋은 솔루션은 무엇입니까?
Edmond Tamas

46

이것은 액티비티에서 항목 클릭 리스너를 가지고 있고 항목 클릭 리스너에서 트리거되지 않는 항목의 단일보기에 대한 클릭 리스너를 갖는 것이 너무 어려웠습니다. Jacob Tabak의 답변을 가지고 놀면서 아이템 내부에 다른 터치 동작이 없으면 아이템 클릭에 대한 그의 답변을 존중합니다.

OnClickListener클릭 한 항목의보기와 어댑터의 항목 위치를 보유하는 항목 클릭 이벤트 가있는 사용자 정의 인터페이스가 있습니다. 생성자에 인스턴스를 제시하거나 setter와 함께 사용할 수 있으며 뷰 홀더 컨테이너 클릭 리스너에 연결합니다.

또한 컨테이너의 다른보기 리스너가 어댑터에서 볼 수 있습니다 (뷰 홀더에있을 수 있음). 컨테이너에서 현재보기 클릭을 처리합니다.

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

활동에서 인스턴스를 전달하여 어댑터를 초기화해야합니다. 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);
}

그리고 내 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);
}}

이 방법은 나를 위해 잘 작동 - 당신이 그리드 뷰 내부보다는 활동에 클릭을 처리 할 수 있다는 것을 의미합니다
leafcutter

3
어디서 돈을 줄 수 있습니까? 4 시간 동안 검색 한 다음 게시물을 읽었습니다. 이것을 게시하는 데 시간을 내 주셔서 감사합니다.
Brandon

3
이것은 바보처럼 들리지만 문제와 같은 메모리 나 효율성이 있습니까? 뷰가 올바르게 그려 질 때마다 클릭 리스너를 할당하기 때문에?
rgv

1
@Raghav yes 뷰가 바인드 될 때마다 새 클릭 리스너가 할당되지만 이것이 표준 흐름입니다. 그러나 mOnItemClickListener 어댑터 바로보기와 위치에 대한 각 항목 클릭에 다른 한 번만 생성)
경 니콜라이 세자르 첫

3
앱 성능을 저하시키고 메모리 남용을 만드는 훌륭한 예! 이 예제를 사용하면 수백 개의 쓸모없는 객체를 생성하기 위해 스크롤 만하면됩니다. @NoobDogg가 맞습니다. onBindView에서 ClickListener를 만들지 않았습니다. 클릭 리스너는 onCreateView (또는 홀더 생성자)에서 한 번 작성해야하며이 어댑터로 화면이 필요한 동안 존재합니다.
Mykola Tychyna

36

누군가가 유용하다고 생각하는 경우, 이것이 내가 필요한 결과입니다.

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

    }
}

출처 : http://blog.csdn.net/jwzhangjie/article/details/36868515


내가 시도한 모든 버전 중에서 이것은 내가 작동 한 버전입니다. 그러나 그렇게하는 것이 괜찮습니까? 아니면 모범 사례와 같은 더 나은 방법이 있습니까?
Matthias Loibl

1
내가 알 수있는 한, 이것이 유일한 방법이었습니다. 자세한 내용은 이것을 확인하십시오! stackoverflow.com/a/24933117/1508887
Fifer Sheep

onclick 메서드 내부에서 새 조각을 어떻게 열 수 있습니까?
해시

5
getAdapterPosition는 () ()에는 getPosition 대체
케네디 Nyaga

27

나는에 대한 좋은 솔루션이 RecyclerView'들onItemClickListener 항목과 하위 항목에 대한을

1 단계- 인터페이스 만들기

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

2 단계- 다음 onBindViewHolder과 같은 방법으로 어댑터의 방법으로 사용하십시오

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

    }

3 단계 : 이것을 사용하는 활동 또는 프래그먼트에서 리사이클 러보기 찾기 및 설정

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

4 단계- 마지막으로 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();
        }
    }

2
이것은 일반적으로 onItemClickListener의 활동 / 조각에서 많은 속성이 필요하며 뷰 홀더에서 직접 호출 할 필요가 없기 때문에 가장 좋은 솔루션입니다 (각 어댑터에 대해 사용자 정의 생성자를 작성해야 함). 그건 그렇고, 귀하의 코드는 약간 확장 적입니다. 가장 중요한 부분 (setOnItemClickListener)으로 자르는 것이 좋습니다.
sagits

이것은 하위 항목과 행 / 항목을 구별하기위한 좋은 간단한 접근 방법입니다.
Nigel Savage

17

여기 내가 한 일이 있습니다. 이 솔루션은 RecyclerView 항목과 RecyclerView 항목 내부보기 모두에서 onClick 및 onLongClick을 모두 지원합니다 (내부보기).

선택한 뷰에 viewHolder를 태그합니다.

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

그리고 holder.getPosition ()을 사용하여 onClick () 메서드에서 위치를 검색합니다 (onLongClick은 유사합니다).

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이있는 변형도 작동합니다. 내부보기의 경우 onClick ()에서 다음을 사용하십시오.

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

내 생각에,이 솔루션의 장점은 이미지를 클릭 할 때 onclick () 이미지 리스너 만 호출되는 반면 Jacob의 RecyclerView 항목보기 솔루션과 내부보기 솔루션을 onclick ( ) (이미지를 클릭 할 때)라고도합니다.


11

이 작업을 수행하는 훨씬 쉬운 방법이 있습니다. 클릭 인 신청onBindViewHolder루트 뷰 .

이것이 어댑터에 대한 관점이라고 생각하십시오.

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

그런 다음 어댑터에서 다음을 수행하십시오.

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

당신은 전달할 수 있습니다 clickListenerAdapter.

당신의 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);
        }
    }
};

그런 다음에 전달하십시오 Adapter.

MainAdapter mainAdapter = new MainAdapter(this, mItemClick);

에서 Adapter의 ' 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;
}

holder의도를 통해 값을 어떻게 전달 합니까?
RoCk RoCk

8

안드로이드 용 경량 라이브러리를 개발했습니다. https://github.com/ChathuraHettiarachchi/RecycleClick을 방문 하십시오.

다음 샘플을 따르십시오.

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

확인할 수 있습니다,이 도서관은 훌륭합니다! 매우 사용하기 쉽고 잘하셨습니다!
peterkodermac

7

OnClickListener를 ViewHolder 클래스에 구현할 수 있습니다

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

그리고 onBindViewHolder는 뷰 홀더의 항목을 설정합니다

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

7

너무 간단하고 효과적입니다.

View.OnClickListener뷰 홀더 내부에서 인터페이스를 구현하거나 활동에서 인터페이스를 만들고 인터페이스하고 구현 하는 대신 구현시 간단 하게이 코드를 사용했습니다 OnClickListener.

public static class SimpleStringRecyclerViewAdapter
            extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {

        // Your initializations goes here...
        private List<String> mValues;

        public static class ViewHolder extends RecyclerView.ViewHolder {

            //create a variable mView
            public final View mView;

            /*All your row widgets goes here
            public final ImageView mImageView;
            public final TextView mTextView;*/

            public ViewHolder(View view) {
                super(view);
                //Initialize it here
                mView = view;

                /* your row widgets initializations goes here
                mImageView = (ImageView) view.findViewById(R.id.avatar);
                mTextView = (TextView) view.findViewById(android.R.id.text1);*/
            }
        }

        public String getValueAt(int position) {
            return mValues.get(position);
        }

        public SimpleStringRecyclerViewAdapter(Context context, List<String> items) {

            mBackground = mTypedValue.resourceId;
            mValues = items;
        }

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

        @Override
        public void onBindViewHolder(final ViewHolder holder, int position) {
            holder.mBoundString = mValues.get(position);
            holder.mTextView.setText(mValues.get(position));

            //Here it is simply write onItemClick listener here
            holder.mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Context context = v.getContext();
                    Intent intent = new Intent(context, ExampleActivity.class);

                    context.startActivity(intent);
                }
            });
        }

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

3
너무 쉬운 것처럼 보이기 때문에 일반적인 나쁜 습관입니다. a) 성능 b) 가비지 콜렉션에 좋지 않은 오브젝트가 바인드 될 때마다 (그리고 리사이클 러의 각 항목이 여러 번 바인드 될 수 있음) 새 내부 리스너를 작성합니다. 대신 ONE 리스너를 어딘가에 (뷰 홀더, 어댑터, 상위 조각 또는 활동에) 작성하고 onCreateViewHolder의 뷰 홀더 생성자 항목에 추가해야합니다. 이로 인해 어떤 항목이 클릭 장치인지 파악해야하는 복잡성이 추가되었지만 태그를 통해 또는 홀더에 정보를 추가하여 쉽게 해결할 수 있습니다.
GuillermoMP

6

지금까지 게시 된 모든 답변은 훌륭한 솔루션이지만 너무 많은 구현 세부 사항을 처리하지 않고 ListView와 비슷한 방식으로 작동하려면 다음과 같이 TwoWay-View를 사용하는 것이 좋습니다.

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

이 구현은 항목을 길게 누르는 것뿐만 아니라 눌러 진 상태에 대한 지원도 지원합니다 (이 질문에 대한 다른 솔루션이 부족한 중요한 사항 임).

전체 라이브러리를 사용하지 않으려면 필요한 경우 독립형으로 사용할 수있는 ClickItemTouchListener 클래스를 살펴보십시오 . 내가 지금 찾은 유일한 문제는 길게 누르기 + 스크롤을 사용하는 것입니다. 잘못된 동작이있는 것 같습니다.


6

개별 이벤트에서 클릭 이벤트를 잡으려면 클래스 OnClickListener에서 구현 ViewHolder한 다음 개별 뷰 또는 전체에서 클릭 리스너를 설정하십시오.itemView .

다음 예제는 동일한 것을 보여줍니다

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

나에게 이것은 가장 좋은 방법입니다.

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 ()가
중단되었습니다

5

RecyclerView없습니다OnClickListener 그리고 그것을 자신을 구현해야합니다.

에서 항목보기를 클릭하면 호출 된 메소드 로 OnItemClickListener인터페이스 를 추가하고 싶습니다 . 따라서 항목에 클릭을 관리하는 책임이 외부에있는 및AdapteronClickViewHolderViewHolderAdapter 있습니다. 해야 할 일을 결정할 활동이나 파편이 있습니까?

리스너와 리스너 객체에 인터페이스를 추가하십시오.

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

  ...

  private static OnItemClickListener onItemClickListener;

  ...

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

  ...
}

콜백이 트리거 될 때 항목의 루트보기 클릭과 onClick어댑터에서 리스너 호출을 캡처합니다 .

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

우리의 경우에는 액티비티 또는 프래그먼트, 프래그먼트 인 Fragment이므로 어댑터에 리스너를 할당하고 onClick 콜백은 위치별로 선택한 항목을 가져 와서 세부 항목 활동을 엽니 다.

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

불행히도 내장 RecyclerView기능이 몇 가지 없습니다 ListView. 예를 들어 OnItemClickListener항목을 클릭하면 트리거 되는 추가 기능이 있습니다 . RecyclerView를 사용하면 OnClickListener어댑터에서을 설정할 수 있지만 호출 코드에서 어댑터 및로 해당 클릭 리스너를 전달하는 것은 ViewHolder간단한 항목 클릭을 잡는 데 복잡합니다.

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

R.id.item_click_supportids.xml 을 사용 하여 정의해야합니다 .

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

결과 코드 클릭 리스너는 이제 다음과 같습니다.

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

recyclerview 클릭에 대한 간단한 설명은 littlerobots_blog를 참조하십시오.


5

다음과 같이 ViewHolder 클래스에서 setOnClickListener 를 쉽게 정의 할 수 있습니다 .

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

여기 내가 한 일이 있습니다 더 읽기 & 요점을 여기에서 다운로드하십시오

여기에 같은 것을 추가

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

위의 대부분의 답변에서 클릭 유도자를 개별 항목으로 설정하는 것으로 보입니다. 그러나 제공하려는 솔루션은 매우 간단하지만 많은 사람들에게는 직관적이지 않습니다. 많은 구성 요소는 다른 구성 요소가 항상 목록 또는 재활용 기보기에 항목을 표시하는 데 사용되는 상위 구성 요소에 있다는 것을 잊고 있습니다. 이 솔루션은 단지 하나의 onclick 리스너를이 부모 뷰로 설정하는 것입니다. 이 솔루션에는 목록 또는 재활용보기에서 클릭중인 항목의 위치를 ​​전달하는 방법도 포함되어 있습니다. 여기서 우리의 주요 루트보기는 안드로이드 지원 라이브러리의 CardView입니다. 샘플 코드는 다음과 같습니다

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

Nhaarman의 답변에 대한 Kotlin 구현 :

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

다음은 내 사용자 정의 어댑터에 대한 완전한 코드입니다.이 코드는 "list_item"이라는 xml 파일에 정의 된 목록 항목으로 행을 확장합니다. 또한 각 위치의 모든 목록 항목 행에서 클릭 이벤트를 수행합니다.

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

Java 약한 참조를 사용하여이 작업을 수행 할 수 있습니다. 의미 적으로 뷰 홀더는 클릭 이벤트에 응답하거나 올바른 응답자에게 위임해야합니다.

우리의 목표 :

  1. 뷰 홀더는 특정 인터페이스를 구현한다는 점을 제외하고 이벤트에 응답하는 클래스에 대해 아무것도 알아야합니다.
  2. 클릭 핸들러는 클릭 한 뷰의 RecyclerView에서 위치를 가져와야합니다.
  3. 우리는 어느 것을 분별할 수 있어야한다뷰 홀더에서 클릭 뷰 .
  4. 모든 구성 요소 사이에 느슨한 결합을 유지하고 유지주기를 발생시키지 마십시오.

단계 :

  1. 클릭 응답을 처리하기위한 인터페이스를 만듭니다.

  2. 클릭을 처리 할 활동에이 인터페이스를 구현하십시오.

  3. RecyclerView 어댑터에 멤버 변수를 추가하여 약한 참조 및이를 설정하는 생성자를 보유하십시오.

  4. RecyclerView ViewHolder에서 동일한 작업을 수행하고 멤버 변수를 추가하여 위치를 추적하십시오.

  5. ViewHolder에서 원하는 모든보기에서 클릭 리스너를 설정 한 다음 응답자를 콜백하여 처리하십시오.

  6. 바인딩 할 때 위치를 설정하도록 onBindViewHolder 메소드를 변경하십시오.

  7. 응답자를 ViewHolder로 전달하십시오.

  8. 응답자에서 이제 뷰에서 getId ()를 사용하여 클릭 한 뷰를 파악할 수 있습니다.

그리고 여기 요지가 있습니다. 모두 잘 어울리는 지 확인할 수 있습니다 : RecyclerView 클릭 처리


2

나는 많은 답변이 있다는 것을 알고 있지만 구현을 제공 할 수도 있다고 생각했습니다. ( 내가 대답 한 다른 질문 에서 자세한 내용을 확인할 수 있습니다. ).

따라서 클릭 리스너를 추가하려면 내부 ViewHolder클래스가 구현해야합니다 View.OnClickListener. 의 생성자 OnClickListeneritemView매개 변수에 를 설정하기 때문 ViewHolder입니다. 내가 무엇을 의미하는지 보여 드리겠습니다.

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

추가해야 할 유일한 것은 사용자 Adapter및 setter 메소드에 대한 사용자 정의 인터페이스입니다 .

private OnEntryClickListener mOnEntryClickListener;

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

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

새로운 클릭 지원 Adapter이 완료되었습니다.

이제 사용합시다 ...

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

Adapter사용자가 특정 목록 항목을 클릭 할 때 수행 할 작업을 제어하기 위해 만든 setter 메소드를 사용하는 것을 제외하고 는 기본적으로 normal 설정 방법입니다.

GitHub에서이 요지에 대한 예제를 살펴볼 수도 있습니다.

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


getLayoutPosition () 대신 getAdapterPosition ()을 사용해야합니다.
BladeCoder

2

이것이 제가 재사용하기 위해하는 일입니다 OnClickListener

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

ViewHoder에서 itemlayout의 부모 가져 오기

  public class MyviewHolder extends RecyclerView.ViewHolder {

       LinearLayout linearLayout_item;

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

onBindViewHolder에서 태그를 위치로 설정

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

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

그리고 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;
    }
}

2

나를 위해 그것을하는 깨끗한 방법은 이것입니다.

어댑터 생성자

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

연결된 인터페이스

private interface EnvironmentTypeRecyclerViewAdapterListener
{
    void onListItemSelected(Environment environment);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.