我可以在运行时在 onClickListener 和 onLongClickListener 之间切换吗?

Posted

技术标签:

【中文标题】我可以在运行时在 onClickListener 和 onLongClickListener 之间切换吗?【英文标题】:Can I switch between onClickListener and onLongClickListener on the run time? 【发布时间】:2020-10-22 14:30:33 【问题描述】:

我在RecyclerView的适配器的ViewHolder类中为item添加了OnClickListener和OnLongClickListener

这个想法基本上是,当我想选择一个项目时,我应该第一次长按它,然后我应该做一个正常的短按来选择其他项目

以下是视图持有者的代码,带有长点击和普通点击的接口 接口将由片段的类实现,接口的方法将被覆盖。如代码所示,我根据 MultipleSelectionOn(这是一个布尔变量)在长单击和正常单击 linsener 之间创建了 if 条件。但是,当我长按该项目时,MultipleSelectionOn 变量会更改为 true,但不会执行 onClickListner。

public class DevicesViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener

    LinearLayout device_item_layout;
    TextView title,status;
    ImageView deleteIcon, selectionBtn;

    OnItemClick onItemClick;
    OnItemLongClick onItemLongClick;

    public DevicesViewHolder(@NonNull View itemView, OnItemClick onItemClick, OnItemLongClick onItemLongClick) 
        super(itemView);

        device_item_layout = itemView.findViewById(R.id.device_item);
        title = itemView.findViewById(R.id.title);
        status = itemView.findViewById(R.id.status);
        deleteIcon = itemView.findViewById(R.id.deleteIcon);
        selectionBtn = itemView.findViewById(R.id.selectionBtn);

        this.onItemClick = onItemClick;
        this.onItemLongClick = onItemLongClick;

        if(MultipleSelectionOn == false) 
            itemView.setOnClickListener(null);
            itemView.setOnLongClickListener(this);
        else
            itemView.setOnLongClickListener(null);
            itemView.setOnClickListener(this);
        

    

    @Override
    public boolean onLongClick(View view) 

        Log.i("MultipleSelectionOn ", String.valueOf(MultipleSelectionOn));

        onItemLongClick.onItemLongClick(getAdapterPosition(), view);

        MultipleSelectionOn = true;

        return true;
    

    @Override
    public void onClick(View view) 

        Log.i("MultipleSelectionOn ", String.valueOf(MultipleSelectionOn));

        onItemClick.onItemClick(getAdapterPosition(), view);

    




public interface OnItemLongClick

    void onItemLongClick(int position, View view);



public interface OnItemClick

    void onItemClick(int position, View view);


【问题讨论】:

【参考方案1】:

首先初始化setOnLongClickListenersetOnClickListener。对于行动,您可以通过多种方式做到这一点 -

    当用户长按它时,创建一个与 recyclerView 的项目重叠的视图。它会模仿项目的选择。还可以使用isSelected 之类的标志。当用户长按一个项目时,标志的值将被改变。在setOnClickListener 中添加一个条件,如果isSelected 不等于true,则在点击侦听器中执行任何操作。标志isSelected 将在适配器中。

    您可以将isSelected 放入recyclerView 实现的模态类中。并在setOnLongClickListener 中相应地将其值更新为truefalse。然后在setOnClickListener 中添加一个条件,如果isSelected 不等于true,则在点击侦听器中执行任何操作。但是这次你使用了isSelected 的值,该值与特定位置的模态类对象相关联。

【讨论】:

谢谢,您的回答解决了!但是我没有理解第二点,什么是模态类? 我的意思是,假设您有一个 List<User> 已传递给适配器。所以列表中的每一项,即; User 有一个类似 isSelected 的标志。默认情况下,列表中的每个项目都是false【参考方案2】:

当你初始化ViewHolder时,你应该同时设置onClickListeneronLongClickListener

public DevicesViewHolder(...) 
    ...

    itemView.setOnLongClickListener(this);
    itemView.setOnClickListener(this);

【讨论】:

我在这里删除了 if 条件 if(MultipleSelectionOn == false) itemView.setOnClickListener(null); itemView.setOnLongClickListener(this); else itemView.setOnLongClickListener(null); itemView.setOnClickListener(this);但是现在我可以使用普通点击和长按来选择项目,这不是我想要的想法是我应该先长按一个项目,然后我可以单击正常点击任何其他项目选择它【参考方案3】:

你可以这样做

public interface OnItemLongClick 

    void onItemLongClick(int position, View view);




public interface OnItemClick 

    void onItemClick(int position, View view);



public class DevicesViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener 

    LinearLayout device_item_layout;
    TextView title, status;
    ImageView deleteIcon, selectionBtn;

    OnItemClick onItemClick;
    OnItemLongClick onItemLongClick;

    public DevicesViewHolder(@NonNull View itemView, OnItemClick onItemClick, OnItemLongClick onItemLongClick) 
        super(itemView);

        device_item_layout = itemView.findViewById(R.id.device_item);
        title = itemView.findViewById(R.id.title);
        status = itemView.findViewById(R.id.status);
        deleteIcon = itemView.findViewById(R.id.deleteIcon);
        selectionBtn = itemView.findViewById(R.id.selectionBtn);

        this.onItemClick = onItemClick;
        this.onItemLongClick = onItemLongClick;
        itemView.setOnLongClickListener(this);
        itemView.setOnClickListener(this);

    

    @Override
    public boolean onLongClick(View view) 

        Log.i("MultipleSelectionOn ", String.valueOf(MultipleSelectionOn));

        onItemLongClick.onItemLongClick(getAdapterPosition(), view);

        MultipleSelectionOn = true;

        return true;
    

    @Override
    public void onClick(View view) 

        Log.i("MultipleSelectionOn ", String.valueOf(MultipleSelectionOn));
        if (MultipleSelectionOn) 
            onItemClick.onItemClick(getAdapterPosition(), view);
        

    

【讨论】:

我需要设置条件以确保在我单击正常单击项目时第一次不执行setOnClickListener,我的想法是我应该先长按一个项目然后我可以只需单击正常单击任何其他项目即可将其选中

以上是关于我可以在运行时在 onClickListener 和 onLongClickListener 之间切换吗?的主要内容,如果未能解决你的问题,请参考以下文章

Android:将 onClickListener 设置为 TextView 中的部分文本 - 问题

定义一个可以在运行时在视图之间切换的故事板

为啥我不能在第一次运行时在 UISplitViewController 中将 Master 和 Detail 视图彼此相邻放置,但在旋转时它可以工作?

如何在启动时在后台运行django服务器?

MFC在运行时在优化校准中显示图像[重复]

Android:如果我将 Switch OnClickListener 放在 FragmentActivity 上,我的应用程序将无法运行