ViewPager2 不能与 Fragments 和点击事件一起正常工作

Una*_*Luz 6 java android android-fragments onitemclicklistener android-viewpager2

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

语境

所以我有 4 个类别,用 表示Fragments,每个类别都包含一个ArrayList项目,每个项目都有一个onItemClickListener应该重现一些音频。
我试图Fragments用 ViewPager显示 ,但问题是当我从一个滚动Fragment到另一个时,然后回到已经创建的Fragment,它没有注册触摸事件,没有任何反应,甚至没有错误或异常。
如果我去一个新创建Fragment的触摸工作就好了。
此外,切换回已创建后Fragment ,如果我连滚动只是一点点到另一个Fragment和复出或通过ArrayList的是Fragment由于某种原因,它开始认识到在触摸ArrayList再次物品。

没有真正帮助的类似问题

我试过的

  • 我尝试使用coordinatorlayout包装ViewPager2但没有区别
  • 我一直在阅读一些用 Kotlin 编写的官方 viewPager2 示例,但它们似乎都没有类似的情况(我也很难阅读 Kotlin 代码)

代码片段

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" />
Run Code Online (Sandbox Code Playgroud)

活动_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>
Run Code Online (Sandbox Code Playgroud)

这是其中一个Fragment,其他三个基本相同,只是arrayList中的item发生了变化,还有一些其他的小东西:

// ...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");
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的主要活动:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

sai*_*mar 7

viewPager.setOffscreenPageLimit(3);创建 viewpager 后,将此添加到您的 MainActivity 中

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

在 ViewPager2 中,当您切换选项卡时,前一个选项卡将自动刷新。

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

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