凡科网站代码,网站地图表现形式,猎头公司应坚持的原则有,温岭建设阳光网站一、介绍
在如今的开发过程只#xff0c;内容变化已多单一的fragment#xff0c;变成连续的#xff0c;特别是以短视频或者直播为主的场景很多。从早起的Viewpage只能横向滑动#xff0c;到如今的viewpage2可以支持横向或者竖向滑动。由于viewpage2的adapter在设计时支持缓…一、介绍
在如今的开发过程只内容变化已多单一的fragment变成连续的特别是以短视频或者直播为主的场景很多。从早起的Viewpage只能横向滑动到如今的viewpage2可以支持横向或者竖向滑动。由于viewpage2的adapter在设计时支持缓存导致想立马生效出现问题不符合国内的业务场景。
二、viewpage2FragmentStateAdapter设计原理分析
1.Viewpager2
Viewpaer2的设计和viewpage还是有区别的最大的区别是viewpage是基础viewgroup通过scroll控制整体view的滑动在早起的时候很多都是可以通过adapter去自定义缓存但是viewpage2在androidx中新增的是通过对recycleview进行二次封装出来的一个新业务。 从源码中可以看出核心是recycleview这个控件在之前v7包中是独立出来的相对listview性能更好在缓存和使用更流畅也是支持横向或者竖向滑动。 2.FragmentStateAdapter
adpter的与Recycview.adapter还是有区别的。核心是adapter和holder。
2.1FragmentStateAdapter
继承recycView.adapter,里面对item进行了缓存mFragments是一个key和fragment绑定的关系下表就是fragment的索引。如果不经常对fragment移除那么这个缓存可以大大提高性能。但是也就是这个原因导致在设计的时候没考虑到移除立马生效等问题
2.2FragmentViewHolder
继承了RecycleView.holder,只要是在holder阶段创建一个rootview-FragmentLayout将fragment包进来。提供容器 三、删除无法立即更新分析
通过第二段了解了viewpage2FragmentStateAdapter的设计可以了解到这些设计的目的。但是我们在开发过程中的场景比较复杂有人习惯了recycleViewrecycleView.Adapter以为viewpage2的核心也是这套删除数据或者更新数据直接通过notify去处理结果发现viewpage2移除不是我们要的那个索引这是为什么呢
1.问题分析
这个问题和fragmentStateAdapter设计有关在这个adapter中mfragment的缓存是通过下表缓存的也就是我们虽然把数据移除了但是position在adapter的索引是连续的还是从0开始一直到最后一个元素就算我们通知了notifyItemRemoved(position)但是数据移除了下标也发生了变化这时候我们通知移除的变成了当前位置后一个position1和我们理想中还是有比较大的区别
这种做法和recycleView.Adapter内部不一样很多开发人员遇到确实无法处理想着从数据来处理这种方法是行不通的。 四、解决方案
目前暴露的api还是很不好处理网上的方案也是五花八门
1.重置adapter 这种做法是删除数据把viewpage2的adapter设为null再用数据重新生成一个新的这样做的弊端是影响了性能和体验
2.直接notify刷新 发现下标索引乱了数据移除失败 处理这个问题的核心是要把mfragment数组中的要对应的数据下表给移除然后重新排序。只有保持索引下表和mfragment中的fragment对应才能取到我们想要的view。 在adapter中也提供了一个remove的方法removeFragment(position:Int),但是这个方法是私有的我们只能通过反射来获取这个方法
步骤
1.先将数据中索引下的数据移除
2.在移除removeFragment最后在notifyItemRemoved刷新列表保持索引的真实性 public fun remove(position: Int) {//先移除item在父类中的adapteradapter?.apply {val cls this.javaClassval method cls.superclass.getDeclaredMethod(removeFragment, Long::class.java)method.isAccessible truemethod.invoke(this, position)}if (position viewPager!!.currentItem) {viewPager?.setCurrentItem(position, false)}mlsit.removeAt(position)notifyItemRemoved(position)}只有通过这样才能保持下标与数据所在数组的准确性。