ViewPager2 不能正常处理 Fragments 和点击事件

ViewPager2 not working properly with Fragments and click events

我只是想知道我是否做错了什么,因为我对这一切有点陌生。
如果您希望我添加任何其他内容,请告诉我。
如果您想查看所有代码,This 是我尝试实现 ViewPager 的 repo 分支。

上下文

所以我有 4 个类别,用 Fragments 表示,每个类别都有一个 ArrayList 个项目,每个项目都有一个 onItemClickListener 应该重现一些音频。
我正在尝试使用 ViewPager 显示 Fragments,但 问题是当我从 Fragment 滚动到另一个时,然后返回到已创建的 Fragment ,它没有注册触摸事件,没有任何反应,甚至没有错误或异常。
如果我转到新创建的 Fragment,触摸效果很好。
此外,在切换回已创建的 Fragment 之后,如果我稍微滚动到另一个 Fragment 并返回或通过 ArrayList Fragment 由于某种原因,它再次开始识别 ArrayList 项中的触摸。

没有真正帮助的类似问题

我试过的

代码片段

word_list.xml:

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/tan_background" />

activity_main.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"/>

</FrameLayout>

这是其中一个Fragments,其他三个基本一样,只是arrayList中的items发生了变化,还有一些其他的小东西:

// ...Skipped some irrelevant code...

public class NumbersFragment extends Fragment {
    private ArrayList<Word> mWords;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.word_list, container, false);

        mWords = new ArrayList<>();
        // ...Add all the items to the list...

        // Make the adapter for the word items
        WordAdapter adapter = new WordAdapter(getActivity(), mWords, R.color.category_numbers);
        // Find the root view of the list
        ListView listView = rootView.findViewById(R.id.root_list_view);
        // Add adapter to the root list view
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("NumbersFragment", "CLICKED");
                }
            }

        });

        return rootView;
    }

    @Override
    public void onPause() {
        super.onPause();

        Log.d("NumbersFragment", "Fragment paused");
    }

}

这是类别适配器,它管理片段:

public class CategoryAdapter extends FragmentStateAdapter {
    private static final int NUM_CATEGORIES = 4;

    // Required public constructor
    public CategoryAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        // Depending on which page the user is in,
        // create a fragment of the corresponding category
        switch (position) {
            case 0:
                return new NumbersFragment();
            case 1:
                return new FamilyFragment();
            case 2:
                return new ColorsFragment();
            default:
                return new PhrasesFragment();
        }
    }

    @Override
    public int getItemCount() {
        return NUM_CATEGORIES;
    }
}

这是我的 MainActivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set the content of the activity to use the activity_main.xml layout file
        setContentView(R.layout.activity_main);

        // Find the view pager that will allow the user to swipe between fragments
        ViewPager2 viewPager = findViewById(R.id.viewpager);

        // Create an adapter that knows which fragment should be shown on each page
        CategoryAdapter adapter = new CategoryAdapter(this);
        //or CategoryAdapter adapter = new CategoryAdapter(getSupportFragmentManager(), getLifecycle());

        // Set the adapter into the view pager
        viewPager.setAdapter(adapter);
    }
}

在创建 viewpager

后在 MainActivity viewPager.setOffscreenPageLimit(3); 中添加这个

因为ViewPager的默认离屏限制为1,而ViewPager2的默认离屏限制为0。

在 ViewPager2 中,当您切换标签时,上一个标签将自动刷新。

在 ViewPager 中,如果您有 3 个或更多选项卡,当您自动切换到第 3 个选项卡时,第一个选项卡将被销毁,当您转到第 1 个选项卡时,它将被重新创建。

viewPager.setOffscreenPageLimit(3); 从这一行开始,当您切换到一个标签时,将预加载前 3 个标签,并预加载接下来的 3 个标签,因此不会刷新任何内容。