IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android ViewPager的动态更新和Adapter的notifyDataSetChanged方法无效的问题 -> 正文阅读

[移动开发]Android ViewPager的动态更新和Adapter的notifyDataSetChanged方法无效的问题

开门见山地说????????ViewPager的动态更新分为以下两种情况:

????????????????1.只改变渲染的List中某些元素的某个值,不改变位置和数量的

? ? ? ? ? ? ? ? 2.改变位置和数量的

????????而Adapter的notifyDataSetChanged方法恰好就是在第一种情况中无效的。

? ? ? ? 先讨论第一种情况。

????????可能有一些跟我一样的初学者会有一样的疑问,为什么里面的元素都更改了,他的这个方法不触发呢,别急,导致notifyDataSetChanged方法哑火的情况有很多,我先只列出这种情况,你先看看是不是你的菜。

? ? ? ? 我使用ViewPager+List<View>+ViewPagerAdapter构建了一个简易的切换页面,点击上方按钮,就可以更新下面的viewpager里面的当前索引的子项的某个组件的值(背景色),这里只大概解释原理和运行规则,MainActivity的代码如下,其他部分的代码我就不贴出来了,想必各位读者都是真才实学的高手,这点代码难不倒你们的。

? ? ? ?

public class MainActivity extends AppCompatActivity {

    private TextView mTextView;
    private ViewPager mViewPager;
    private MViewPagerAdapter mAdapter;
    private List<View> itemList;
    private LayoutInflater mInflater;
    private int mIndex;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mViewPager = findViewById(R.id.viewPager);
        mTextView = findViewById(R.id.textView);
        itemList = new ArrayList<>();
        mInflater = getLayoutInflater();
        //添加两个初始子项
        itemList.add(generateItem(R.color.pink));
        itemList.add(generateItem(R.color.teal_200));
        mAdapter = new MViewPagerAdapter(this,itemList);
        mViewPager.setAdapter(mAdapter);
        //给viewpager添加切换事件监听,滑动时可以切换索引
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                mIndex = position;
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        mTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                changeCurrentColor(mIndex,R.color.red);
            }
        });
    }

    /**
     * 用于插入一个ViewPager的子项
     * @param id 颜色的id,可以指定生成什么颜色的子项
     * @return 返回一个子项的view,直接插入itemList
     */
    public View generateItem(int id){
        View item = mInflater.inflate(R.layout.viewpager_item, null);
        TextView vpTextView = item.findViewById(R.id.vp_textView);
        vpTextView.setBackgroundColor(getResources().getColor(id));
        return item;
    }

    /**
     * 根据索引改变当前位置的子项中组件的背景色
     * @param index 索引
     * @param id 颜色的id
     */
    public void changeCurrentColor(int index,int id){
        //错误的做法
        /*View view = generateItem(id);
        itemList.set(index,view);
        mAdapter.notifyDataSetChanged();*/
        
        //正确的做法
        View view = itemList.get(index);
        TextView tv = view.findViewById(R.id.vp_textView);
        tv.setBackgroundColor(getResources().getColor(id));
    }
}

????????可以看到我标出了错误的做法和正确的做法两个地方。可能是因为java基础不好,我很多时候是拒绝查看源码的,这是一个不好的习惯,也是导致这个问题我也是查了资料才解决的。

? ? ? ? 源码中notifyDataSetChanged()的触发条件有二:

? ? ? ? 1). 当前对象发生过位置改变

? ? ? ? 2). 绑定的List的长度发生变化

具体源码的话我还是不太看得懂,详情见这篇

https://www.jianshu.com/p/863297e782c3?nomobile=yes

? ? ? ? 也就是说,在错误案例中的

        View view = generateItem(id);
        itemList.set(index,view);
        mAdapter.notifyDataSetChanged();

?这样的操作完全没有碰到notifyDataSetChanged()方法的触发条件,这样用是错误的。

在更新List时的,删除子项或插入子项,调用这个方法没问题,但如果只是维护某索引的某个子项中的某个值的话,建议直接去修改它就好。

因此notifyDataSetChanged的这种情况的结论简单来说就是: 删除或插入可以,简单的更新不行。

当然notifyDataSetChanged失效的原因还有一点,viewpager-adapter-list三者之一不指向绑定时的地址了,换句话说就是,有内鬼!

具体的原因这篇文章讲的还不错,嘻嘻。

https://blog.csdn.net/whitley_gong/article/details/50562634

十分感谢你能看到这里。我们的目标是星辰大海,加油!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:42:49  更:2021-08-12 16:44:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 3:42:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码