【问题标题】:Can I switch between onClickListener and onLongClickListener on the run time?我可以在运行时在 onClickListener 和 onLongClickListener 之间切换吗?
【发布时间】: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);

}

【问题讨论】:

    标签: android events android-recyclerview onclicklistener onlongclicklistener


    【解决方案1】:

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

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

    2. 您可以将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,我的想法是我应该先长按一个项目然后我可以只需单击正常单击任何其他项目即可将其选中
    猜你喜欢
    • 2013-03-14
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    相关资源
    最近更新 更多