#android #android-viewpager2 #fragmentstateadapter
#Android #android-viewpager2 #fragmentstateadapter
Вопрос:
Я использую a ViewPager2
вместе с a FragmentStateAdapter
.
public class MyAdapter extends FragmentStateAdapter {
public MyAdapter(@NonNull Fragment fragment) {
super(fragment);
}
@NonNull
@Override
public Fragment createFragment(int position) {
return MyFragment.newInstance(MyClass.func(position));
}
@Override
public int getItemCount() {
return MyClass.NUM;
}
}
К сожалению, вызов notifyDataSetChanged()
адаптера вообще не имеет никакого эффекта. (Вызов notifyItemChanged(position)
работает нормально.)
Как я могу это решить?
Ответ №1:
Я создал отчет об ошибке для этого здесь, в IssueTracker. Для меня, однако, даже методы notifyItemChanged(position:)
and notifyItemRangeChanged(positionStart:itemCount:)
ведут себя некорректно.
Ошибка связана с реализацией FragmentStateAdapter.getItemId(position:)
метода по умолчанию, который просто возвращает position
переданное в него. Поэтому itemId
для каждого position
будет одинаковым до и после FragmentStateAdapter.notifyDataSetChanged()
вызова, и поэтому ни один из Fragment
них никогда не будет воссоздан.
Одним из возможных обходных путей является присвоение каждой странице уникального идентификатора в вашей FragmentStateAdapter
реализации и присвоение нового идентификатора каждой странице при notifyDataSetChanged()
каждом вызове метода. Смотрите init
Блок в ViewPagerAdapter
классе ниже, который облегчает этот обходной путь: AdapterDataObserver
объект зарегистрирован в этом init
блоке таким образом, что он получает обратный вызов при каждом notifyDataSetChanged()
вызове.
class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
private var counter = 0L
private var itemIds: List<Long>
init {
itemIds = generateListOfItemIds()
val adapterDataObserver = object : AdapterDataObserver() {
override fun onChanged() {
itemIds = generateListOfItemIds()
}
}
registerAdapterDataObserver(adapterDataObserver)
}
override fun createFragment(position: Int): Fragment {
return PageFragment.newInstance(position)
}
override fun getItemCount(): Int {
return itemIds.size
}
override fun getItemId(position: Int): Long {
return itemIds[position]
}
override fun containsItem(itemId: Long): Boolean {
return itemIds.contains(itemId)
}
private fun generateListOfItemIds() = (1..5).map { counter }
}
Комментарии:
1. Смотрите Здесь минимальное приложение для Android, которое демонстрирует этот
ViewPagerAdapter
класс.
Ответ №2:
Перед установкой adapter() на ваш viewpager. Сделать viewPager.setSaveFromParentEnabled(false);