7

安卓工作室 3.6

我想在我的活动中使用 ViewPager2 中的 2 个片段。

这是我的活动:

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
public class QRBluetoothSwipeActivity extends AppCompatActivity {
    private ViewPager2 myViewPager2;
    private ViewPagerFragmentAdapter myAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        // Make sure this is before calling super.onCreate
        setTheme(R.style.AppTheme); // show splash screen
        super.onCreate(savedInstanceState);
        setContentView(R.layout.qr_bluetooth_swipe_activity);
        init();
    }

    private void init() {
        myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager());
        myAdapter.addFragment(new BluetoothPageFragment());
        myAdapter.addFragment(new QrPageFragment());
        myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
        myViewPager2.setAdapter(myAdapter);
    }

}

这里 ViewPagerFragmentAdapter

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import java.util.ArrayList;

public class ViewPagerFragmentAdapter  extends FragmentStateAdapter {

    private ArrayList<Fragment> arrayList = new ArrayList<>();

    public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return arrayList.get(position);
    }

    public void addFragment(Fragment fragment) {
        arrayList.add(fragment);
    }

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

但我得到编译错误:

ViewPagerFragmentAdapter is not abstract and does not override abstract method createFragment(int) in FragmentStateAdapter

我该如何解决这个问题并在ViewPager2中使用FRAGMENTS

谢谢

4

1 回答 1

13

FragmentStateAdapterinViewPager2与 in 有点不同,ViewPager如下所示:

  • 与其实施getCount(),不如实施getItemCount()

  • 与其实施getItem(int position),不如实施createFragment(int position)

  • Lifecycle通过添加应该包含在 super 中的参数,构造函数签名是不同的

所以ViewPagerFragmentAdapter用下面的替换你的

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import java.util.ArrayList;


public class ViewPagerFragmentAdapter extends FragmentStateAdapter {

    private ArrayList<Fragment> arrayList = new ArrayList<>();

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


    public void addFragment(Fragment fragment) {
        arrayList.add(fragment);
    }

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

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        // return your fragment that corresponds to this 'position'
        return arrayList.get(position);
    }

}

还要确保导入/扩展 ViewPager2 的正确适配器

import androidx.viewpager2.adapter.FragmentStateAdapter;

2021 年更新

这回答了问题的原始问题;但是FragmentStateAdapter,一般来说,创建这种方式并不正确;因为:

  1. 要获得高性能ViewPager,它应该只保留一些实例化的屏幕外页面片段。

  2. 将所有页面片段保存在一个列表中,在浪费设备资源方面是不好的。

  3. createFragment(),顾名思义,旨在为特定页面创建一个新片段并返回它;不要从已经实例化片段的列表中返回片段。

  4. 最重要的是根据文档 createFragment():

提供与指定位置关联的新 Fragment。

适配器将负责片段生命周期:

  • Fragment 将用于显示项目。
  • Fragment 离视口太远时会被销毁,并保存其状态。当 item 再次靠近视口时,将请求一个新的 Fragment,并使用之前保存的状态对其进行初始化。

因此,我建议更改此设计以将其包括在内:

假设您的页面片段是PageFragment;那么您可以通过在 中使用static PageFragment newInstance(int position) {}方法来获得单实例模式PageFragment,然后createFragment()应该是:

@NonNull
@Override
public Fragment createFragment(int position) {
    // return a brand new fragment that corresponds to this 'position'
    return PageFragment.newInstance(position); // Create a new instance of the page fragment
}
于 2019-10-23T16:36:27.063 回答