转载 http://www.67tgb.com/?p=624

最近项目结束,搞了一次代码分享。其中一位同学分享了一下自己在解决问题过程中的一些心得体会,感觉受益匪浅。整理出来,分享给大家。

建议使用自己编译的android os和虚拟机,这样就可以调试android系统中的任何组件。简单说来,深入android源码,去寻找解决问题的答案。这事儿说起来简单,实际做起来还是有些难度的。我也曾经尝试着去看过,没看一会儿就晕了。

所以还是有针对性的去看源码,效率会高一些。

废话不多说,先看第一个示例。

Viewpager在调用notifyDataSetChanged()时,界面无刷新。

相信很多做过Viewpager的同学肯定遇到过这个问题,这个是bug还是android就是如此设计的,我们不做讨论。总之,它确实影响我们功能的实现了。

可能不少同学选择为Viewpager重新设置一遍适配器adapter,达到刷新的目的。但是这种方法在大多数情况下,是有问题的。

追踪源代码:

为什么调用数据更新的方法,Viewpager却没有更新呢,我们跟进该方法的源代码看一下。

首先查看适配器调用的super.notifyDataSetChanged(),该方法调到抽象基类PagerAdapter.notifyDataSetChanged()中:

/**

* This method should be called by the application if the data backing this adapter has changed

* and associated views should update.

*/

public void notifyDataSetChanged() {

mObservable.notifyChanged();

}

注释里说到,当附加在适配器上的数据发生变化时,应该调用该方法刷新数据。该方法调用了一个mObservable .notifyChanged();

我们继续跟进这个方法,进入DataSetObservable类中,发现这样一段代码:

/**

* Invokes {@link DataSetObserver#onChanged} on each observer.

* Called when the contents of the data set have changed. The recipient

* will obtain the new contents the next time it queries the data set.

*/

public void notifyChanged() {

synchronized(mObservers ) {

// since onChanged() is implemented by the app, it could do anything, including

// removing itself from {@link mObservers} - and that could cause problems if

// an iterator is used on the ArrayList {@link mObservers}.

// to avoid such problems, just march thru the list in the reverse order.

for (int i = mObservers .size() - 1; i >= 0; i--) {

mObservers.get(i).onChanged();

}

}

}

这都不是重点,重点我们来看这个mObservers的类型是一个抽象类DataSetObserver,里面只有两个未实现的方法,都有谁使用了这个抽象类呢,快捷键 ctrl + alt + H ,在众多的调用者当中,我们发现了Viewpager的身影

进入viewpager,我们终于找到了viewpager中控制数据变更的重点方法dataSetChanged ,这个方法如下:

void dataSetChanged () {

// This method only gets called if our observer is attached, so mAdapter is non-null.

boolean needPopulate = mItems .size() < mOffscreenPageLimit * 2 + 1 &&

mItems.size() < mAdapter.getCount();

int newCurrItem = mCurItem ;

boolean isUpdating = false;

for (int i = 0; i < mItems.size(); i++) {

final ItemInfo ii = mItems .get(i);

final int newPos = mAdapter.getItemPosition(ii.object );

if (newPos == PagerAdapter.POSITION_UNCHANGED ) {

continue;

}

if (newPos == PagerAdapter.POSITION_NONE) {

mItems.remove(i);

i--;

if (!isUpdating) {

mAdapter.startUpdate( this);

isUpdating = true;

}

mAdapter.destroyItem( this, ii.position , ii.object);

needPopulate = true;

if (mCurItem == ii.position ) {

// Keep the current item in the valid range

newCurrItem = Math. max(0, Math.min(mCurItem, mAdapter.getCount() - 1));

needPopulate = true;

}

continue;

}

if (ii.position != newPos) {

if (ii.position == mCurItem ) {

// Our current item changed position. Follow it.

newCurrItem = newPos;

}

ii. position = newPos;

needPopulate = true;

}

}

if (isUpdating) {

mAdapter.finishUpdate( this);

}

Collections. sort(mItems, COMPARATOR);

if (needPopulate) {

// Reset our known page widths; populate will recompute them.

final int childCount = getChildCount();

for (int i = 0; i < childCount; i++) {

final View child = getChildAt(i);

final LayoutParams lp = (LayoutParams) child.getLayoutParams();

if (!lp.isDecor ) {

lp. widthFactor = 0.f;

}

}

setCurrentItemInternal(newCurrItem, false, true);

requestLayout();

}

}

重点看这样一行代码:

final int newPos = mAdapter.getItemPosition(ii.object );

if (newPos == PagerAdapter.POSITION_UNCHANGED ) {

continue ;

}

官方对getItemPosition()的解释是:

Called when the host view is attempting to determine if an item’s position has changed. Returns POSITION_UNCHANGED if the position of the given item has not changed orPOSITION_NONE if the item is no longer present in the adapter.

The default implementation assumes that items will never change position and always returns POSITION_UNCHANGED.

意思是如果item的位置如果没有发生变化,则返回POSITION_UNCHANGED。如果返回了POSITION_NONE,表示该位置的item已经不存在了。默认的实现是假设item的位置永远不会发生变化,而返回POSITION_UNCHANGED

解决方案:

所以我们可以尝试着修改适配器的写法,覆盖getItemPosition()方法,当调用notifyDataSetChanged时,让getItemPosition方法人为的返回POSITION_NONE,从而达到强迫viewpager重绘所有item的目的。

具体代码如下:

class SearchAdapter extends PagerAdapter {

private int mChildCount = 0;

@Override

public void notifyDataSetChanged() {

mChildCount = getCount();

super.notifyDataSetChanged();

}

@Override

public int getItemPosition(Object object) {

if ( mChildCount > 0) {

mChildCount --;

return POSITION_NONE;

}

return super.getItemPosition(object);

}

}

Android -- 处理ViewPager的notifyDataSetChanged无刷新

Viewpager在调用notifyDataSetChanged()时,界面无刷新 Viewpager在调用notifyDataSetChanged()时,界面无刷新,它确实影响我们功能的实现了.可能 ...

&num;&num;解决 ViewPager 调用 notifyDataSetChanged&lpar;&rpar;无刷新:原理、解决办法&num;&num;

一.原理 转自:http://www.cnblogs.com/maoyu417/p/3740209.html 转载 http://www.67tgb.com/?p=624 最近项目结束,搞了一次代码分 ...

ListView动态刷新adapter&period;notifyDataSetChanged&lpar;&rpar;无反应

前段时间在做一个动态刷新ListView(模拟聊天),遇到一个问题,调用notifyDataSetChanged()方法,数据源已经存在但是并没有动态刷新! 首先我们需要了解notifyDataSet ...

Xamarin&period; Android实现下拉刷新功能

PS:发现文章被其他网站或者博客抓取后发表为原创了,给图片加了个水印 下拉刷新功能在安卓和iOS中非常常见,一般实现这样的功能都是直接使用第三方的库,网上能找到很多这样的开源库.然而在Xamarin. ...

Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法

http://www.cnblogs.com/SkyD/archive/2010/11/08/1871423.html Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法 Surfa ...

【JS】ajax 实现无刷新文件上传

一.摘要 最近在做个东西,需要实现页面无刷新文件上传,目前看到的方法有两种 1) 通过隐藏iframe 实现页面无刷新,适用于不关心上传结果

使用bootstrap时遇到的问题及解决办法

1.用到 Glyphicons图标组件时,要注意文件的存放位置,最好在站点下将下好的bootstrap文件夹复制过来,里面的fonts文件夹不要动,使用的时候直接引用bootstrap.css和boo ...

linux 命令 — download

wget 下载工具 一般 wget url 下载url指定的资源,日志输出到stdout,文件名称和url中指定的资源名称一致 wget url -o log -O file -o:指定日志输出到的文 ...

Python应用场景 (转)

Web应用开发 Python经常被用于Web开发.比如,通过mod_wsgi模块,Apache可以运行用Python编写的Web程序.Python定义了WSGI标准应用接口来协调Http服务器与基于P ...

Dockerfile 构建前端node应用cnpm命令启动nodejs服务

cat Dockerfile.node FROM centos MAINTAINER zha*****ch.cn ENV LANG en_US.UTF-8 RUN /bin/cp /usr/share ...

基于Axis1&period;4的webservice接口开发(接口调用)

基于Axis1.4的webservice接口开发(接口调用) 一.webservice接口代码参考上一篇博客: http://www.cnblogs.com/zhukunqiang/p/7125668 ...

android 无刷新 好友,Android viewPage notifyDataSetChanged无刷新相关推荐

  1. Android -- 处理ViewPager的notifyDataSetChanged无刷新

    Viewpager在调用notifyDataSetChanged()时,界面无刷新 Viewpager在调用notifyDataSetChanged()时,界面无刷新,它确实影响我们功能的实现了.可能 ...

  2. android 天气 没有广告,收集几款无广告的纯净天气App

    本文最后更新于2020-12-29 11:16:11,某些文章具有时效性,若有错误或已失效,请在下方留言或联系老夜. 多年前获取天气预报信息还得每天晚上七点半守着央视电视台,等新闻联播结束伴随着< ...

  3. Windows PC、 Linux、 Android、 iOS多平台支持H5无插件播放RTSP摄像机解决方案

    Windows PC. Linux. Android. iOS多平台支持H5无插件播放RTSP摄像机解决方案 需求分析 视频流媒体监控行业已经进入互联网时代,浏览器承载了绝大多数的互联网访问流量,目前 ...

  4. [Android]美国VOA英语学习软件,无广告

    下载地址: [北方网通]    [电信网通] [下载说明] 1 点击上面的地址,打开下载页面 2 点击"普通下载"--等待30秒--点击"下载"按钮--保存 本 ...

  5. android拍照功能无预览,Android快速实现无预览拍照功能

    本文实例为大家分享了Android实现无预览拍照功能的具体代码,供大家参考,具体内容如下 实现思路: 把预览的SurfaceView的宽高设置为肉眼看不出的值,例如0.1dp,其他的就是自定义相机的标 ...

  6. 无线轮播android,Android无限轮播Banner的实现

    概述 应用首页的广告轮播Banner,一般都会使用ViewPager来实现,但是ViewPager 没有轮播效果. 现成有这么几种实现方案: 1.使用Integer.MAX_VALUE ,理论上很难达 ...

  7. Android实现有声计算器代码,android studio实现简单的计算器(无bug)

    本文实例为大家分享了android studio实现简单计算器的具体代码,供大家参考,具体内容如下 1.效果图 2布局代码 3.逻辑代码 package com.example.myzhuoye; i ...

  8. android shape 无边框颜色,Android 使用shape定义不同控件的的颜色、背景色、边框色...

    Android 使用shape定义不同控件的的颜色.背景色.边框色 设置按钮的右边框和底边框颜色为红色,边框大小为3dp: 在drawable新建一个 buttonstyle.xml的文件,内容如下: ...

  9. android继电器指令,手机 蓝牙 控制 继电器 无线门锁 物联网 安卓源码 安卓开发 Android WIFI控制 详细注释测试稳定无bug...

    一.功能: 1.Android  WIFI连接与断开,保存连接IP及端口. 2.WIFI控制3个继电器 3.16进制发送指令,可以单条和多条发送,用逗号隔开. 4.16进制接收 如需特别功能可以找我定 ...

最新文章

  1. 使用dstat命令的插件查看mysql的io状态
  2. 创建一个storageevent事件_事件循环:微任务和宏任务
  3. 菜鸟成长日记(四)之WMIC简单命令应用
  4. Hotspot垃圾回收
  5. 夫妻经典小笑话····
  6. python向量化编程技巧_Python学习(六)向量化
  7. OGG_GoldenGate日常维护(案例)
  8. 2022-07-25
  9. Windows下完成SCTP简单抓包
  10. 连续多帧图像光流对齐和光流运动检测
  11. 12月19日|DevFest 2021 京津冀专场重磅来袭!
  12. js:简单的盒子碰撞
  13. iPad 使用技巧:备忘录
  14. api与密度转换公式_API重度和密度换算公式.doc
  15. 怎么分析某个明星或者公众人物ins的数据?
  16. java计算机毕业设计基于安卓Android的论坛App
  17. 响应式布局的实现方式(5种)
  18. 超级计算机的英语作文80字,80字英语作文要10篇80字左右的英语作文
  19. 自制U盘安装xin7系统
  20. php 直接使用十六进制,人们通常用十六进制而不用二进制书写计算机是为什么...

热门文章

  1. IOS 关于设置同样的字号,显示大小不一致
  2. php使用excel表格数据库数据,php使用excel表格数据库数据库-php中如何将execl的数据导入到数据库中...
  3. echarts各省市地图实现
  4. 凸优化问题:基础定义
  5. 全球GDP和人口数据合集
  6. JavaScript的运行机制
  7. 系统分析员论文12篇
  8. 个人网站搭建学习笔记
  9. Terraform实战 | 实用云部署编程入门指南,DevOps软件开发运维必备
  10. Http服务传输图片的Python实现