概述
继续构建Miwok语言应用,理解适配器的使用,并自定义适配器。
目标
上次利用视图回收机制在页面中实现了数据的展示,但Miwok是一个用于学习语言的app ,因此需要提供两种语言的参照,如同一个单词需要展示 Miwok 和 English 两种语言的。
比如在学习 Numbers 的页面中每行需显示该数字的 Miwok 和 English 版本,最终需要实现的样子应该类似这样:
实现步骤
问题分析
上次在实现一个页面中显示 1~n 的数字时使用到了 ArrayAdapter
,以及 ArrayList<String>
并让每个数字都作为一个列表项显示在Android 为我们提供的布局 文件android.R.layout.simple_list_item_1
当中。 ArrayAdapter
帮助我们管理 ArrayList 中的 String 对象,
点开该布局文件,会发现其实就只是一个 TextView
,其内容如下:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:minHeight="?android:attr/listPreferredItemHeightSmall" />
之前在创建 数据适配器 ArrayAdapter 实例的语句为:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, words);
ArrayAdapter 指定了泛型 String 表示这个适配器管理的数据为String类型,同时我们传入了一个 包含 String对象 的 列表数据 words
。
页面中显示的每个数字列表项,其实就是通过这个android.R.layout.simple_list_item_1
布局而创建的实例,因此 ArrayAdapter 默认管理的视图和对象为 单个 TextView 和 String。
而最终想要实现的效果为 每个列表项中 包含 Miwok 和 English 两个语言版本,为达到这一效果,就需要自定义列表项的布局文件,并自定义适配器 ,再让这个适配器管理自定义的列表项布局视图。
列表项布局
那么首先来定义列表项的布局文件,最终效果中的列表项分为两部分:Miwok 和 English ,那么可以考虑使用垂直布局的 LinearLayout
并嵌套 2个 TextView
来分别显示两种语言的单词版本。
创建列表项的布局文件(list_item.xml)如下:
使用 ViewGroup LinearLayout
作为列表项布局的基本视图,android:orientation="vertical"
使布局中的 两个 TextView
垂直排列,同时设置 TextView 的 layout_height
为 0dp
、layout_weight
为 1
让其高度均值分布。
数据来源
我们需要在每个列表项显示 2个 语言的字符串,因此可以考虑使用对象来封装每个列表项中需要显示的数据,可以更好的控制数据。
定义一个 Word
类型,并包含两个语言版本 的字符串 的属性 、一个 初始化 该类的构造函数 和 两个属性的 Getter
方法。
Word.java
:
public class Word {
/**
* Default(English) translation for the word
*/
private String defaultTranslation;
/**
* Miwok translation for the word
*/
private String miwokTranslation;
/**
* Create a new Word object.
*
* @param defaultTranslation is the word in a language that the user is already familiar with
* (such as English)
* @param miwokTranslation is the word in the Miwok language
*/
public Word(String defaultTranslation, String miwokTranslation) {
this.defaultTranslation = defaultTranslation;
this.miwokTranslation = miwokTranslation;
}
}
之后就可以 将一个包含 Word
对象的数组列表交给 适配器来管理。
自定义适配器
Android 提供的 ArrayAdapter 只能管理 单个 TextView 和 String 对象,而我们自己的列表项需要显示两条数据(一个Word对象),或许可以对现有的 ArrayAdapter 进行扩展,让它管理 自定义的 Word 对象 和 自定义的列表项布局 ,这就需要自定义适配器(继承基适配器)。
自定义的适配器需要继承 ArrayAdapter
接收一个泛型 Word
表示管理一个包含 Word
的数据列表。
自定义适配器 WordAdapter.java
如下