处理物品的正确方法点击回收站视图

Posted

技术标签:

【中文标题】处理物品的正确方法点击回收站视图【英文标题】:Proper Way to Handle Item Click Recycler View 【发布时间】:2018-10-18 14:06:18 【问题描述】:

我有 5 行要显示在 RecyclerView 中。当用户单击其中一个项目时,会打开另一个活动。每个项目都有开始不同的活动。我处理了如下点击事件。

switch (getAdapterPosition()) 
                case 1:
                    ActivityUtil.startActivity(itemView.getContext(), BlablaActivity.class);
                    break;
                //other cases

它工作正常。但是,如果将来将新项目添加到列表中怎么办?对于每一个项目,我都必须在 switch-case 中添加一个新的 case。根据开闭原则,这不是一个合适的解决方案。我应该如何处理?任何建议都会很棒...

【问题讨论】:

你无法避免这一点。因为您必须在每个项目上打开不同的活动(或者我们可以说执行不同的操作)。您可以做的事情是将活动命名为与其在列表中的相关项目位置相似的名称,例如 activity_1,以便活动在第一个项目处打开。 您可以做的是将项目引用的活动存储在列表中,并动态进行 为什么不直接创建一个 POJO,它还存储您希望作为字段触发的活动类? @JoaquinAlvarez 谢谢。你的方法很有帮助。我只是将 activityName 变量创建为 Class 而不是 String。 【参考方案1】:

首先保存项目在您的数据库中引用的活动,然后将其添加到您的类型列表模型中,如果是这样的话

yourlist.java
....
private String BLABLA;
private String BLABLA1;
private String ActivityName;
....

然后在您的适配器 OnBindViewholder OnClick 中执行类似这样的操作

  @Override
        public void onClick(View v) 

            activityString = singleItem.getActivityName();
            Intent intent= new Intent(context, Class.forName(activityString));
            context.startActivity(intent);
        
    );

【讨论】:

【参考方案2】:

理想情况下,您应该将Class<? extends Activity> 字段添加到代表您的 RecyclerView 项目的类中。然后你可以在你的点击监听器中访问这个字段(这段代码在onCreateViewHolder()里面):

holder.itemView.setOnClickListener(v -> 
    int position = holder.getAdapterPosition();

    if (position != RecyclerView.NO_POSITION) 
        Class<? extends Activity> activityClass = items.get(position).getActivityClass();
        ActivityUtil.startActivity(v.getContext(), activityClass);
    
);

这样,每个项目负责知道点击时的去向。您可以将新项目添加到您的列表中,而无需触摸适配器代码。

【讨论】:

【参考方案3】:

如果您严格地使 RecyclerView 适配器仅作为视图工作,即仅在视图中显示数据,则可以轻松处理。所有的逻辑决策责任都应该委托给父活动或片段。这可以通过使用回调/监听器来实现。

只要RecyclerView item 有点击事件,告诉父activity或者fragment去处理。

你需要把你的适配器改成这样:

public class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> 

    // Local variable for listener
    private OnItemClickListener listener;

    // Listener interface
    public interface OnItemClickListener 
        void onItemClick(View itemView, int position);
    

    // set the listener on parent activity or fragment
    public void setOnItemClickListener(OnItemClickListener listener) 
        this.listener = listener;
    


    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener 

      ....

      public ViewHolder(final View itemView) 
        super(itemView);

        itemView.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    if (listener != null) return;
                    // tell the parent to handle the item.
                    listener.onItemClick(itemView, position);
                
            );
      

    

那么你可以使用下面的方法来处理点击:

// assuming adapter is your adapter
adapter.setOnItemClickListener(new ContactsAdapter.OnItemClickListener() 
    @Override
    public void onItemClick(View view, int position) 
        handleItemClickByPosition(position);
    
);

...

private void handleItemClickByPosition(int position) 
   switch (getAdapterPosition()) 
     case 1:
       ActivityUtil.startActivity(itemView.getContext(), BlablaActivity.class);
       break;
       //other cases
  

因此,每当您的适配器中有新项目时,您都不需要更改适配器。

【讨论】:

他想动态地处理开关盒,而不必为每个项目创建一个案例

以上是关于处理物品的正确方法点击回收站视图的主要内容,如果未能解决你的问题,请参考以下文章

一次刷一件物品Recyclerview [复制]

在回收站视图中访问对象的正确高度

回收站视图点击动画

如何在recyclerView中管理点击事件

在回收站视图上点击第一个匹配的文本 Android espresso 测试

处理项目长按回收站视图