为什么 FragmentStateAdapter 在 ViewPager2 中不起作用?
Why FragmentStateAdapter not work in ViewPager2?
Android Studio 3.6
我想在我的 activity 中使用 ViewPager2 中的 2 个片段。
这是我的 activity:
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?
谢谢
FragmentStateAdapter
在 ViewPager2
中与在 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);
}
}
还要确保 import/extend ViewPager2 的正确适配器
import androidx.viewpager2.adapter.FragmentStateAdapter;
2021 年更新
回答了原问题;但是,一般来说,以这种方式创建 FragmentStateAdapter
并不是那么正确;因为:
要获得高性能 ViewPager
,它应该只保留一些实例化的屏幕外页面片段。
将所有页面碎片保存在一个列表中在浪费设备资源方面并不好。
createFragment()
,顾名思义,意在为特定页面创建一个新的片段,并return它;不要 return 来自已经实例化片段的列表中的片段。
-
Provide a new Fragment associated with the specified position.
The adapter will be responsible for the Fragment lifecycle:
- The Fragment will be used to display an item.
- The Fragment will be destroyed when it gets too far from the
viewport, and its state will be saved. When the item is close to the
viewport again, a new Fragment will be requested, and a previously
saved state will be used to initialize it.
因此,我建议更改此设计以将其纳入考虑范围:
假设您的页面片段是PageFragment
;然后你可以通过在 PageFragment
中使用 static PageFragment newInstance(int position) {}
方法来获得单实例模式,然后 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
}
Android Studio 3.6
我想在我的 activity 中使用 ViewPager2 中的 2 个片段。
这是我的 activity:
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?
谢谢
FragmentStateAdapter
在 ViewPager2
中与在 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);
}
}
还要确保 import/extend ViewPager2 的正确适配器
import androidx.viewpager2.adapter.FragmentStateAdapter;
2021 年更新
回答了原问题;但是,一般来说,以这种方式创建 FragmentStateAdapter
并不是那么正确;因为:
要获得高性能
ViewPager
,它应该只保留一些实例化的屏幕外页面片段。将所有页面碎片保存在一个列表中在浪费设备资源方面并不好。
createFragment()
,顾名思义,意在为特定页面创建一个新的片段,并return它;不要 return 来自已经实例化片段的列表中的片段。
Provide a new Fragment associated with the specified position.
The adapter will be responsible for the Fragment lifecycle:
- The Fragment will be used to display an item.
- The Fragment will be destroyed when it gets too far from the viewport, and its state will be saved. When the item is close to the viewport again, a new Fragment will be requested, and a previously saved state will be used to initialize it.
因此,我建议更改此设计以将其纳入考虑范围:
假设您的页面片段是PageFragment
;然后你可以通过在 PageFragment
中使用 static PageFragment newInstance(int position) {}
方法来获得单实例模式,然后 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
}