【问题标题】:RecyclerView onItemClick ListenerRecyclerView onItemClick 监听器
【发布时间】:2015-03-07 06:49:07
【问题描述】:

如何实现RecyclerView onItemClick 监听器,就像我们使用 ListView 一样,这是我使用 ListView 的旧适配器类:

public class GenreAdapter extends BaseAdapter {

....

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // convert view = design
    View v = convertView;
    if (v == null) {
        holder = new ViewHolder();
        v = vi.inflate(Resource, null);
        holder.textTitle = (TextView) v.findViewById(R.id.textTitle);
        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }

    holder.textTitle.setText(genreArrayList.get(position).getTitle());

    v.setOnClickListener(new OnClickListener() {

       @Override
       public void onClick(View v) {                          

           Bundle bundle = new Bundle();
           bundle.putSerializable("data", genreArrayList);
           bundle.putInt("current", position);             

           Intent intent = new Intent(context, MovieActivity.class);
           intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
           intent.putExtras(bundle);
           context.startActivity(intent);

        }
    });

    return v;
}

static class ViewHolder {
    public TextView textTitle;
}

MainFragment.java:-

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_main, container, false);

        /* Initialize recycler view */
        mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));

        list = new ArrayList<MainPoho>();
        adapter = new MainAdapter(getActivity(), list);
        mRecyclerView.setAdapter(adapter);

        .......

}

这是我使用RecyclerView 的新Adapter 类:

public class MyRecyclerAdapter extends RecyclerView.Adapter<FeedListRowHolder> {

    private List<FeedItem> feedItemList;
    private Context mContext;

    public MyRecyclerAdapter(Context context, List<FeedItem> feedItemList) {
        this.feedItemList = feedItemList;
        this.mContext = context;
    }

    @Override
    public FeedListRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, null);
        FeedListRowHolder mh = new FeedListRowHolder(v);
        return mh;
    }

    @Override
    public void onBindViewHolder(FeedListRowHolder feedListRowHolder, int i) {
        FeedItem feedItem = feedItemList.get(i);        
        feedListRowHolder.title.setText(Html.fromHtml(feedItem.getTitle()));
    }

    @Override
    public int getItemCount() {
        if(feedItemList !=null){
            return feedItemList.size();
          } else {
            return 0;
          }
    }

public class FeedListRowHolder extends RecyclerView.ViewHolder {
    protected TextView title;

    public FeedListRowHolder(View view) {
        super(view);
        this.title = (TextView) view.findViewById(R.id.title);
    }

FeedItem.java:-

public class FeedItem {
    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}

【问题讨论】:

    标签: android android-5.0-lollipop onitemclicklistener android-recyclerview


    【解决方案1】:

    首先将整个视图存储在您的 viewHolder 中:

      public class FeedListRowHolder extends RecyclerView.ViewHolder {
         protected TextView title;
         protected View mRootView;
    
        public FeedListRowHolder(View view) {
            super(view);
            this.title = (TextView) view.findViewById(R.id.title);
            mRootView = view;
        }
    

    然后在onBindViewHolder设置点击监听:

    @Override
    public void onBindViewHolder(FeedListRowHolder feedListRowHolder, int i) {
        FeedItem feedItem = feedItemList.get(i);        
        feedListRowHolder.title.setText(Html.fromHtml(feedItem.getTitle()));
        feedListRowHolder.mRootView.setOnClickListener(new OnClickListener(){
    
            @Override
            public void onClick(View v) {
    
            }
       });
    }
    

    【讨论】:

    • 谢谢,但它只有在我连续点击文本时才有效,而在列表视图中,无论我们在哪里点击一行都有效......那可能是什么原因?
    • 我认为如果你将点击监听器设置为 rootview 你会得到你想要的。
    • 我不知道你的问题到底是什么,我看到了你的另一篇文章,抱歉,我现在无法创建任何示例项目来测试,但我已经实现了我在我的一个应用程序中发布的内容: -(
    • 我不是在寻找任何示例项目,我担心的是为什么当我点击行时点击没有响应
    • 当你扩展RecyclerView.ViewHoldermRootView已经可用,但是被称为itemView
    【解决方案2】:

    首先你必须实现你自己的 OnItemTouchListener :

    static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{
    
        private GestureDetector gestureDetector;
    
        public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener){
            gestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    //here get the view that has been touched
                    View child = recyclerView.findChildViewUnder(e.getX(),e.getY());
    
                    //now pass the item and its position to your click listener 
                    if(child!=null && clickListener!=null){
                        clickListener.onClick(child, recyclerView.getChildPosition(child));
                    }
    
                    return true;
                }
    
                @Override
                public void onLongPress(MotionEvent e) {
                }
            });
        }
    
        public static interface ClickListener {
            public void onClick(View view, int position);
        }
    
        @Override
        public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
            //use the gesture detector to intercept singletap and longtouch events
            gestureDetector.onTouchEvent(motionEvent);
            return false;
        }
    
        @Override
        public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
        }
    }
    

    然后您将必须实现将由上面的 RecyclerTouchListener 调用的 ClickListener:

    private RecyclerTouchListener.ClickListener mClickListener =  new RecyclerTouchListener.ClickListener() {
        @Override
        public void onClick(View view, final int position) {
                //Do something with your item...
                mRecyclerAdapter.getElementAt(position).doSomething();
    
            }
    
        }
    

    【讨论】:

      【解决方案3】:

      我知道这有点晚了,但对于那些徘徊并没有迷路的人来说。我找到了这个优雅的解决方案here

      所以基本上你创建了一个如下所示的 ItemClickSupport 类

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

      然后在您定义并绑定您的 recyclerView 的活动/片段中,只需执行以下操作

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

      另外,您需要在 res/values 文件夹中创建一个 ids.xml 文件并在其中定义以下内容

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

      我希望这会有所帮助。仍然建议您通过article 阅读更多相关信息。

      【讨论】:

        猜你喜欢
        • 2012-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多