从 ListView 到 RecyclerView 的用法浅析

从 ListView 到 RecyclerView 的用法浅析,第1张

概述文章目录要走好明天的路,必须记住昨天走过的路,思索今天正在走着的路。ListView,一种在垂直滚动列表中显示条目的视图;RecyclerView,一种在局限的窗口呈现大数据集合的灵活视图。RecyclerView部件是ListView的一种更高级且更灵活的版本。以上描述来自官网。移动设备屏幕空间 文章目录

要走好明天的路,必须记住昨天走过的路,思索今天正在走着的路。

ListVIEw,一种在垂直滚动列表中显示条目的视图;RecyclerVIEw,一种在局限的窗口呈现大数据集合的灵活视图。RecyclerVIEw 部件是 ListVIEw 的一种更高级且更灵活的版本。

以上描述来自官网。

移动设备屏幕空间有限,导致在屏幕上一次性显示的内容也是有限的。当需要显示大量的数据时,设想有这样的控件,可以帮助用户只通过手指上下滑动,就可以让屏幕外的数据滚动到屏幕内,同时,屏幕上原有的数据会滚动出屏幕。如此,便可以优雅地解决在局限的屏幕上显示大量数据的问题。ListVIEw 和 RecyclerVIEw 便适用于此。

不过,自 AndroID 5.0 推出以来,RecyclerVIEw 在很多地方都在逐步取代 ListVIEw,这也是官方推崇的。“江山代有才人出,各领风骚数百年”。如今,已要来到 AndroID 7.0 的时代,RecyclerVIEw 的使用也很普遍了,或许,ListVIEw 正逐步从 AndroID 的大舞台退出,RecyclerVIEw 即将独领风骚。

下面浅析从 ListVIEw 到 RecyclerVIEw 的用法

ListVIEw 的用法

ListVIEwDemo 地址: ListViewDemo,学习总结自郭霖的《第一行代码》。

新建一个 ListVIEwDemo 项目,默认持续下一步直至完成。然后,删掉 activity_main.xml 中默认建好的 TextVIEw,建立一个 ListVIEw 如下:

1
2
3
4
5
<ListVIEw
androID:ID="@+ID/List_vIEw"
androID:layout_wIDth="match_parent"
androID:layout_height="match_parent">
</ListVIEw>

接着,新建一个实体类 Fruit,作为 ListVIEw 适配器的适配类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class  {

private String name;
private int imageID;

public (String name, int imageID) {
this.name = name;
this.imageID = imageID;
}

public String getname() {
return name;
}

public int getimageID() {
return imageID;
}
}

name 是水果的名字,imageID 是水果对应图片的资源 ID。然后,为 ListVIEw 的子项自定义一个布局,在 layout 目录下新建 fruit_item.xml 如下:

1
2
3
4
5
6
7
8
9
10
11
<ImageVIEw
androID:ID="@+ID/fruit_image"
androID:layout_wIDth="wrap_content"
androID:layout_height="wrap_content"/>

<TextVIEw
androID:ID="@+ID/fruit_name"
androID:layout_wIDth="wrap_content"
androID:layout_height="wrap_content"
androID:layout_gravity="center"
androID:layout_marginleft="10dp"/>

ImageVIEw 用于显示水果的图片,TextVIEw 用于显示水果的名称。

由于数据无法直接传递给 ListVIEw,需要借助适配器完成。AndroID 中提供了很多适配器的实现类,这里使用 ArrayAdapter,通过泛型指定适配的数据类型,再在构造函数中传入适配的数据。自定义一个适配器 FruitAdapter,继承自 ArrayAdapter,泛型指定为 Fruit 类。

同时,优化 ListVIEw 的使用效率:

一. FruitAdapter 中的 getVIEw() 方法每次都将布局加载一遍,这样,快速滚动的话会影响性能。故利用好 convertVIEw 参数,缓存之前加载好的布局,再重用。

二. 使用 VIEwHolder 模式,其充分利用 ListVIEw 的视图缓存机制,避免每次调用 getVIEw() 时通过 findVIEwByID() 实例化控件。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class FruitAdapter extends ArrayAdapter<Fruit> {

private int resourceID;

public FruitAdapter(Context context, int textVIEwResourceID, List<Fruit> objects) {
super(context, textVIEwResourceID, objects);
resourceID = textVIEwResourceID;
}


public VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) {
Fruit fruit = getItem(position);
VIEw vIEw;
VIEwHolder vIEwHolder;
if (convertVIEw == null) {
vIEw = LayoutInflater.from(getContext()).inflate(resourceID, null);
vIEwHolder = new VIEwHolder();
vIEwHolder.fruitimage = (ImageVIEw) vIEw.findVIEwByID(R.ID.fruit_image);
vIEwHolder.fruitname = (TextVIEw) vIEw.findVIEwByID(R.ID.fruit_name);
vIEw.setTag(vIEwHolder);
} else {
vIEw = convertVIEw;
vIEwHolder = (VIEwHolder) vIEw.getTag(); //重新获取 VIEwHolder, 找到缓存的布局.
}
vIEwHolder.fruitimage.setimageResource(fruit.getimageID());
vIEwHolder.fruitname.setText(fruit.getname());
return vIEw;
}

class VIEwHolder {
ImageVIEw fruitimage;
TextVIEw fruitname;
}
}

FruitAdapter 重写父类的构造函数,将上下文、ListVIEw 子项布局的 ID 和数据传递进来。同时,重写了 getVIEw() 方法,每个子项滚动进屏幕内时调用该方法。其中,getItem() 方法获取当前项的 Fruit 实例。

增加判断与一个内部类 VIEwHolder,利用视图缓存机制进行缓存。

若 convertVIEw 为空,则创建一个 VIEwHolder 对象,将控件的实例存放在 VIEwHolder 里。然后,调用 VIEw 的 setTag() 方法,将 VIEwHolder 对象存储在 VIEw 中。若 convertVIEw 不为空,则调用 VIEw 的 getTag() 方法,重新取出 VIEwHolder。如此,所有控件的实例都缓存在 VIEwHolder 里。

最后,修改并完善 MainActivity 中的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class MainActivity extends AppCompatActivity {

private List<Fruit> fruitList = new ArrayList<Fruit>();

@OverrIDe
protected voID onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.activity_main);
initFruits();

FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);
ListVIEw ListVIEw = (ListVIEw) findVIEwByID(R.ID.List_vIEw);
ListVIEw.setAdapter(adapter);
}

private voID initFruits() {
Fruit apple = new Fruit("Apple", R.mipmap.ic_launcher);
fruitList.add(apple);
Fruit banana = new Fruit("Banana", R.mipmap.ic_launcher);
fruitList.add(banana);
Fruit orange = new Fruit("Orange", R.mipmap.ic_launcher);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermelon", R.mipmap.ic_launcher);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.mipmap.ic_launcher);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.mipmap.ic_launcher);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.mipmap.ic_launcher);
fruitList.add(pineapple);
Fruit strawBerry = new Fruit("StrawBerry", R.mipmap.ic_launcher);
fruitList.add(strawBerry);
Fruit cherry = new Fruit("Cherry", R.mipmap.ic_launcher);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.mipmap.ic_launcher);
fruitList.add(mango);
Fruit peach = new Fruit("Peach", R.mipmap.ic_launcher);
fruitList.add(peach);
Fruit lemon = new Fruit("Lemon", R.mipmap.ic_launcher);
fruitList.add(lemon);
Fruit pitaya = new Fruit("Pitaya", R.mipmap.ic_launcher);
fruitList.add(pitaya);
Fruit durin = new Fruit("Durin", R.mipmap.ic_launcher);
fruitList.add(durin);
}

}

添加了 initFruits() 方法,初始化所有的水果数据。将水果的名字和对应的图片 ID 传入 Fruit 类的构造函数中,再把创建好的对象添加到水果列表中。而后,在 onCreate() 方法里创建了 FruitAdapter 对象,将 FruitAdapter 作为适配器传递给 ListVIEw。

至此,ListVIEw 的简单综合应用浅析完毕,运行程序,如下:

更多如动态修改 ListVIEw、使 ListVIEw 具有d性、自动显示与隐藏布局 ListVIEw、模仿微信聊天布局 ListVIEw、动态改变点击 Item 布局的 ListVIEw 等,详见 GitHub。

RecyclerVIEw 的用法

RecyclerVIEwDemo 地址: RecyclerViewDemo,学习总结自徐宜生的《 AndroID 群英传》。

首先,在 gradle 中引入compile 'com.androID.support:recyclervIEw-v7:23.4.0'的依赖。由于 RecyclerVIEw 封装好了 VIEwHolder,再实现其功能。新建一个 RecyclerVIEwDemo 如上所示,同时添加了 Spinner 和按钮:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<androID.support.v7.Widget.RecyclerVIEw
androID:ID="@+ID/rc_List"
androID:layout_wIDth="match_parent"
androID:layout_height="0dp"
androID:layout_weight="9"
androID:scrollbars="vertical"/>

<linearLayout
androID:layout_wIDth="match_parent"
androID:layout_height="0dp"
androID:layout_weight="1">

<Spinner
androID:ID="@+ID/spinner"
androID:layout_wIDth="0dp"
androID:layout_height="wrap_content"
androID:layout_weight="1"
androID:entrIEs="@array/recycler_List"/>

<button
androID:layout_wIDth="0dp"
androID:layout_height="wrap_content"
androID:layout_weight="1"
androID:onClick="addRecycler"
androID:text="Add"/>

<button
androID:layout_wIDth="0dp"
androID:layout_height="wrap_content"
androID:layout_weight="1"
androID:onClick="delRecycler"
androID:text="Delete"/>

</linearLayout>

在 strings.xml 中新建 Spinner 中用到的 array:

1
2
3
4
<string-array name="recycler_List">
<item>linearlayoutmanager</item>
<item>GrIDLayoutManager</item>
</string-array>

与 ListVIEw 的用法一样,使用一个合适的数据适配器来加载数据,自定义一个适配器 RecyclerAdapter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
总结

以上是内存溢出为你收集整理的从 ListView 到 RecyclerView 的用法浅析全部内容,希望文章能够帮你解决从 ListView 到 RecyclerView 的用法浅析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1067845.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)