具有自定义视图的Viewpager优化



场景-我正在开发一个应用程序,该应用程序在viewpager中显示特定日期的事件,其中每个页面代表一天(即24小时垂直方式,类似于谷歌日历(。每个页面/片段都包含一个垂直滚动视图(其中有一个框架布局(,基于事件列表,我正在动态创建自定义视图(视图位置和维度基于相应的事件时间和持续时间(,并将其添加到滚动视图中用户可以在日期之间拖放事件

问题-我已经成功完成了视图创建部分,现在问题是性能。有时,vewpager(使用FragmentStatePagerAdapter(在浏览页面时会滞后。

有人请建议我如何减少延迟或任何更好的方法来实现这个

是的,我在viewpager和FragmentStatePagerAdapter上有类似的性能,viewpager的问题是在当前视图的两侧预先创建视图,以加快滑动到下一个视图的速度。

这适用于静态视图,但对于具有动态数据的视图,预先创建的视图通常已经过时,需要在用户滑动到它时重新生成

因此,它不得不在3个视图上调用onCreateView,而用户在视图之间滑动有时会导致滞后。

我想到了两个性能改进,尽管只使用了一个。

1( 视图支架/模型模式,例如。https://www.androidcode.ninja/android-viewholder-pattern-example/和https://developer.android.com/topic/libraries/architecture/viewmodel其中充气和查找项目与CCD_ 2活动重复使用/分离。

我没有使用这种方法

2( 为动态视图创建基本视图(第一个视图是静态的,然后在位置1和2有两个动态视图,其中包含动态数据不同方面的列表视图。(

列表视图被夸大了,并且在这些视图的onCreateView中有一个适配器设置为空列表,因此创建起来很快。

然后我在OnPageChangeListener上添加了一个,它通知支持ViewPageradapter页面已更改

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调用FragmentStatePagerAdapter类中的getItemPosition,以确定页面位置是否已更改,以及是否需要在新位置重新创建页面。

然后在FragmentStatePagerAdapter中,扩展类I用覆盖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,因此视图寻呼机不会尝试重新创建Fragments。

然后在Fragment的update方法中,我获取listview适配器并更新数据。

public void update(){
adapter.clear();
adapter.addAll(datasource.getData());
}

因此,获取和显示动态数据的成本更高,只有在页面实际显示时才能完成,而不是在viewPager预先创建时(因为预先创建的视图无论如何都是过时的数据,需要更新(

这种方法有一个缺点,在滑动期间显示的屏幕仍然是旧数据(要么是空的,要么是上次更新页面时的数据(,这对我来说是可以接受的。

最新更新