美文网首页
PagerAdapter 数据的增删改

PagerAdapter 数据的增删改

作者: zlzxm | 来源:发表于2019-04-15 19:21 被阅读0次

一:PagerAdapter#notifyDataSetChanged调用过程

PagerAdapter#notifyDataSetChanged方法源码

注:这里会通过mViewPagerObserver.onchanged()回调通知viewpager

ViewPager#setadapter方法源码

注:前面调用adapter的回调通知 是在Viewpager#setadapter方法时通过this.mAdapter.setViewPagerObserver(this.mObserver);给adapter注册的回调

ViewPager#PagerObserver类

注:PagerObserver是Viewpager的一个内部类,所以notifyDataSetChanged的时候最终会调用ViewPager#dataSetChanged方法

ViewPager#dataSetChanged部分源码

注:ViewPager#dataSetChanged 才是 adapter数据刷新的处理,要先找到这里才能开始分析。

Viewpager静态内部类Iteminfo Viewpager#setCurrentItemInternal Viewpager#populate部分源码

二:fragmentStateAdapter 数据修改:

1.增:

    方法:viewpager#dataSetChanged:

   1. boolean needPopulate = this.mItems.size() <this.mOffscreenPageLimit *2 +1  &&this.mItems.size() < adapterCount ;(增的情况下 计算结果都是ture)

    2.newPos   = - 1(viewpager内部默认-1,用户可修改)

    3.if(newPos == -1) 什么事情都不做

    4.if(newPos == -2) 会对viewpager中的mItems进行remove然后      mAdapter.destroyItem  同时更新viewpager当前页(增的情况下,不变)。随后needPopulate =true

   5.if(needPopulate){

    this.setCurrentItemInternal(newCurrItem,false,true);

     this.requestLayout();

 }

  6.setCurrentItemInternal方法内部根据mFirstLayout判断是否执行this.populate(item);(mFirstLayout = false)

  7.populate会根据当前的页码数和用户设置的mOffscreenPageLimit和ItemInfo中的widthFactor计算需不需要去执行Viewpager#addNewItem();

  8.addNewItem 会去执行adapter.instantiateItem()方法;

结论1:if(newPos == -2) 会让viewpager清除ArrayList<ViewPager.ItemInfo> mItems 的内容。同时this.mAdapter.destroyItem(this, ii.position, ii.object);

结论2(仅仅只是增长adapter集合):notifyDataSetChanged 必定会调用populate方法,假如mItems是空的(newpos == -2),必定会去addnewitem同时this.mAdapter.instantiateItem(this, position);假如newpos == -1的情况,会根据当前页和viewpager偏移值去判定需不需要调用addnewitem。

结论3:仅仅只是增长adapter集合viewpager不会有问题;

2.改(不增加和减少adapter中数据的长度):

1. boolean needPopulate = this.mItems.size() <this.mOffscreenPageLimit *2 +1  &&this.mItems.size() < adapterCount ;(改的情况下 mOffscreenPageLimit为1的情况下  adapter长度为1和2的时候needPopulate为false ,3的时候当前页在中间的时候为false,其他为true)

    2.newPos   = - 1(viewpager内部默认-1,用户可修改)

    3.if(newPos == -1) 什么事情都不做

    4.if(newPos == -2) 会对viewpager中的mItems进行remove然后      mAdapter.destroyItem  同时更新viewpager当前页(改的情况下,不变)。随后needPopulate =true

   5.if(needPopulate){

    this.setCurrentItemInternal(newCurrItem,false,true);

     this.requestLayout();

 }

6.根据mFirstLayout判断是否执行this.populate(item);(mFirstLayout = false)

总结:所以这里有3种情况:

1.   needPopulate= false  &&  newPos == -1   -------> (表现为ui不更改)

2.  needPopulate= true  &&  newPos == -1   -------> (表现为ui不更改)

3.  needPopulate= true  &&  newPos == -2   -------> (表现为ui根据adapter提供的实例修改)

情况1:不需要调用

情况2:调用了populate,但是需要的iteminfo都存在所以不会调用addnewitem,导致如果集合中相同位置的引用改变了。使用的还是mItems缓存的旧的对象,假如mitems中的每一个对象都有remove的机会那么视图在拖动中总有机会去更新到最新的。

情况3:清空了mItems,导致每一项重新开始调用addnewitem和this.mAdapter.instantiateItem(this, position)。

2.删:

 和改一样有3种情况

1.   needPopulate= false  &&  newPos == -1   -------> ui无修改

2.  needPopulate= true  &&  newPos == -1     -------> ui展现正确的当前页

3.  needPopulate= true  &&  newPos == -2    ------->(表现为ui根据adapter提供的实例修改)

注:1.其中情况2假如是从不正确的当前页修改为正确的当前页,他还是可以拖动到后   一页应为 mItems 并没有清除之前的iteminfo所以在ontouch#case2的performdrag中rightBound 计算 还是按照之前的方法计算然后调用scrollTo 去滚动。但是ontouch#case1:this.setCurrentItemInternal(nextPage,true,true, initialVelocity)------>else if (item >=this.mAdapter.getCount()) {

item =this.mAdapter.getCount() -1;

}和 this.scrollToItem(item, smoothScroll, velocity, dispatchSelected);

  又给他设置到正确的位置了,然后ui就是 可以拖到最后一页但是就是翻不过去;

    2.和情况2类似,情况一假如翻到最后一页,然后调用notifyDataSetChanged没有反应,但是在你收触摸到屏幕,不管是什么方向的去触发performdarg 他最后都会返回到正确的最后一页。

讨论:needPopulate 值在删情况下变动:

  mOffscreenPageLimit 为1:

  adapter 的数据长度改动            当前页 (从1开始)             needPopulate值

    1-----0                                          1                                              false

    2-----1                                          1                                               false     

   2-----1                                            2                                             false    

   3-----2                                            1                                            false     

   3-----2                                            2                                           false     

   3-----2                                            3                                            false     

   4-----3                                            1                                            true     

   4-----3                                              2                                          false  

  4-----3                                               3                                         false  

  4-----3                                               4                                          true 

所以得出 也不是在删数据的时候都会去设置正确的当前页面。比如在3-2,和4-3的ui变动是不一样的,这是由needPopulate值决定的。


三:记录完了。over

相关文章

  • PagerAdapter 数据的增删改

    一:PagerAdapter#notifyDataSetChanged调用过程 注:这里会通过mViewPager...

  • 关于python的list的增查删改

    说到增查删改,想起了数据库,我们在关系型数据库当中就会对表进行增查删改。 在python当中我们也可以对list进...

  • MYSQL数据库的增删改查

    MYSQL数据库的增删改查 一.对于库的增删改查 增create database 库名称;create data...

  • SQL查询结构总结

    SQL 增删改查 对数据库有修改的操作是:增删改 增 insert into 表名 values(); 删 del...

  • 数据库的存储

    如何创建数据库 数据库的增删改查 增insert into student (name,phone) values...

  • 表内容的操作

    对表数据进行增删改查(curd) 增(insert into): auto_increment自增长 SELECT...

  • 增删改

    对于表中的操作,就是增删改查,查内容较多,这里先说增删改。 1.增(insert或者load) 即插入数据,多行插...

  • JavaScript防篡改对象

    preventExtensions:不能增,能删改seal:不能增删,能改freeze:不能增删改 对象属性增删改...

  • SQL-增删改查

    从增山改查开始,增删改查都是从数据库,数据表,数据三个维度展开。 新增 新增数据库 CREATE DATABASE...

  • MYSQL基本命令(3)

    增删改查(crud) (一)增 <1>插入完整行 <2>根据列插入数据 <3>多行插入数据 <4>讲一个表里的子列...

网友评论

      本文标题:PagerAdapter 数据的增删改

      本文链接:https://www.haomeiwen.com/subject/dckewqtx.html