【问题标题】:SwipeRefreshLayout blocks onClickCallback of item in nested RecyclerViewSwipeRefreshLayout 阻止嵌套 RecyclerView 中项目的 onClickCallback
【发布时间】:2020-02-23 18:48:13
【问题描述】:

我有一个带有嵌套 RecyclerView 的 SwipeRefreshLayout。回收站视图中的每个项目本质上都是一个附加了 onClickHandler 的 CardView。我有一个问题,如果回收站视图滚动到最顶部,我的 clickHandler 不会被调用。如果我向下滚动 1 px,我可以点击一些东西。

在触摸事件和点击事件上添加打印输出语句后,滑动刷新布局似乎也会拦截触摸事件和setTargetOffsetTopAndBottom。这会调用requestLayout,最终似乎会导致ACTION_CANCEL 事件。如果我向下滚动回收站视图 1px canChildScrollUp() 将返回 true 并停止 SwipRefreshLayout 的 requestLayout 调用。

// SwipeRefreshLayout.java
public boolean onInterceptTouchEvent(MotionEvent ev) {
    ...
    if (!isEnabled() || mReturningToStart || canChildScrollUp()
            || mRefreshing || mNestedScrollInProgress) {
        // Fail fast if we're not in a state where a swipe is possible
        return false;
    }
    ...
    switch (action) {
        case MotionEvent.ACTION_DOWN:
            setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCircleView.getTop());
            mActivePointerId = ev.getPointerId(0);
            mIsBeingDragged = false;

            pointerIndex = ev.findPointerIndex(mActivePointerId);
            if (pointerIndex < 0) {
                return false;
            }
            mInitialDownY = ev.getY(pointerIndex);
            break;
    ...

布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ticket_wallet_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/ticket_wallet_recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:itemCount="3"
        tools:listheader="@layout/ticket_header_item"
        tools:listitem="@layout/active_ticket_item" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

ViewHolder

sealed class FooViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    abstract fun bind(item: WalletItem)

    class ActiveFooViewHolder(
        view: View,
        private val remainingTimeFormatter: RemainingTimeFormatter,
        private val callback: (Int) -> Unit
    ) : FooViewHolder(view) {

        init {
            view.setOnClickListener {
                callback(adapterPosition)
            }
   ...

我的编译目标是 Android API lvl 29。

【问题讨论】:

    标签: android android-recyclerview onclick swiperefreshlayout


    【解决方案1】:

    我也遇到过同样的问题。我确实有一个 ConstraintLayout 包装了 SwipeRefreshLayout。当我删除 ConstraintLayout(将其替换为 LinearLayout)时,问题已解决。希望有帮助。我不知道它为什么起作用。

    【讨论】:

    • 使用 LinearLayout 设置父布局解决了这个问题。
    • 对我来说这行得通!我可以用 LinearLayout 更改 ConstraintLayout。我试过嵌套布局: - ConstraintLayout>LinearLayout>SwipeRefreshLayout 不起作用。我尝试在元素上放置边距/填充: - 在 SwipeRefreshLayout 上放置填充效果!保证金不起作用。它必须是顶部或底部;开始/结束/左/右不起作用。它可以是 1px、0.1px 甚至更小,直到特定程度。这很奇怪。看起来像一个错误。
    【解决方案2】:

    我遇到了类似的问题。在我的情况下,onClick 被阻止了几秒钟,然后神奇地返回。滚动可能也解决了它,但我没有足够的项目来滚动它们(在我的应用程序中,我显示了 3-5 个蓝牙设备)。 OnTouch 激活成功; onClick 不是。

    我尝试了此处提出的答案,但没有帮助。 thisthis 也没有。

    意外地解决了这个问题是在我的addDevice(BluetoothDevice device) 函数中使用notifyItemInserted(int position) 而不是notifyDataSetChanged()

    我不知道为什么会这样。我的 RecyclerView 可能包含 5 台设备,我很难相信通知数据集更改需要长达 20 秒。

    更详细的:

    我的代码基于Android example。在示例中,DeviceScanActivity 中有如下代码:

    @Override
            public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mLeDeviceListAdapter.addDevice(device);
                        mLeDeviceListAdapter.notifyDataSetChanged();
                    }
                });
            }
    

    删除notifyDataSetChanged() 行并在适配器内的addData 函数内添加notifyItemInserted(&lt;position of new device&gt;) 解决了该问题。

    【讨论】:

      猜你喜欢
      • 2020-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 2020-11-10
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多