Android SwipeRefreshLayout在嵌套的RecyclerView中阻止项的onClickCallback
我有一个SwipeRefreshLayout和一个嵌套的RecyclerView。recycler视图中的每个项目本质上都是一个连接了onClickHandler的CardView。我有一个问题,如果回收器视图滚动到最顶端,我的clickHandler不会被调用。如果我向下滚动一个像素,我可以点击一些东西 在添加关于触摸事件和点击事件的打印输出语句后,滑动刷新布局似乎也会截获触摸事件和Android SwipeRefreshLayout在嵌套的RecyclerView中阻止项的onClickCallback,android,android-recyclerview,onclick,swiperefreshlayout,Android,Android Recyclerview,Onclick,Swiperefreshlayout,我有一个SwipeRefreshLayout和一个嵌套的RecyclerView。recycler视图中的每个项目本质上都是一个连接了onClickHandler的CardView。我有一个问题,如果回收器视图滚动到最顶端,我的clickHandler不会被调用。如果我向下滚动一个像素,我可以点击一些东西 在添加关于触摸事件和点击事件的打印输出语句后,滑动刷新布局似乎也会截获触摸事件和setTargetOffsetTopAndBottom。这将调用requestLayout,最终似乎会导致ACT
setTargetOffsetTopAndBottom
。这将调用requestLayout
,最终似乎会导致ACTION\u CANCEL
事件。如果向下滚动recycler view 1pxcanChildScrollUp()
将返回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;
...
我的编译目标是Android API lvl 29。我也遇到过同样的问题。我确实有一个
ConstraintLayout
包装了SwipeRefreshLayout
。当我删除ConstraintLayout
(将其替换为LinearLayout
)时,问题得到了解决。希望有帮助。我不知道它为什么起作用 使用LinearLayout设置父布局解决了这个问题。对我来说,这很有效!我可以使用LinearLayout更改约束。我尝试嵌套布局:-ConstraintLayout>LinearLayout>SwiperFreshLayout不起作用。我尝试在元素上添加边距/填充:-在布局上添加填充效果很好!保证金不起作用。它必须是顶部或底部;开始/结束/左/右不工作。它可以是1px、0.1px甚至更小,直到达到特定程度。这很奇怪。看起来像只虫子。
<?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>
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)
}
...