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

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

禁止平板,iPad长按弹出默认菜单事件

通过监控按下抬起时间差来禁止弹出事件,把以下代码写在要禁止的页面的页面加载事件里面即可     var date;document.addEventListener('touchstart', event => {date = new Date().getTime();});document.addEventListener('touchend', event => {if (new

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

native和static native区别

本文基于Hello JNI  如有疑惑,请看之前几篇文章。 native 与 static native java中 public native String helloJni();public native static String helloJniStatic();1212 JNI中 JNIEXPORT jstring JNICALL Java_com_test_g

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使