RecyclerView和SwipeRefreshLayout一起使用时,点击事件无法正常工作?

3
在使用FragmentStateAdapter之前,我使用的是FragmentPagerAdapter,一切都很好,但当我从FragmentPagerAdapter迁移到FragmentStateAdapter以减少内存使用时,我遇到的问题是:RecyclerView在顶部位置时,单击列表中的任何项都无法工作。如果我将RecyclerView向下滚动一点,则onClick就可以正常工作。这个问题在使用SwipeRefreshLayout时并没有发生。当我从RecyclerView的父级中移除SwipeRefreshLayout时,它就可以正常工作了。我该如何在SwipeRefreshLayout中使用它?
我正在像这样在父片段中使用子片段enter image description here 这是父片段的代码。
public class DailyFragment extends Fragment {
    private FragmentDailyBinding binding;
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        binding = FragmentDailyBinding.inflate(inflater, container, false);
        MyChildFragmentAdapter childFragmentAdapter = new MyChildFragmentAdapter(this.getChildFragmentManager(), this.getLifecycle()); // I'm showing these fragment in Parent fragment. So that I'm using getChildFragmentManager() 
        childFragmentAdapter.addFragment(new FirstFragment(),"first");
        childFragmentAdapter.addFragment(new SecondFragment(),"second");
        childFragmentAdapter.addFragment(new ThirdFragment(),"third");
        childFragmentAdapter.addFragment(new FourthFragment(),"fourth");
        childFragmentAdapter.addFragment(new FifthFragment(),"fifth");
        binding.dailyViewPager.setAdapter(childFragmentAdapter);
        new TabLayoutMediator(binding.dailyTabLayout, binding.dailyViewPager, (tab, position) -> tab.setText(childFragmentAdapter.fragmentsArrayListTitle.get(position))).attach();
        binding.dailyViewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
        return binding.getRoot();
    }


    // FragmentStateAdapter
    public static class MyChildFragmentAdapter extends FragmentStateAdapter {
        private final ArrayList<Fragment> fragmentsArrayList = new ArrayList<>();
        private final ArrayList<String> fragmentsArrayListTitle = new ArrayList<>();

        public MyChildFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
            super(fragmentManager, lifecycle);
        }



        public void addFragment(Fragment fragment, String title) {
            fragmentsArrayList.add(fragment);
            fragmentsArrayListTitle.add(title);
        }

        @NonNull
        @Override
        public Fragment createFragment(int position) {
            return fragmentsArrayList.get(position);
        }

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

    }
}

这是关于FirstFragment()的XML。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".ChieldFragment.dailyChield.MahadevFragment">
    
<androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/mahadevSwipe"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/mahadevRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

我的问题类似于这个问题:

ViewPager2与SwipeRefreshLayout冲突

我查看了这些答案,但没有解决我的问题。


不确定,但如果你正在使用VP2,你能否禁用ViewPager2 RecyclerView的嵌套滚动呢?在这里描述 - Zain
@Zain 是的,我正在使用ViewPager2。我认为这个问题是由于ViewPager2的嵌套滚动引起的。因为当我的图像正在加载时,我的设备也会卡顿。 - M DEV
太好了.. 你试过禁用它吗? - Zain
@Zain 抱歉,问题还没有解决。我的ViewPager2显示正确,但无法点击图像的顶部位置。当我将RecyclerView向下滚动一点时,onClick就可以正常工作了。 - M DEV
2个回答

4

我不久前也遇到了同样的问题。我通过将NestedScrollView作为SwipeRefreshLayout的子节点,并将你的RecyclerView布局作为NestedScrollView的子节点来解决了这个问题。请参考下面的示例:

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/mahadevSwipe"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        // I didn't put mandatory constraints, but you'll have to
        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/mahadevRecyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

        </androidx.core.widget.NestedScrollView>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

或者,你也可以保持代码不变,并使用滚动监听器添加自定义滚动行为。如果我的第一个猜测不起作用,请告诉我,我会给你提供自定义滚动处理的示例。


谢谢你的回答。我查看了NestedScrollView,但它会消耗3倍的内存并且还会导致设备卡顿。我认为这不是解决这个问题的合适方法。 - M DEV
在某些情况下,您的NestedScrollView有助于解决此问题。如果您将第二种方法添加到您的问题中,则会更好。如果其他开发人员遇到其他问题,则可以尝试您的第二种方法,如果第一种方法不起作用。 - M DEV
@MDev 我的目标是提供最少更改的解决方案。在我看来,最好的解决方案是摆脱下拉刷新布局并实现自定义行为到recylcerView中,从而使其成为自定义swipeToRefresh,而无需嵌套行为冲突的布局。 - jacouille
是的,如果我使用ProgressBar来刷新我的布局也是不错的选择。无论如何,NestedScrollView在特定条件下解决了我的问题。非常感谢您的回答。 - M DEV
哦,没想到那个,聪明的变通方法!没问题,谢谢你的奖励;) - jacouille
1
这个错误也在Android问题跟踪器中被提出过。通过更改其父布局来解决。如果有人遇到这种类型的错误,请尝试将SwipeRefreshLayout的父布局更改为FrameLayoutLinearLayout。或者尝试这个答案或者也可以尝试这个链接 https://dev59.com/y7roa4cB1Zd3GeqPgkPp#61115487 - M DEV

0
尝试在协调布局下的所有视图中添加app:layout_behavior="@string/appbar_scrolling_view_behavior"

@jaunje 谢谢你的回答。但这个方法并没有解决我的问题。NestedScrollView可以工作,但如果你有其他方法可以不用NestedScrollView解决这个问题,那就更好了。否则,使用NestedScrollView也可以(但是嵌套时可能会出现一些问题)。 - M DEV

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接