在RecyclerView本身上设置onClickListener不在项目上

时间:2018-06-26 13:30:51

标签: android android-recyclerview onclicklistener

我想在RecyclerView中设置onClickListener,不要在其项目上设置。因此,如果用户单击Recyclerview,它会触发click事件(即使它是空的RecyclerView或已装满物品)。

  • 我正在使用MVVM。
  • 我尝试了mRecyclerView.setClickable(true),无法正常工作;

我想要的

mRecyclerView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        }
    });

我的适配器类

public class TaskItemAdapter extends RecyclerView.Adapter<TaskItemAdapter.BaseItemAdapterViewHolder> {
private static final String TAG = TaskItemAdapter.class.getSimpleName();
private List<Task> mTaskList;
private View.OnLongClickListener mOnLongClickListener;

public TaskItemAdapter(List<Task> taskList, View.OnLongClickListener longClickListener) {
    mTaskList = taskList;
    mOnLongClickListener = longClickListener;
}

@NonNull
@Override
public BaseItemAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    if (parent instanceof RecyclerView) {
        int layoutId = R.layout.item_list_main;
        View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
        view.setFocusable(true);
        return new BaseItemAdapterViewHolder(view);

    } else {
        throw new RuntimeException(TAG + "Not bound to recyclerView");
    }
}

@Override
public void onBindViewHolder(@NonNull BaseItemAdapterViewHolder holder, int position) {
    Task task = mTaskList.get(position);
    holder.mItemTextView.setText("- " + task.getName());

    holder.itemView.setTag(task);
    holder.itemView.setOnLongClickListener(mOnLongClickListener);

}

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

public void loadItems(List<Task> taskList) {
    mTaskList = taskList;
    notifyDataSetChanged();
}


public class BaseItemAdapterViewHolder extends RecyclerView.ViewHolder {
    @BindView(R.id.item_textView)
    TextView mItemTextView;

    public BaseItemAdapterViewHolder(View view) {
        super(view);
        ButterKnife.bind(this, view);

    }

}

}

6 个答案:

答案 0 :(得分:2)

<div canvas="container">

<!-- Header -->
<nav class="navbar navbar-expand-sm bg-dark navbar-dark fixed-top">

</nav>

<!-- Sidebar -->
<div off-canvas="id-1 left overlay">

</div>

<!-- Footer -->
<nav class="navbar navbar-expand-sm bg-dark navbar-dark fixed-bottom">

</nav>

</div>

然后只处理所需的MotionEvent类型。如果您不希望RecylerView用它做任何其他事情,则返回true。

答案 1 :(得分:1)

从View.OnTouchListener onTouch()按下并释放事件。可以触发视图。

答案 2 :(得分:0)

我设法通过:

我将两个侦听器传递给适配器:

<nav class="navbar navbar-default navbar-fixed-top">
    <div class="container-fluid">
        <a class="navbar-brand" href="#"><img src="#" alt="logo"></a>
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="modal" data-target="#nav-modal" aria-expanded="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="fa fa-bars fa-2x" id="menu-icon"></span>
            </button>
        </div>    
    </div>
</nav>


<div class="modal fade" id="nav-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-nav-content">
            <div class="row modal-nav-body">
                <ul>
                    <li class="nav-item">
                        <a href="#" id="home">about</a>
                    </li>
                    <li class="nav-item">
                        <a href="#" id="about">Chi siamo</a>
                    </li>
                    <li class="nav-item">
                        <a href="#" id="services">Servizi</a>
                    </li>
                    <li class="nav-item">
                        <a href="#" id="contacts">Contatti</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>

在方法View.OnClickListener; View.OnTouchListener; 中,我设置了两个侦听器并将recyclerViewID传递到标签中。

onCreateViewHolder

在主要活动中:

  1. int layoutId = R.layout.item_list_main; View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); view.setFocusable(true); parent.setOnTouchListener(mOnTouchListener); view.setTag(R.id.PARENT_VIEW_ID, parent.getId()); view.setOnClickListener(mOnClickListener); return new BaseItemAdapterViewHolder(view); 在recyclerView的空白空间中操作 本身。
  2. View.OnTouchListener在recyclerView的项目中运行。
  3. 并使用空布局的点击侦听器。

因此,现在无论用户单击recyclerView或其项目,还是其空状态,都将触发整个点击。

答案 3 :(得分:0)

当您在onCreateView中将焦点设置为Adapter视图时,您的父级(aka recyclerview将不会获得焦点,除非您设置焦点规则。)您可以尝试

recycler.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);

答案 4 :(得分:0)

您可以在适配器内部添加View,而不是将onClick侦听器添加到RecyclerView。

@Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recycler_layout, parent, false);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext,"RecyclerView Clicked", Toast.LENGTH_SHORT).show();
            }
        });

        return new MyViewHolder(itemView);
    }

答案 5 :(得分:0)

默认情况下,RecyclerView不提供OnClick回调。因此,您可以创建一个OnTouchListener来使用点击事件。

public class RVClickHandler implements View.OnTouchListener {

    private RecyclerView mRecyclerView;
    private float mStartX;
    private float mStartY;

    public RVClickHandler(RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        boolean isConsumed = false;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                mStartX = event.getX();
                mStartY = event.getY();
                break;
            }
            case MotionEvent.ACTION_UP: {
                float endX = event.getX();
                float endY = event.getY();
                if(detectClick(mStartX, mStartY, endX, endY)) {
                    //Ideally it would never be called when a child View is clicked.
                    //I am not so sure about this.
                    View itemView = mRecyclerView.findChildViewUnder(endX, endY);
                    if(itemView == null) {
                        //RecyclerView clicked
                        mRecyclerView.performClick();
                        isConsumed = true;
                    }
                }
                break;
            }
        }
        return isConsumed;
    }

    private static boolean detectClick(float startX, float startY, float endX, float endY) {
        return Math.abs(startX-endX) < 3.0 && Math.abs(startY-endY) < 3.0;
    }

}

如下所示将其添加到您的RecyclerView

recyclerView.setOnTouchListener(new RVClickHandler(recyclerView));

现在,您可以附加普通的OnClickListener来处理点击。

recyclerView.setOnClickListener((v) -> {
    //Called when an empty space is clicked inside RecyclerView.
});

可以在ViewHolder内处理子视图的点击事件