首页 > 其他分享 >Android Viewpager2 remove fragmen不生效解决方案

Android Viewpager2 remove fragmen不生效解决方案

时间:2024-07-14 15:30:29浏览次数:21  
标签:缓存 fragment viewpage2 adapter remove 移除 Viewpager2 position Android

一、介绍

在如今的开发过程只,内容变化已多单一的fragment,变成连续的,特别是以短视频或者直播为主的场景很多。从早起的Viewpage只能横向滑动,到如今的viewpage2可以支持横向或者竖向滑动。由于viewpage2的adapter在设计时支持缓存,导致想立马生效出现问题,不符合国内的业务场景。

二、viewpage2+FragmentStateAdapter设计原理分析

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包进来。提供容器

三、删除无法立即更新分析

通过第二段,了解了viewpage2+FragmentStateAdapter的设计,可以了解到这些设计的目的。但是我们在开发过程中的场景比较复杂,有人习惯了recycleView+recycleView.Adapter,以为viewpage2的核心也是这套,删除数据或者更新数据直接通过notify去处理,结果发现viewpage2移除不是我们要的那个索引,这是为什么呢?

1.问题分析:

这个问题和fragmentStateAdapter设计有关,在这个adapter中,mfragment的缓存是通过下表缓存的,也就是我们虽然把数据移除了,但是position在adapter的索引是连续的,还是从0开始,一直到最后一个元素,就算我们通知了notifyItemRemoved(position),但是数据移除了,下标也发生了变化,这时候我们通知移除的变成了当前位置后一个:position+1,和我们理想中还是有比较大的区别

这种做法和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在父类中的adapter
            adapter?.apply {
                val cls = this.javaClass
                val method = cls.superclass.getDeclaredMethod("removeFragment", Long::class.java)
                method.isAccessible = true
                method.invoke(this, position)
            }
            if (position == viewPager!!.currentItem) {
                viewPager?.setCurrentItem(position, false)
            }

            mlsit.removeAt(position)
            notifyItemRemoved(position)
        }

只有通过这样,才能保持下标与数据所在数组的准确性。

标签:缓存,fragment,viewpage2,adapter,remove,移除,Viewpager2,position,Android
From: https://blog.csdn.net/qq36246172/article/details/140415343

相关文章

  • Android 14.0 Camera2 静音时拍照去掉快门声音
    1.概述在14.0系统rom定制化开发时,在Camera2静音情况下有快门拍照声音,这就不符合使用规范了静音的情况下拍照也不应该发出声音,所以在静音拍照流程中要求去掉快门声音,接下来具体实现相关的功能2.Camera2静音拍照去掉快门声音核心代码/packages/apps/Camera2/src/co......
  • 【Android面试八股文】谈谈OkHttp框架的原理(深度剖析源码)
    文章目录一、OkHttp介绍二、OkHttp使用流程三、OkHttp的分发器Dispatcher3.1Dispatcher3.2同步请求3.3异步请求四、OKHttp的请求流程五、分发器线程池六、拦截器责任链6.1责任链模式6.1.1故事背景6.1.2责任链模式实现6.2OkHttp的拦截器流程......
  • 【Android面试八股文】谈谈你对Glide框架的缓存机制设计的理解
    文章目录一、引入缓存的目的二、Glide缓存流程2.1Glide缓存的读取顺序2.2Glide加载资源流程2.3Glide的缓存分层结构三、内存缓存原理四、存取原理4.1取数据4.2存数据4.3为什么要引入软引用?五、磁盘缓存原理(DiskLruCache)5.1磁盘缓存概述5.......
  • Android 四大组件 Activity、Service、Broadcast、Content Provider
    一、Android四大组件Activity、Service、Broadcast、ContentProvider1、Activity:1.1、打开App内部Activity:Intentintent=newIntent(SourceActivity.this,TargetActivity.class);startActivity(intent); 1.2、打开Activity并获取返回结果(类似模式对话框): 主Activit......
  • Android C++系列:Linux常用函数和工具
    1.时间函数1.1文件访问时间#include<sys/types.h>#include<utime.h>intutime(constchar*name,conststructutimebuf*t);返回:若成功则为0,若出错则为-1如果times是一个空指针,则存取时间和修改时间两者都设置为当前时间;如果times是非空指针,则存取时......
  • Android C++系列:Linux进程间关系
    1.终端在UNIX系统中,用户通过终端登录系统后得到一个Shell进程,这个终端成为Shell进程的控制终端(ControllingTerminal),在前面文章我们说过,控制终端是保存在PCB中的信息,而我们知道fork会复制PCB中的信息,因此由Shell进程启动的其它进程的控制终端也是这个终端。默认情况......
  • Android初学者书籍推荐
    书单1.《Android应用开发项目式教程》,机械工业出版社,2024年出版2.《第一行代码Android》第二版3.《第一行代码Android》第三版4.《疯狂Android讲义》第四版5.《Android移动应用基础教程(AndroidStudio第2版)》从学安卓到用安卓再到教安卓,我翻阅了不下二十本书,培养了多......
  • python获取Android App性能数据(CPU、GPU、内存、电池、耗电量)
    原文链接:https://blog.csdn.net/u012089395/article/details/1266689461、原理python脚本通过os.popen()方法运行adb命令,获取性能数据,将性能数据保存在csv文件并算出均值、最大值、最小值。本脚本可测试一个app包含多个进程的场景,可以获取每个进程的性能数据。2、环境准备:2.1软......
  • 数据恢复篇:适用于 Android 的恢复工具
    正在摆弄Android设备。突然,您意外删除了一张或多张图片。不用担心,您总能找到一款价格实惠的照片恢复应用。这款先进的软件可帮助Android用户从硬盘、安全数字(SD)或存储卡以及数码相机中恢复已删除的图片。Android上文件被删除的主要原因在获得这些文件恢复应用程序......
  • Cellebrite UFED 4PC 7.69 (Windows) - Android 和 iOS 移动设备取证软件
    CellebriteUFED4PC7.69(Windows)-Android和iOS移动设备取证软件TheIndustryStandardforLawfullyAccessingandCollectingDigitalData请访问原文链接:https://sysin.org/blog/cellebrite-ufed/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgCellebri......