您的位置:首页 > 其它

GeekBand第二周 ListView(上)

2016-05-19 16:28 387 查看
第二周学习的是ListView,在各种app的使用很多,相关的内容也很多。需要好好学习。

使用ListView的步骤:

一、添加ListView控件,findViewById

二、适配器:需要context,list_item.xml,数据源。也是适配器在一个contex中如何将数据源和list_item.xml进行适配

三、listview绑定监听器

<!--
android:background="@color/red"   背景和分割线,都可以选择设置颜色和图片
android:divider="@color/white"   设置分割线颜色为透明,分割线消失
android:dividerHeight="1px"   分割线的高度,为0dp时分割线消失,
-->
<ListView
android:id="@+id/list_view"
android:background="@color/red"
android:divider="@color/white"
android:dividerHeight="1px"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>


第一步和第三步都很简单,今天主要介绍一下第二步,ListView中非常关键的三个Adapter,分别是ArrayAdapter,SimpleAdapter,BaseAdapter.

适配器的作用,就是把复杂的数据填充在指定的视图界面上。数据从数组,链表,集合和数据库等等。

第一个Adapter,ArrayAdapter,使用的是最简单的,用于绑定格式单一的数据。数据源是:集合和数组

需要:1.context 2.数据:一个数组 3.布局:android自带布局

/**
* 数据源:一个string数组
*/
private String[] names={"初音未来","叶萌君","辣小丫宫廷版","嗷大喵第三季","嗷大喵红包篇","想念熊喜欢你","长草颜团子日常","功夫熊猫重出江湖","蛋黄哥","阿狸"};
/**
* 参数1,context,参数2,android自带的一个item布局,参数3,string数组
*/
ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,names);


第二个Adapter ,是SimpleAdapter

需要: 1.context,2.数据:一个装有map的list,3.布局:自定义一个list_item.xml

// 准备一个list来存放数据
private List<Map<String,Object>> mHashMapArrayList=new ArrayList<>();
private SimpleAdapter mSimpleAdapter;
// 将图片资源打包成一个数组
private int[] mImages= { R.drawable.address_book,R.drawable.calendar, R.drawable.camera, R.drawable.clock,R.drawable.games_control,R.drawable.messenger,R.drawable.ringtone,R.drawable.settings, R.drawable.speech_balloon, R.drawable.weather};
//  将文本资源打包成一个数组
private String[] names={"初音未来","叶萌君","辣小丫宫廷版","嗷大喵第三季","嗷大喵红包篇","想念熊喜欢你","长草颜团子日常","功夫熊猫重出江湖","蛋黄哥","阿狸"};
/**
*  通过for循环将两个数组的数据放到一个map中,然后再添加到list中
* 一个map就相当于一个数据的item和视图item相对应。
*/
for(int i=0;i<names.length;i++){
Map<String ,Object> map=new HashMap<>();
//    此处可以放多个map,一个item里面有几个数据,控件,放几个map
map.put("name",names[i]);
map.put("image",mImages[i]);
mHashMapArrayList.add( map);
}
/**
* 参数1,context, 参数2,数据
* 参数3,自定义的item布局,一个imageview一个textview
* 参数4,和参数5是相对应的,一个是map键组成的数组,一个是item控件id组成的数组
* 注意:键的数据和控件一定要对应
*/
mSimpleAdapter=new SimpleAdapter(this,mHashMapArrayList,R.layout.list_item,
new String[]{"name","image"},new int[]                                                                                {R.id.list_item_name,R.id.list_item_image});


第三个 Adapter BaseAdapter

需要:1.context, 2.数据:list中放入Face类 ,3.布局:自定义item.xml

一个存储数据的类,里面的构造方法和set,get方法就不贴了。

public class Face {
private int image;
private String name;
private String introduce;
}


新建一个类,继承BaseAdapter

/**
* 此前都是在activity中直接操作,这次adapte是新建外部类继承BaseAdapter
*/
public class MyAdapter extends BaseAdapter {
private Context mContext;
//    用来将xml文件转为View对象,从而可以获取其控件,并设置数据
private LayoutInflater mLayoutInflater;
//    这个存储数据的list里面装的是Face类,你需要新建一个类,就是一条Item的数据
private ArrayList<Face>  mArrayList;
public MyAdapter(Context context,ArrayList<Face>  faces){
mContext=context;
mLayoutInflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mArrayList=faces;
}
@Override
public int getCount() {
return mArrayList.size();
}

@Override
public Object getItem(int position) {
return mArrayList.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

/**
* 最重要的一个方法,将一个item的xml转为view,通过view找到它的控件,将list中的数据设置给它
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=new ViewHolder();
if(convertView==null){
// 这个item布局是一个imageview,两个textview,一个button,位置随意。 button不需要find,设置数据,都是一样的
convertView=mLayoutInflater.inflate(R.layout.list_item,null);
viewHolder.imageView    = (ImageView)convertView.findViewById(R.id.list_item_image);
viewHolder.nameText     = (TextView) convertView.findViewById(R.id.list_item_name);
viewHolder.introduceText  = (TextView) convertView.findViewById(R.id.list_item_introduce);
viewHolder.loadButton       = (Button) convertView.findViewById(R.id.list_item_load);
convertView.setTag(viewHolder);
}else {
viewHolder= (ViewHolder) convertView.getTag();
}
viewHolder.imageView.setImageResource(mArrayList.get(position).getImage());
viewHolder.nameText.setText(mArrayList.get(position).getName());
viewHolder.introduceText.setText(mArrayList.get(position).getIntroduce());
return convertView;
}
class ViewHolder{
ImageView imageView;
TextView nameText;
TextView introduceText;
Button  loadButton;
}
}


在activity中操作

private MyAdapter mMyAdapter;
private ArrayList<Face> faces=new ArrayList<>();
/**
* 准备数据,for循环,建10个face对象,存进list中
*/
for(int i=0;i<10;i++){
Face face=new Face(R.drawable.address_book,"温暖调皮的小狐狸","阿狸");
faces.add(face);
}
//        参数1.context, 参数2,数据
mMyAdapter=new MyAdapter(this,faces);


可能BaseAdapter中的getView方法是比较难懂的。那它方法的第一步是通过一个InFlatre对象,将item的xml转换为View对象,然后第二步是通过这个View对象找到它的子控件对象,然后第三部给这些子控件设置属性显示到界面中(通过数据)。

那因为listview会有很多item,每个item需要adapter调用一次getView方法,创建一个View对象,必将占用很多内存,因此有做了相关的优化。

优化一,设置判断条件,convertView为空时,我们创建view对象,并setTag.当下次listview再次滑动这个item时,convertView不为空,我们就可以从getTag中取出,不用再次创建。

优化二、使用ViewHolder, 因为有了View对象,在findViewById()方法是一个树查找过程,耗时操作,也需要优化。方法是,在创建View对象,实例化每一个控件时,将其保存到ViewHolder对象中,然后setTag。在下次需要时,直接getTag取出就可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  listview adapter