ListView用起来还是比较简单的,也是Android应用程序中最重要的一个组件,但其他ListView可以随你所愿,能够完成很多想要的精美列表,而这正是我们接下来要学习的内容。

一、自定义ArrayAdapter

从上期自定义列表项示例知道,每个列表项的图标都一样,如果需要每个列表项的图标根据内容动态表示,Android系统的ArrayAdapter就无能为力了,就只能使用自定义ArrayAdapter来实现啦。

做法就是创建一个ArrayAdapter的子类,重写其getView()方法,再构建不同的列表项。其中getView()方法返回的是一个View,也就是与Adapter数据对应的相应位置的行。

在学习自定义ArrayAdapter前,一起先来学习一下LayoutInflater类。在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件并实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。

LayoutInflater 是一个抽象类,获得 LayoutInflater 实例有以下三种方式。

[代码]java代码:1

2

3

4

5

6

7

8//通过Activity获取

LayoutInflaterinflater=getLayoutInflater();

//通过静态方法获取

LayoutInflaterinflater=LayoutInflater.from(context);

//通过系统服务获取

LayoutInflaterinflater=   (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

其实这三种方式最终本质是都是调用的Context.getSystemService(),关于该方法的使用会在后续内容进行学习。

获得LayoutInflater 实例后,就可以调用inflater.inflater()方法来查找并实例化布局文件了,常用于获得ListView的每个Item布局。

二、示例

接下来用一个示例来学习如何自定义ArrayAdapter,需要重写getView()方法,在不同对的行中根据内容显示不同的图标。要显示的图标根据显示的字符串首字母来判断,如果以字母“a”或者“A”开头,就显示一张字母A的图标。

继续使用WidgetSample工程的listviewsample模块,在app/main/res/layout/目录下创建custom_arrayadapter_layout.xml文件,在其中填充如下代码片段:

[代码]xml代码:01

02

03

04

05

06

07

08

09

10

11<?xml version="1.0" encoding="utf-8"?>

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/listview"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

然后在res/layout/目录下新建一个custom_arrayadapter_item.xml的列表项布局文件,其代码如下:

[代码]xml代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21<?xml version="1.0" encoding="utf-8"?>

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="horizontal"

android:gravity="center_vertical">

android:id="@+id/letter_img"

android:layout_width="50dp"

android:layout_height="50dp"

android:padding="5dp"

android:class="lazyload" src="https://img-blog.csdnimg.cn/2022010709194779718.png" data-original="@mipmap/ic_launcher"/>

android:id="@+id/content_tv"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="24sp"

android:textColor="#b6400e"/>

再创建一个MyArrayAdapter类,继承ArrayAdapter类,重写getView()方法,具体代码如下:

[代码]java代码:01

02

03

04

05

06

07

08

09

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

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64package com.jinyu.cqkxzsxy.android.listviewsample.adapter;

import android.app.Activity;

import android.support.annotation.NonNull;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ArrayAdapter;

import android.widget.ImageView;

import android.widget.TextView;

import com.jinyu.cqkxzsxy.android.listviewsample.R;

/**

* @创建者 鑫鱻

* @描述 Android零基础入门到精通系列教程,欢迎关注微信公众号ShareExpert

*/

public class MyArrayAdapter   extends ArrayAdapter   {

private Activity mContext = null; //上下文环境

private int mResourceId; //列表项布局资源ID

private String[] mItems; //列表内容数组

public MyArrayAdapter(Activity context, int resId, String[] items){

super(context,   resId, items);

//保存参数

mContext   = context;

mResourceId   = resId;

mItems   = items;

}

@NonNull

@Override

public View getView(int position, View convertView, ViewGroup   parent) {

//获取LayoutInflater对象

LayoutInflater   inflater = mContext.getLayoutInflater();

//装载列表项视图

View   itemView = inflater.inflate(mResourceId, null);

//获取列表项之组件

TextView   contentTv = (TextView) itemView.findViewById(R.id.content_tv);

ImageView   letterImg = (ImageView) itemView.findViewById(R.id.letter_img);

//取出要显示的数据

String   content = mItems[position].trim();

//给TextView设置显示值

contentTv.setText(content);

//根据内容首字母判断要显示的图标

if(content.startsWith("a")   || content.startsWith("A")) {

letterImg.setImageResource(R.drawable.letter_a);

}   else if(content.startsWith("b")   || content.startsWith("B")) {

letterImg.setImageResource(R.drawable.letter_b);

}   else if(content.startsWith("c")   || content.startsWith("C")) {

letterImg.setImageResource(R.drawable.letter_c);

}   else if(content.startsWith("d")   || content.startsWith("D")) {

letterImg.setImageResource(R.drawable.letter_d);

}   else if(content.startsWith("e")   || content.startsWith("E")) {

letterImg.setImageResource(R.drawable.letter_e);

}

//返回列表项视图

return itemView;

}

}

在上述代码中,重写了getView()方法,以便根据要显示的对象返回列表项,其中对象是用Adapter中的位置索引来表示的。

通过LayoutInflater获取到的View对象,实际上就有由列表项布局文件,包含ImageView和TextView的LinearLayout。然后找到ImageView和TextView组件,填充内容给TextView,并根据内容的首字母来判断ImageView要显示的字母图标。

接下来为ListView提供Adapter,使用自定义ArrayAdapter决定ListView所要显示的列表项。新建CustomArrayAdapterActivity.java文件,加载上面新建的布局文件,具体代码如下:

[代码]java代码:01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29package com.jinyu.cqkxzsxy.android.listviewsample;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.widget.ListView;

import com.jinyu.cqkxzsxy.android.listviewsample.adapter.MyArrayAdapter;

public class CustomArrayAdapterActivity   extends AppCompatActivity   {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.custom_arrayadapter_layout);

//获取界面组件

ListView   listView = (ListView) findViewById(R.id.listview);

//定义要显示的数组

String[]   contents = {"Android", "demo", "Edit", "APP",   "excel",

"dota",   "Button", "Circle", "excel", "back"};

//将数组包装为自定义MyArrayAdapter

MyArrayAdapter   adapter = new MyArrayAdapter(this,   R.layout.custom_arrayadapter_item, contents);

//为ListView设置Adapter

listView.setAdapter(adapter);

}

}

可以发现,使用自定义ArrayAdapter和使用Android原生ArrayAdapter的步骤是一样的。

修改启动的Activity,运行程序,可以看到下图所示界面效果。

从上图可以看出,这个显然比之前的示例界面更实用,可以动态显示列表项内容,可以设计出非常美观的列表页面。

今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐