Да, у меня была похожая производительность с viewpager и FragmentStatePagerAdapter, проблема с viewpager заключается в том, что pre создает представления по обе стороны от текущего представления, чтобы ускорить пролистывание до следующего представления.
Это хорошо работает для статическогопредставления, но для представлений с динамическими данными, предварительно созданное представление, как правило, устарело и должно было быть восстановлено, когда пользователь проводил по нему.
Таким образом, ему приходилось вызывать onCreateView
для 3 представлений, пока пользовательпролистывал между видами, что иногда приводило к отставанию.
Я думал о 2 улучшениях производительности, хотя использовал только одно.
1) Держатель вида / модель, например https://www.androidcode.ninja/android-viewholder-pattern-example/ и https://developer.android.com/topic/libraries/architecture/viewmodel, где инфляция и нахождение предметов повторно использовались / отделены от onCreateView
действий.
Я не использовал этот метод
2) Создайте голые представления для динамических(Первое представление было статичным, а затем в позициях 1 и 2 было 2 динамических представления, которые содержали списки различных аспектов динамических данных.)
Списки просмотра были раздуты, и в onCreateView
этих представлений для адаптера был установлен пустой список, поэтому они быстро создавались.
Затем я добавил OnPageChangeListener
, который уведомил adapter
поддержка ViewPager
, что страницы изменились
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if (position == 1 || position == 2)
{
mSectionsPagerAdapter.notifyDataSetChanged();
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Code goes here
}
@Override
public void onPageScrollStateChanged(int state) {
// Code goes here
}
});
notifyDataSetChanged
заставляет viewPager вызывать getItemPosition
в классе FragmentStatePagerAdapter
, если изменилась позиция страницы, и если нужновоссоздать его в новой позиции.
Затем в FragmentStatePagerAdapter
расширенном классе я переопределил getItemPosition
с помощью
@Override
public int getItemPosition(Object object) {
if (object instanceof LogFragment) {
LogFragment f = (LogFragment) object;
if (f != null) {
f.update();
}
} else if (object instanceof SummaryFragment){
SummaryFragment f = (SummaryFragment) object;
if (f != null) {
f.update();
}
} else {
return POSITION_UNCHANGED;
}
return super.getItemPosition(object);
}
Это позволило мне получить объект Fragment и затем вызватьметод update
для него, но по-прежнему возвращает POSITION_UNCHANGED
, поэтому просмотрщик не пытался воссоздать фрагменты.
Затем в методе update
фрагмента я получаю адаптер списка и обновляюdata.
public void update(){
adapter.clear();
adapter.addAll(datasource.getData());
}
Таким образом, более дорогостоящие получение и отображение динамических данных выполняются только тогда, когда страница действительно отображается, а НЕ когда она предварительно создается viewPager (потому что это предварительно созданное представление будет старымустарел dв любом случае и потребуется обновление)
У этого подхода есть один недостаток: экран, отображаемый во время , до сих пор остаются старые данные (либо пустые, либо данные, полученные с этой страницы). последнее обновление), это было приемлемо для меня.