Android应用界面开发
第二章学习
第二部分####
1.继续分析Adapter的常用类
上一篇文章使用了ArrayAdapte制作了一个只由简单的文字组成的ListView,那ArrayAdapter是不是只有简单显示一行文字的功能呢?答案是否定的。
public class ArrayAdapter extends BaseAdapter implements Filterable, ThemedSpinnerAdapter {...}
发现,既然ArrayAdapter是接受泛型的,那其实什么样的类都能传给它,并且它继承自BaseAdapter,可使用的方法很多。
包含泛型List的构造方法:
public ArrayAdapter(Context context, int resource, List objects)
其它上一篇都说了,这次不使用数组,而使用一个泛型集合List< T > objects,并且去掉了一个构造参数int textViewResourceId (也就是textView的ID),这次不只针对单行的文本,所以只有这个参数不够用呀,你当然也可以填满4个参数,默认值就为0,表示无。
自己思考后,画了2张图,原创的!
其实,在数据源中每一个object(包含各种Java类),在ListView中对应着每一个item(列表中的每一个横行)
而Java类中的对应的变量,则可以一 一对应与item布局文件中的各个属性。
来,编代码,存在一个Data类,表示每一个Item包含的内容。
public class Data {
private String Text; //需要显示的文字
private int ImageId; //需要显示的图片资源编号
public Data(String text, int imageId) {
Text = text;
ImageId = imageId;
}
public String getText() {
return Text;
}
public int getImageId() {
return ImageId;
}
}
接下来需要编写一个自定义ArrayAdapter< Data >类,用于处理Data变量与控件属性的关系。
public class DataAdapter extends ArrayAdapter {
int mResourceId;
public DataAdapter(Context context, int resource, List objects) {
super(context, resource, objects); //调用ArrayAdapter的构造方法
mResourceId = resource; //获取list的布局文件
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//重写getView方法
Data mData = getItem(position);
//获取此Data
ViewHolder mViewHolder;
if (convertView == null){
//如果view未被创建过,且缓存为空
mViewHolder = new ViewHolder();
convertView= LayoutInflater.from(getContext()).inflate(mResourceId,null);
//此时,将mResourceId转换成了View类
/*其实LayoutInflater.from(Context context)方法,就是包含下列参数的静态方法
/LayoutInflater LayoutInflater =(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
获得了系统的布局解析服务*/
//inflate的第一个参数是布局文件Id,第二个ViewGroup对象,在创建单独的view的时候,只需要填null
mViewHolder.textView = (TextView)convertView.findViewById(R.id.textView);
mViewHolder.image = (ImageView) convertView.findViewById(R.id.image);
//通过convertView找到其中的控件
convertView.setTag(mViewHolder);
//将ViewHolder类存储到已经实例化的convertView中
}else {
//如果convertView有值
mViewHolder = (ViewHolder) convertView.getTag();
//从convertView中拿到ViewHolder类,从而可以使用其中的对象
}
mViewHolder.textView.setText(mData.getText());
mViewHolder.image.setImageResource(mData.getImageId());
//通过实例化后的Data数据,获取相应函数,进行属性的赋值
return convertView;
}
class ViewHolder{
//创建一个类,用于保存实例化的对象
TextView textView;
ImageView image;
}
}
其中position是item的顺序编号,此编号与List< Data>中的Data位置相同
其它不难理解,在其中创建了一个内部类ViewHolder,因为调用getview方法时,不需要每次都创建textView等属性的实例,只需要第一次创建时,将实例创建在ViewHolder内部;利用View的setTag方法,可将一些类型的实例存储于其中,并随着view的传递而传递,在需要使用是,利用getTag方法取出。
贴上剩下的代码
Class FirstAty
public class FirstAty extends AppCompatActivity {
private ArrayList mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first_aty);
initData();
//初始化数据
DataAdapter DataAdapter = new DataAdapter(FirstAty.this,R.layout.list_layout,mList);
//实例化适配器
ListView listView = (ListView) findViewById(R.id.list_view);
//通过id实例化ListView
listView.setAdapter(DataAdapter);
//关联listView与适配器
}
private void initData() {
mList = new ArrayList<>();//创建数据源的容器
mList.add(new Data("camera",R.drawable.camera));
mList.add(new Data("games_control",R.drawable.games_control));
mList.add(new Data("ringtone",R.drawable.ringtone));
mList.add(new Data("settings",R.drawable.settings));
mList.add(new Data("speech_balloon",R.drawable.speech_balloon));
}
}
activity_first_aty.xml
list_layout.xml
这几个代码基本上也没变,我只是在工程目录下放置了一些图片,用于listview中显示,当然Data类与list_layout中的控件是一一对应的,可以添加其它两边都可适配的各类控件及属性。
运行效果如下
文章太长容易让人看不下去,今天就到这里吧。