第七个项目——新闻列表
实验目的
掌握ListView控件的基本用法;
掌握ListView自定义Item布局的方法;
掌握ArrayAdapter的基本用法及自定义Adapter的方法;
掌握CardView控件的基本用法;
实验要求
创建布局文件并对根据要求对布局进行设置;
实验内容
在本实验项目中,要求实现如图1. Code06最终运行效果所示的新闻阅读器应用。

步骤一,创建Android工程
打开Android Studio创建名为Code06的工程,选择Empty Activity模板。
步骤二,修改activity_main.xml布局
在activity_main.xml中添加一个ListView作为根容器的唯一子控件,代码如下所示。
步骤三,准备ListView的数据源
简便起见,我们将所有的新闻数据作为字符串资源放入arrays.xml文件中。 在工程窗口中右击app模块文件夹,选择【New】-> 【Android Resource File】菜单,弹出New Resource File窗口,设置文件名为arrays。 在array.xml文件中加入titles及authors两个字符串数组,代码如下所示。
步骤四,构造ListView所需的Adapter对象
ListView控件需要通过setAdapter()方法设置数据适配器,并绑定每个Item对应的布局。在MainActivity类中进行此操作。
1. 读取arrays.xml文件中的titles、authors字符串数组资源。
在MainActivity类中定义了titles、authors两个字符串数组,并使用getResources()得到Resources对象,并通过该对象的getStringArray的方法获取arrays.xml文件中定义的字符串数组资源。
2. 设置ArrayAdapter,指定Item布局。
在本步骤中使用ArrayAdapter绑定titles字符串数组作为ListView控件的数据源。并指定Item的布局为系统预定义的 android.R.layout.simple_list_item_1,该布局指包含1个TextView控件。
3. 编译并部署APK。
编译本项目,并部署运行,其运行效果如图2. Code06运行效果——仅显示新闻标题所示。

步骤五,设置SimpleAdapter,在ListView中显示新闻标题及作者
ArrayAdapter作为ListView的适配器使用时,只能用于Item中包含1个TextView的情况。如果要在列表中显示新闻的标题及作者,则需要使用SimpleAdapter作为适配器。
首先了解SimpleAdapter适配器构造函数如何使用,代码如下所示,其中:
Context context,表示上下文对象,可直接传递MainActivity.this对象;
List<? extends Map > data,表示绑定的数据List列表,其类型需为Map;
int resource,ListView的Item布局资源,可以为系统预定义或用户自定义的布局资源;
String[] from,Map中的String类型的Key,与to结合一起将Map中的该key对应的value绑定到to数组中的资源上;
int[] to,resource布局资源中对应的控件id,与from结合完成Map中value数据与控件的绑定;
1. 构造数据源的List对象。
使用List > dataList 替换掉之前定义的titles、authors数组。将数据源的构造操作 放入initData()方法中。
2. 构造SimpleAdapter适配器。
SimpleAdapter对象所需的context上下文参数、数据源对象均已经构造好。Item布局则使用 系统预定义的android.R.layout.simple_list_item_2资源,该资源包含两个TextView控件标签,具体可在Android Studio中查看。
from数组,则是构造List >对象时所使用到的两个key:NEWS_TITLE及NEWS_AUTHOR。
to数组中则是android.R.layout.simple_list_item_2资源中的两个TextView控件标签的id。
3. 编译并部署APK。
编译本项目,并部署运行,其运行效果如图3. Code06运行效果——仅显示新闻标题及作者所示。

步骤六,自定义Item布局
要在ListView控件中的每一列中显示如图1. Code06最终运行效果所示新闻图片、标题、作者样式,需要自定ListView的Item布局。
1. 自定义list_item.xml布局。 在工程窗口中右击app模块文件夹,选择【New】-> 【Android Resource File】菜单, 弹出New Resource File窗口,将File Name设为list_item, Resource Type设为Layout。
list_item.xml布局中的根元素使用CardView卡片容器控件。要使用卡片容器控件,需要在app模块的build.gradle文件中加入该控件的依赖库,代码如下所示。
在CardView中使用RelatvieLayout进行布局管理,其中引入ImageView显示新闻图片。 设定其图片拉伸属性scaleType为centerCrop。
新闻标题及作者对应的TextView控件则使用分别使用layout_below属性位于新闻图片及新闻标题下方,并设置合理的padding属性,list_item.xml布局代码下所示。
2. 加入图片资源
将准备好的图片资源放入工程的res/drawable文件夹中,并且在arrays.xml文件中加入这些图片资源的drawable路径字符串数组,代码如下所示。
步骤七,构造NewsAdapter适配器类
1. 构造News类。
News类用于存储新闻的标题、作者、新闻正文、对应的标题图,代码如下所示。 需要为News类中的每个成员变量设置set/get方法,可通过【Refactor】->【Encapsulate Fields...】 窗口选择所需封装的成员变量自动生成set/get方法。
2. 构造NewsAdapter适配器类。
右击工程窗口中的app/java文件夹,选择【New】-> 【Java Class】,将类名命名为NewsAdapter。 继承的父类为ArrayAdapter。
对于继承至ArrayAdapter类的NewsAdapter子类,需要至少实现两个方法:构造器方法以及getView方法。
NewsAdapter类的构造器需要三个参数,分别为:
Context context,context上下文用于NewsAdapter类中LayoutInflater加载布局时使用;
int resourceId,用于设置ListView每个Item项时的布局;
List data,用于传递News对象列表;
NewsAdapter构造函数中首先调用父类的构造方法,再将这三个参数保存以便在getView方法中使用。
getView方法是用于ListView显示某一位置Item时进行回调的方法。该方法返回值为Item所需要加载的View控件。 而该方法的的三个参数含义为:
int position,当前Item对应的位置;
View convertView,针对ListView中缓存的不可见的Item的View对象;
ViewGroup parent,需要加载的View的父容器对象;
通过position参数,可以使用getItem方法获取对应的News对象。
针对第二个参数convertView,需要结合ViewHolder使用以减少每一次getView方法调用 都需要重新构造Item项View布局对象,从而提升ListView效率,在此先不做介绍,详见第\ref{sec:listviewdemo}章内容。
在getView方法中调用LayoutInflater加载指定的resourceId布局,第二个参数则为加载的布局对应的父容器控件对象, 第三个参数表示是否将加载的布局加入父容器控件中,在此情况下要选择false。
使用LayoutInflater加载完成布局后,可分别绑定新闻标题、新闻作者、新闻标题图控件。并根据position取到的News对象设置这三个控件的属性,从而完成当前Item对应的布局的加载及数据绑定操作。
3. 修改数据源的构造方式。
在MainActivity中修改从arrays.xml中加载新闻标题、作者、新闻标题图的方式。
首先使用List newsList作为存储加载数据的对象。并在initData方法中使用Resources 的obtainTypedArray方法获取在arrays.xml文件定义的新闻标题图drawable资源。
在onCreate方法中新建NewsAdapter,并把自定义的list_item布局,以及在initData中构造的newsList 对象作为其构造函数参数。
最后将通过ListView的setAdapter设置构造好的NewsAdapter适配器,完成数据源与ListView的绑定。
4. 编译并部署APK。
编译本项目,并部署运行,其运行效果如图1. Code06最终运行效果所示。
实验小结
通过本次实验,你应该掌握了如下知识内容:
使用ListView进行数据显示;
自定义ListView的Item布局;
自定义ArrayAdapter构造适配器;
使用CardView卡片布局展示数据;
Last updated
Was this helpful?