RecyclerView(局部刷新) 和 ListView(优化)的区别,ExpandableListView,ListView禁止上下滚动

本文主要是介绍RecyclerView(局部刷新) 和 ListView(优化)的区别,ExpandableListView,ListView禁止上下滚动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

根据自己的使用场景来选择是要用 RecyclerView 还是 ListView- https://github.com/D-clock/AndroidSystemUiTraining
-- RecyclerView 相比 ListView 在基础使用上的区别主要有如下几点:
  1.ViewHolder 的编写规范化了
  2.RecyclerView 复用 Item 的工作 Google 全帮你搞定,不再需要像 ListView 那样自己调用 setTag

  3.RecyclerView 需要多出一步 LayoutManager 的设置工作

--  监听RecyclerView列表划过的位置 Android
scrollview监听滑动位置- https://blog.csdn.net/shb2058/article/details/50707221
android 检测ListView滚动到的位置- http://www.mamicode.com/info-detail-121427.html
android仿朋友圈列表精准定位- https://www.jianshu.com/p/c741a0488a70

-- ListView 和 RecyclerView 复用机制区别- https://www.jianshu.com/p/1eaaccd169e4
 ListView 的复用是两级缓存的,而 RecyclerView 是四级缓存;
 ListView 复用的是 View,也就是在实现 ListView 的 Adapter 的时候实现的 getView 方法里的参数 convertView,但是 RecyclerView 复用的对象是 ViewHolder,当然 ListView 也可以由自己来实现 ViewHolder;
  ListView 的回收过程十分简单,就是完全滑出屏幕后就把 View 回收到 mScrapeViews 当中去,并把 View 还原成初始状态,所以说 ListView 中所有进行复用的 View 的数量加起来一定是一个定值,其大小和屏幕所能容纳下的 item 的个数有关
  RecyclerView 的回收过程就是一个标准的二级缓存,滑出屏幕的 ViewHolder 先缓存进 mCacheViews ,此时并不还原视图,当 mCacheViews 中的数量超过一定的限制以后(默认是2个,这个是可以由自己来决定的),将最先放入 mCacheViews 的 ViewHolder 放入到 mRecyclerPool 当中去,并且是根据 View 的 type 不同,放入不同的 mRecyclerPool 当中去,同时 mRecyclerPool 也有大小的限制(默认是 5 个),但是这种回收机制好处就在于可以保证 mCacheViews 和 mRecyclerPool 是最新的放到前面。

> RecyclerView 

RecyclerView添加头部和尾部- https://github.com/jdsjlzx/LRecyclerView

RecyclerView添加头部和尾部- https://github.com/whichname/PTLRecyclerView

为RecyclerView添加HeaderView和FooterView- http://blog.csdn.net/lmj623565791/article/details/51854533
 Android 默认提供的 RecyclerView 就能支持 线性布局、网格布局、瀑布流布局 三种(这里我们暂且不提代码细节,后文再说),而且同时还能够控制横向还是纵向滚动。怎样,从效果上足以碾压 ListView 有木有。

LayoutManager 只是一个抽象类而已,系统已经为我们提供了三个相关的实现类:
  1.横向滚动的ListView开源控件是不是可以不用再找了?对,你没看错!- LinearLayoutManager(线性布局效果)
  2.瀑布流效果的开源控件是不是可以不用再找了?对,你没看错!- GridLayoutManager(网格布局效果)
  3.连横向滚动的GridView都不用找了!对,你没看错!-StaggeredGridLayoutManager(瀑布流布局效果)
-- RecyclerView 基础使用关键点同样有两点:
  继承重写 RecyclerView.Adapter 和 RecyclerView.ViewHolder;
  设置布局管理器,控制布局效果

-- 系统也为我们提供了两个默认的动画实现:SimpleItemAnimator 和 DefaultItemAnimator。而 RecyclerView 在不手动调用 setItemAnimator 的情况下,则默认用了内置的 DefaultItemAnimator 。

-- RecyclerView管理器:
1.LinearLayoutManager 现行管理器,支持横向、纵向。
2.GridLayoutManager 网格布局管理器
3.StaggeredGridLayoutManager 瀑布就式布局管理器
-- RecyclerView整体总结它的几点如下:
 Adapter:包装数据集合并且为每个条目创建视图。
 ViewHolder:保存用于显示每个数据条目的子View。
 LayoutManager:将每个条目的视图放置于适当的位置。
 ItemDecoration:在每个条目的视图的周围或上面绘制一些装饰视图。
 ItemAnimator:在条目被添加、移除或者重排序时添加动画效果。

-- RecyclerView 数据刷新的几种方式,RecyclerView 真正的布局刷新的正确方式
再说Android RecyclerView局部刷新那个坑- https://blog.csdn.net/jdsjlzx/article/details/52893469
RecyclerView之更新UI数据的高级用法- https://blog.csdn.net/leejizhou/article/details/51179233

notifyDataSetChanged(),刷新全部可见的item

notifyItemChanged(int position) 更新列表position位置上的数据可以调用
notifyItemInserted(int position) 列表position位置添加一条数据时可以调用,伴有动画效果
notifyItemRemoved(int position) 列表position位置移除一条数据时调用,伴有动画效果
notifyItemMoved(int fromPosition, int toPosition) 列表fromPosition位置的数据移到toPosition位置时调用,伴有动画效果
notifyItemRangeChanged(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项进行数据刷新
notifyItemRangeInserted(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项批量添加数据时调用,伴有动画效果
notifyItemRangeRemoved(int positionStart, int itemCount) 列表从positionStart位置到itemCount数量的列表项批量删除数据时调用,伴有动画效果

-- RecyclerView清除缓存,Fragment中的刷新
Fragment中的刷新问题- https://blog.csdn.net/qq_27969037/article/details/53555884
RecyclerView 局部刷新Item卡顿,已解决- https://blog.csdn.net/weixin_39079048/article/details/79448344
adapter试下remove后,再insert。

-- 使用https://github.com/whichname/PTLRecyclerView库,adapter里面的notify一系列方法,好多都失效,除了load的时候能完成部分效果外,绝大部分效果并不支持,比如元素删除、插入等
由于头部其实也是item,因此使用notify时,需通过adapter获取item真实的位置来进行更新

-- RecyclerView缓存,RecyclerView缓存清理,RecyclerView的重用机制
RecyclerView解决条目错乱以及图片闪越+三级缓存机制- https://blog.csdn.net/haoxl1994/article/details/59095522
 - 解决recyclerView加载图片闪越问题和图片错乱的问题:
 图片闪越:在onBindView方法中给图片设置站位图
 图片错乱:一种是在onViewRecycle方法中取消加载的图片的异步任务,第二种是在onBindViewHolder方法中给ImageView设置Tag,在设置图片的时候判断Tag如果没有变化才设置图片。

 - RecyclerView缓存机制总结:主要是三步:
主要靠三个内部类来完成,Recycler,ViewCacheExtension,RecyclerViewPool:
 1、首先通过 recycler.getViewForPosition()方法,该方法返回ViewHolder对象,通过源码可以知道,该方法会检查mAttachedScrap和一级
缓存列表mCachedViews,如果有则返回ViewHolder进行复用。
 2、然后调用ViewCacheExtension.getViewForPositionAndType()方法,注意这个方法是抽象方法,需要开发者进行重写。
 3、最后检查RecyclerViewPool是否有ViewHolder。
 注意:上述的三个步骤中,只要有一个返回了ViewHolder,就不会在进行后边的步骤了。
 最后:缓存的数量:默认的一级缓存中,mCachedViews中可以缓存的ViewHolder的个数是2;默认的缓存池中的缓存数量是 5;所以在缓存时
,会先检测一级缓存是否满了,如果没满就add进去,如果满了就加入到三级缓存Recyclerpool
recyclerView的Item局部更新问题:http://www.tuicool.com/articles/euuy2iM

-- RecyclerView的绘制流程关键点:
 1.RecyclerView是将绘制流程交给LayoutManager处理,如果没有设置不会测量子View。
 2.绘制流程是区分正向绘制和倒置绘制。
 3.绘制是先确定锚点,然后向上绘制,向下绘制,fill()至少会执行两次,如果绘制完还有剩余空间,则会再执行一次fill()方法。
 4.LayoutManager获得View是从RecyclerView中的Recycler.next()方法获得,涉及到RecyclerView的缓存策略,如果缓存没有拿到,则走我们自己重写的onCreateView方法。
 5.如果RecyclerView宽高没有写死,onMeasure就会执行完子View的measure和Layout方法,onLayout仅仅是重置一些参数,如果写死,子View的measure和layout会延后到onLayout中执行。

基于AOP的RecyclerView楼层开发方式,支持组件化工程,全局多人楼层打通,高拓展性- https://github.com/DrownCoder/EMvp

 视图的复用机制,也就是缓存。从ListView的RecycleBin到RecyclerView的Recycler,Google对于列表视图的缓存的设计一直非常考究值得我们学习和研究。

RecyclerView类的结构也比较清楚,这里可以清楚的看到我们后面讲到的四级缓存机制所用到的类都在这里可以看到:
    * 1.一级缓存:mAttachedScrap
    * 2.二级缓存:mCacheViews
    * 3.三级缓存:mViewCacheExtension
    * 4.四级缓存:mRecyclerPool
1.RecyclerView内部大体可以分为四级缓存:mAttachedScrap,mCacheViews,ViewCacheExtension,RecycledViewPool.
2.mAttachedScrap,mCacheViews在第一次尝试的时候只是对View的复用,并且不区分type,但在第二次尝试的时候是区分了Type,是对于ViewHolder的复用,ViewCacheExtension,RecycledViewPool是对于ViewHolder的复用,而且区分type。
3.如果缓存ViewHolder时发现超过了mCachedView的限制,会将最老的ViewHolder(也就是mCachedView缓存队列的第一个ViewHolder)移到RecycledViewPool中。

> ListView 

- ListView图片错乱问题,在getview方法中给imageview设置tag,这个tag可以为url
ImageView.setTag(imageUrl);

- 如果要给 ListView 的 Item 加动画,我们只能自己通过属性动画来操作 Item 的视图: https://github.com/nhaarman/ListViewAnimations
-- ListView 的基础使用大家再熟悉不过,其使用的关键点主要如下:
  继承重写 BaseAdapter 类;自定义 ViewHolder 和 convertView 一起完成复用优化工作
-- ListView 提供了 setEmptyView 这个 API 来让我们处理 Adapter 中数据为空的情况,只需轻轻一 set 就能搞定一切。代码设置和效果如下
        mListView = (ListView) findViewById(R.id.listview);

        mListView.setEmptyView(findViewById(R.id.empty_layout));//设置内容为空时显示的视图

[Android优化进阶] 提高ListView性能的技巧 -- http://www.jianshu.com/p/3e22d53286ca#
ListView优化一直是一个老生常谈的问题,不管是面试还是平常的开发中,ListView永远不会被忽略掉,那么这篇文章我们来

-- 如何最大化的优化ListView的性能:
2.尽最大可能避免GC
3.滑动的时候不加载图片
4.将ListView的scrollingCache和animateCache设置为false

5、convertView重用;
 利用好 convertView 来重用 View,切忌每次 getView() 都新建。ListView 的核心原理就是重用 View,如果重用 view 不改变宽高,重用View可以减少重新分配缓存造成的内存频繁分配/回收;
6、ViewHolder优化;
 使用ViewHolder的原因是findViewById方法耗时较大,如果控件个数过多,会严重影响性能,而使用ViewHolder主要是为了可以省去这个时间。通过setTag,getTag直接获取View。
7、图片加载优化
 如果ListView需要加载显示网络图片,我们尽量不要在ListView滑动的时候加载图片,那样会使ListView变得卡顿,所以我们需要在监听器里面监听ListView的状态,如果ListView滑动(SCROLL_STATE_TOUCH_SCROLL)或者被猛滑(SCROLL_STATE_FLING)的时候,停止加载图片,如果没有滑动(SCROLL_STATE_IDLE),则开始加载图片。
8、onClickListener处理(通过接口回传)
9、减少Item View的布局层级
 这是所有layout都必须遵循的,布局层级过深会直接导致View的测量与绘制浪费大量的时间
10、adapter中的getView方法尽量少使用逻辑
 不要在getView方法中做过于复杂的逻辑,可以想办法抽离到别的地方,
11、adapter中的getView方法尽量少做耗时操作
12、adapter中的getView方法避免创建大量对象
13、将ListView的scrollingCache和animateCache设置为false
14、分页加载数据

-- ListView优化方案-http://blog.csdn.net/fenghai22/article/details/44173057

一、复用convertView,减少findViewById的次数 
1、优化一:复用convertView
2、优化二:缓存item条目的引用——ViewHolder

二、ListView中数据的分批及分页加载:

三、ListView中图片的优化:详看OOM异常中图片的优化 ,压缩及三级缓存

四、ListView的其他优化:
1、尽量避免在BaseAdapter中使用static 来定义全局静态变量: 
2、尽量使用getApplicationContext: 
3、尽量避免在ListView适配器中使用线程:

-- ListView禁止上下滑动
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;

public class ScrollEnableListView extends ListView {

    private int mPosition;
    private boolean mIsScroll = true;

    /**
     * 是否支持上下滑动
     *
     * @param isScroll 滑动与否, true可以滚动
     */
    public void setScrollEnable(boolean isScroll) {
        mIsScroll = isScroll;
    }

    public ScrollEnableListView(Context context) {
        super(context);
    }

    public ScrollEnableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrollEnableListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        ToastUtil.showToast("ListView onMeasure");
        if (!mIsScroll) {
            int expandSpec = MeasureSpec.makeMeasureSpec(
                    Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        ToastUtil.showToast("ListView dispatchTouchEvent");
        if (!mIsScroll) {
            return true;
        }
        int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;
        if (actionMasked == MotionEvent.ACTION_MOVE && !mIsScroll) {
            return true;
        }

        if (actionMasked == MotionEvent.ACTION_DOWN) {
            // 记录手指按下时的位置
            mPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
            return super.dispatchTouchEvent(ev);
        }
        // 手指抬起时
        if (actionMasked == MotionEvent.ACTION_UP
                || actionMasked == MotionEvent.ACTION_CANCEL) {
            // 手指按下与抬起都在同一个视图内,交给父控件处理,这是一个点击事件
            if (pointToPosition((int) ev.getX(), (int) ev.getY()) == mPosition) {
                super.dispatchTouchEvent(ev);
            } else {
                // 如果手指已经移出按下时的Item,说明是滚动行为,清理Item pressed状态, 点击事件都能通过触摸后移动来取消这个事件
                setPressed(false);
                invalidate();
                return true;
            }
        }
        return super.dispatchTouchEvent(ev);
    }
}

> 多级列表ExpandableListView

Android中多级列表可以使用ExpandableListView和SimpleExpandableListAdapter配合来实现。

这篇关于RecyclerView(局部刷新) 和 ListView(优化)的区别,ExpandableListView,ListView禁止上下滚动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/417072

相关文章

SpringBoot中HTTP连接池的配置与优化

《SpringBoot中HTTP连接池的配置与优化》这篇文章主要为大家详细介绍了SpringBoot中HTTP连接池的配置与优化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、HTTP连接池的核心价值二、Spring Boot集成方案方案1:Apache HttpCl

PyTorch高级特性与性能优化方式

《PyTorch高级特性与性能优化方式》:本文主要介绍PyTorch高级特性与性能优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、自动化机制1.自动微分机制2.动态计算图二、性能优化1.内存管理2.GPU加速3.多GPU训练三、分布式训练1.分布式数据

关于Mybatis和JDBC的使用及区别

《关于Mybatis和JDBC的使用及区别》:本文主要介绍关于Mybatis和JDBC的使用及区别,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、JDBC1.1、流程1.2、优缺点2、MyBATis2.1、执行流程2.2、使用2.3、实现方式1、XML配置文件

MySQL中like模糊查询的优化方案

《MySQL中like模糊查询的优化方案》在MySQL中,like模糊查询是一种常用的查询方式,但在某些情况下可能会导致性能问题,本文将介绍八种优化MySQL中like模糊查询的方法,需要的朋友可以参... 目录1. 避免以通配符开头的查询2. 使用全文索引(Full-text Index)3. 使用前缀索

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

exfat和ntfs哪个好? U盘格式化选择NTFS与exFAT的详细区别对比

《exfat和ntfs哪个好?U盘格式化选择NTFS与exFAT的详细区别对比》exFAT和NTFS是两种常见的文件系统,它们各自具有独特的优势和适用场景,以下是关于exFAT和NTFS的详细对比... 无论你是刚入手了内置 SSD 还是便携式移动硬盘或 U 盘,都需要先将它格式化成电脑或设备能够识别的「文

什么是ReFS 文件系统? ntfs和refs的优缺点区别介绍

《什么是ReFS文件系统?ntfs和refs的优缺点区别介绍》最近有用户在Win11Insider的安装界面中发现,可以使用ReFS来格式化硬盘,这是不是意味着,ReFS有望在未来成为W... 数十年以来,Windows 系统一直将 NTFS 作为「内置硬盘」的默认文件系统。不过近些年来,微软还在研发一款名

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

售价599元起! 华为路由器X1/Pro发布 配置与区别一览

《售价599元起!华为路由器X1/Pro发布配置与区别一览》华为路由器X1/Pro发布,有朋友留言问华为路由X1和X1Pro怎么选择,关于这个问题,本期图文将对这二款路由器做了期参数对比,大家看... 华为路由 X1 系列已经正式发布并开启预售,将在 4 月 25 日 10:08 正式开售,两款产品分别为华