android中释放适配器
总览 (Overview)
If you’ve been in Android development for a while, you may well have needed to implement a list of views at various points in your career.
如果您从事Android开发已有一段时间,那么您可能需要在职业生涯的各个阶段实现一系列的观点。
First, you probably used ListView
and GridView
to show a list of items vertically and horizontally— in a grid structure. Then came Recyclerview
, which brought many enhancements to the existing patterns and new implementations like viewtypes
—this was a revolutionary improvement in Android adapters. Recently ListAdapter
has emerged, mainly concentrating on enhancing performance to provide a smooth experience, even with thousands of items on the list.
首先,您可能使用了ListView
和GridView
在网格结构中垂直和水平显示项目列表。 然后是Recyclerview
,它对现有模式和viewtypes
类型等新实现进行了许多增强,这是Android适配器的一项革命性改进。 最近出现了ListAdapter
,主要致力于增强性能以提供流畅的体验,即使列表中包含成千上万个项目。
It’s important to know what we use today. It’s equally important to know why we use what we use today. So let’s look at the history of adapters in Android.
了解我们今天使用的内容很重要。 同样重要的是要知道为什么我们要使用今天使用的东西。 因此,让我们看一下Android中适配器的历史。
底座适配器 (Base Adapter)
This was the beginning of adapters in Android. In base adapters, we don’t have any viewtypes
or itemdecorator
like in modern Android development. Let’s take a look at a simple base adapter:
这是Android中适配器的开始。 在基本适配器中,没有像现代Android开发中那样的任何viewtypes
或itemdecorator
。 让我们看一个简单的基本适配器:
Here, getView
is the function that’s entirely responsible for creating and inflating each view. We have to manually check whether the view has been created or not, then use the views in the layout, which is the best way at that moment. As of my knowledge to inflate different view-types, we need to design all the views in the same layout, and we have to toggle visibility based on the type. That’s a lot of work and the views won’t recycle properly. These things limit Android developers from creating fancy lists like the ones we see on Instagram and Twitter these days.
在这里, getView
是完全负责创建和扩展每个视图的功能。 我们必须手动检查视图是否已创建,然后在布局中使用视图,这是目前的最佳方法。 据我所知,要使不同的视图类型膨胀,我们需要在同一布局中设计所有视图,并且必须根据类型切换可见性。 这是很多工作,并且视图无法正确回收。 这些事情限制了Android开发人员创建喜欢的列表,就像我们最近在Instagram和Twitter上看到的那样。
The other major drawback is that we have to use Grid-Adapter to show views in grids. Personally, I uses BaseAdapter
and GridAdapter
for a while at the beginning of my career in late 2015 — trust me, they suck!
另一个主要缺点是我们必须使用Grid-Adapter在网格中显示视图。 就个人而言,我在2015年底职业生涯初期使用BaseAdapter
和GridAdapter
了一段时间-相信我,他们很烂!
It’s not that they suck at performance, but we have to do every little bit of work all the time and even then there will be issues like OOM (OutOfMemory) exceptions. That was a nightmare back then.
并不是说他们在性能上很烂,但是我们必须一直做每一点工作,即使那样,也会出现诸如OOM(内存不足)异常的问题。 那时真是一场噩梦。
RecyclerView适配器 (RecyclerView Adapter)
Moving forward with the miserable baseAdapter
for months, one day I got to know the miraculous recyclerviewAdapter
. This was a game-changer for me. It not only solved problems in the baseAdapter
but it opened the doors for new possibilities like viewTypes
, itemdecorators
, combining vertical, horizontal and grid lists with layoutmanager
, and more.
随着可悲的baseAdapter
了几个月,有一天我了解了奇迹般的recyclerviewAdapter
。 这对我来说是改变游戏规则的人。 它不仅解决的问题baseAdapter
但它敞开了大门像新的可能性viewTypes
, itemdecorators
,垂直,水平和电网名单相结合layoutmanager
,等等。
Let’s see a simple recyclerview
adapter:
让我们看一个简单的recyclerview
适配器:
In this recyclerview
adapter, we have two different functions: onCreateViewHolder
and onBindViewHolder
. These create the view only once and inflate it whenever required. This increases performance because recyclerview
only creates and uses views when necessary. If you have a hundred items on the list, it won’t load all of them — instead, it only loads the number of views that can be shown to the user at the moment. While scrolling, the recyclerview
adapter only stores the views that are visible to the user in the memory, which makes it more efficient and straightforward.
在此recyclerview
适配器中,我们具有两个不同的功能: onCreateViewHolder
和onBindViewHolder
。 这些仅创建视图一次,并在需要时对其进行充气。 这可以提高性能,因为recyclerview
仅在必要时创建和使用视图。 如果列表中有一百个项目,则不会全部加载-而是仅加载当前可以显示给用户的视图数。 滚动时, recyclerview
适配器仅将用户可见的视图存储在内存中,这使其更高效,更直接。
视图类型 (ViewTypes)
Apart from the above advantages, recyclerview
also opened the doors for new implementation, through viewTypes
, to build nested lists and different layouts in the same adapter.
除了上述优点之外, recyclerview
还通过viewTypes
在新的实现中viewTypes
,以在同一适配器中构建嵌套列表和不同布局。
In the above adapter, we implement getItemViewType()
function and code as shown below in that method. This is the viewType
logic that differentiates the views to inflate.
在上面的适配器中,我们实现了getItemViewType()
函数和代码,如下所示。 这是viewType
逻辑,用于区分要膨胀的视图。
@Override
public int getItemViewType(int position) {
if (employees.get(position).isEmail) {
return TYPE_EMAIL;
} else {
return TYPE_CALL;
}
}
The viewType
that we pass here is available in onCreateViewHolder
. By using it, we inflate different views.
我们在此处传递的viewType
在onCreateViewHolder
可用。 通过使用它,我们可以增加不同的视图。
支持网格和列表 (Supports grids and lists)
There is a new concept called layout-manager in recycler-view, which allows us to integrate both grid and lists without any complexities.
在recycler-view中有一个称为layout-manager的新概念,它使我们能够毫无问题地集成网格和列表。
LinearLayoutManager
: Supports both vertical and Horizontal lists.LinearLayoutManager
:支持垂直和水平列表。StaggeredLayoutManager
: Supports Staggered lists like the ones we see in Pinterest app.StaggeredLayoutManager
:支持交错列表,例如我们在Pinterest应用中看到的列表。GridLayoutManager
: Supports display grids like a gallery.GridLayoutManager
:支持像画廊这样的显示网格。
Take a look at how quickly we can change the list structure with layout manager:
看看我们可以多快地使用布局管理器更改列表结构:
动画制作 (Animations)
Animations in lists is another cool feature that came along with RecyclerView
. RecyclerView
will perform a relevant animation if any of the notify
functions are triggered, except for notifyDataSetChanged
. This includes notifyItemChanged
, notifyItemInserted
, notifyItemMoved
, and notifyItemRemoved
.
列表中的动画是RecyclerView
附带的另一个很酷的功能。 如果触发了任何notify
函数( notifyDataSetChanged
除外),则RecyclerView
将执行相关的动画。 这包括notifyItemChanged
, notifyItemInserted
, notifyItemMoved
和notifyItemRemoved
。
ViewHolder模式 (ViewHolder-Pattern)
The ViewHolder
pattern is used to speed up the rendering of your lists to make it work smoothly. findViewById
is expensive when used each time a list item is rendered — it must traverse deep into your layout hierarchy and also instantiate objects. Since lists can redraw its items quite frequently during scrolling, such overhead might affect the performance.
ViewHolder
模式用于加快列表的呈现速度,以使其顺利运行。 每次呈现列表项时使用findViewById
都很昂贵-它必须遍历您的布局层次结构并实例化对象。 由于列表在滚动过程中可能会非常频繁地重绘其项目,因此此类开销可能会影响性能。
RecyclerView
is no doubt a revolutionary widget in Android, but there is the next step for everything. So it is for RecyclerView
and that next step is called as ListAdapter
.
RecyclerView
无疑是Android中的革命性小部件,但下一步就是一切。 RecyclerView
也是如此,下一步称为ListAdapter
。
列表适配器 (ListAdapter)
RecyclerView
adapter isn’t an extension for BaseAdapter
. ListAdapter
, on the other hand, is the next generation of the RecyclerView
adapter (it extends recyclerview-adapter
). ListAdapter
is mainly focused on improving performance — even with huge chunks of data, like endless Instagram and Twitter feeds with autoplay videos.
RecyclerView
适配器不是BaseAdapter
的扩展。 另一方面, ListAdapter
是下一代RecyclerView
适配器(它扩展了recyclerview-adapter
)。 ListAdapter
主要专注于提高性能-即使有大量数据,例如无尽的Instagram和带有自动播放视频的Twitter feed。
When working with RecyclerView
, the adapter itself is responsible for validating the list if any new items are added or removed or if anything has changed in the existing items. With ListAdapter
, this work is now done by AsyncListDiffer,
a helper for computing the difference between two lists via DiffUtil
on a background thread. Take a look at its basic usage:
使用RecyclerView
,适配器本身负责验证列表,如果添加或删除了任何新项目,或者现有项目中有任何更改。 使用ListAdapter
,这项工作现在由AsyncListDiffer,
完成, AsyncListDiffer,
一个帮助程序,用于通过后台线程上的DiffUtil
计算两个列表之间的差异。 看一下它的基本用法:
It has two main functions:
它具有两个主要功能:
areItemsTheSame (areItemsTheSame)
This function decides whether to inflate the current view or to create a new view. As shown above, we need to compare the primary-key value here like an id, which is unique for every item on the list.
此功能决定是为当前视图充气还是创建新视图。 如上所示,我们需要在此处像ID一样比较主键值,它对于列表中的每个项目都是唯一的。
areContentsTheSame (areContentsTheSame)
List adapter only refreshes the view if this function returns true. That’s because we may have many variables in the items which might not affect the UI, so changes in those variables shouldn’t affect the UI. In order to work this effectively, we need to compare the item-variables that we use in the UI.
如果此函数返回true,则列表适配器仅刷新视图。 这是因为项目中可能有很多变量,这些变量可能不会影响UI,所以这些变量的更改不应影响UI。 为了有效地执行此操作,我们需要比较在UI中使用的项目变量。
In this way, we can control when a new item renders in the list and also when the data in the item is updated. That’s cool, right!
通过这种方式,我们可以控制何时在列表中呈现新项目以及何时更新项目中的数据。 太酷了,对!
奖金 (Bonus)
To learn more about how to use the latest list adapter to create a reactive and heterogeneous Adapter in Kotlin, read this article.
要了解有关如何使用最新的列表适配器在Kotlin中创建React式和异构适配器的更多信息,请阅读本文 。
Thanks for reading.
谢谢阅读。
翻译自: https://medium.com/better-programming/evolution-of-adapters-in-android-2e2ff58c0f98
android中释放适配器