zoukankan      html  css  js  c++  java
  • Android开发 ViewPager删除Item后,不会更新数据和View

    问题描述: 

      在使用ViewPager的适配器删除适配器里一个Item后依然会,而删除的这个item依然会保留缓存,适配器不会重新加载更新数据.如下代码:

    public class TReleaseCircleZoomablePagerAdapter extends PagerAdapter {
        private List<TReleaseCircleBase.Pic> mImageUrlList = new ArrayList<>();
    
    
        public void removeItem(int position){
            mImageUrlList.remove(position);
            notifyDataSetChanged();
    
        }
    
    //....略

    在这个代码里removeItem(int position)是希望清理适配器List里的一项item,并且重新刷新.但是其实真实情况是并不会重新刷新...... 在滑动超过3个页面后才会让你那个删除item消失.

    解决办法:

    依然在这个适配器里重写public int getItemPosition(@NonNull Object object)方法

    public class TReleaseCircleZoomablePagerAdapter extends PagerAdapter {
        private List<TReleaseCircleBase.Pic> mImageUrlList = new ArrayList<>();
    
        public void removeItem(int position){
            mImageUrlList.remove(position);
            notifyDataSetChanged();
    
        }
    
    
        @Override
        public int getItemPosition(@NonNull Object object) {
    //        return super.getItemPosition(object);
            return POSITION_NONE;
        }
    
    //略......

    注意关键点是返回 POSITION_NONE

    为什么呢?

      为什么我改了这个之后就可以在删除item后更新view了呢?好奇心害死猫,我们进一步探究一下.

      首先我们看看 return super.getItemPosition(object); 父类里写的返回值到底里面有啥

      

        /**
         * 在主视图尝试确定项目的位置时调用
         * 已经改变。 如果给定的位置,则返回{@link #POSITION_UNCHANGED}
         * 如果适配器中不再存在该项,则item未更改或{@link #POSITION_NONE}。
         *
         * <p>The default implementation assumes that items will never
         * change position and always returns {@link #POSITION_UNCHANGED}.
         *
         * @param object Object representing an item, previously returned by a call to
         *               {@link #instantiateItem(View, int)}.
         * @return object's new position index from [0, {@link #getCount()}),
         *         {@link #POSITION_UNCHANGED} if the object's position has not changed,
         *         or {@link #POSITION_NONE} if the item is no longer present.
         */
        public int getItemPosition(@NonNull Object object) {
            return POSITION_UNCHANGED;
        }

    很好上面的意思是

    如果视图item已经是加载过的,就使用 POSITION_UNCHANGED 来标识,表示这个item不需要重复更新

    如果item在适配器里不存在,就说item未加载过,就使用 POSITION_NONE 来标识,标识这个item需要更新一次

    接着继续探究下ViewPager是怎么调用getItemPosition()的

    void dataSetChanged() {
            // This method only gets called if our observer is attached, so mAdapter is non-null.
    
            final int adapterCount = mAdapter.getCount();
            mExpectedAdapterCount = adapterCount;
            boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1
                    && mItems.size() < adapterCount;
            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, adapterCount - 1));
                        needPopulate = true;
                    }
                    continue;
                }
    上面的if (newPos == PagerAdapter.POSITION_UNCHANGED)if (newPos == PagerAdapter.POSITION_NONE) 就已经破案了...,只能说google真会写方法名称...

  • 相关阅读:
    Environment variable ORACLE_UNQNAME not defined. Please set ORACLE_UNQNAME to database unique name. 的解决方法
    无法打开物理文件xxx.mdf 操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120) 的解决方法
    IIS7.5 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler” 错误的解决方法
    datetime
    9.29中文词频统计
    9.26文件方式实现完整的英文词频统计实例
    9.22
    英文词频统计预备,组合数据类型练习
    9.19凯撒密码、GDP格式化输出、99乘法表
    9.15字符串基本操作
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/11099708.html
Copyright © 2011-2022 走看看