Android自学——ListView

来源:互联网 发布:java怎么定义函数 编辑:程序博客网 时间:2024/06/08 16:24

ListView

​ 简介:ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,例如QQ的聊天记录等。所谓ListView也就是把具有相同布局的View给放在一个列表中展示而已

​ 使用ListView需要设置数据适配器Adapter,那什么是Adapter?

Adapter

An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.

一个Adapter是AdapterView视图与数据之间的桥梁,Adapter提供对数据的访问,也负责为每一项数据产生一个对应的View,后将View添加到ListView之中。

​ 可能直接这样说比较抽象,下面我们来举例说明一下:我们的手机通讯录就是一个简单的ListView。通讯录中有一条一条的联系人,每一个联系人都显示了相应的信息。现在通讯录比较简单,一般情况下只显示头像和姓名,以前还会显示手机号。每一条联系人的显示方式又是一个View。Adapter适配器将我们的信息(头像和姓名)根据一定的格式适配到每个View中,然后再将View添加到ListView中。大家根据这个例子可能对ListView控件和Adapter适配器以及他们之间的关系有了更好的理解了。

引用自http://www.cnblogs.com/gaobig/p/5016651.html

​ Adapter的构造函数有三个参数,分别代表当前上下文ListView子项布局的id要适配的数据

​ Android提供了很多适配器的实现类,我们这里先看看ArrayAdapter,其通过泛型来指定要适配的数据,比如我们要传入文本类型的数据:

private String[] data = {"a", "b", "c", "d", "e", "f", "g"};@Overrideprotected void onCreate(Bindle savedInstanceState) {  super.onCreate(saveInstanceState);  setContentView(R.id.activity_main);  //生成适配器实例,其中android.R.layout.simple_list_item_1是内置的简单布局,只含有一个TextView  ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,                                    android.R.layout.simple_list_item_1, data);  //生成ListView实例并载入适配器,  //其中R.id.lsit_view是自定义的ListView控件,该控件的用法和普通控件一样,这里就不写布局的代码了  ListView listView = (ListView) findViewById(R.id.lsit_view);  listView.setAdapter(adapter);}

​ Adapter中有一个getView()方法,每当子项被滚动到屏幕内的时候就会被ListView调用,用于干什么呢?当然是给当前的ListView的子项填进一个View,所以理所当然该方法返回的是View类型,因此如果要自定义ListView的子项布局的话,就可以自己新建一个View然后再用自定义的布局的控件跟View绑定到一起。

​ 那怎么绑定呢?我们看一下下面的例子:

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {  View view = LayoutInflater.from(getContext()).inflate(自定义子项布局的id, parent, false);  //对View中的控件进行设置,如:  TextView text = (TextView) view.findViewById(R.id.text);  text.setText("Hello");  return view;}

​ 这里有必要再解释一下LayoutInflater.from(getContext()).inflate()

LayoutInflater.from(getContext())可以构造出一个LayoutInflater对象,然后调用inflate()方法动态加载一个布局。inflate()方法有三个参数,,第一个参数是要填充的布局的id,第二个是父布局,第三个是是否把布局先添加到父布局再返回View。其中第三个参数省略的话默认为true:

inflate()方法第三个参数attachToRoot是true的话,那第一个参数的layout文件就会被填充并附加在第二个参数所指定的ViewGroup内。方法返回结合后的View,根元素是第二个参数ViewGroup。如果是false的话,第一个参数所指定的layout文件会被填充并作为View返回。这个View的根元素就是layout文件的根元素。不管是true还是false,都需要ViewGroup的LayoutParams来正确的测量与放置layout文件所产生的View对象。

作者:斯科特安链接:http://www.jianshu.com/p/41796f541e67來源:简书 著作权归作者所有。

​ 反正就是这样来给View加载布局的。

​ 然后就是要说说怎么自定义Adapter了,比如我们要在ListView中展示水果图片+名字的一组列表:

/*在定义Adapter之前先定义一个我们要展示的数据的类*/public class Fruit {  private String name;  private int imageId;  public Fruit(String name, int imagId) {    this.name = name;    this.imageId = imageId;  }  //此处省略两个成员变量的getter和setter方法  ...}
/*一般自定义Adapter可以选择继承ArrayAdapter,可以省下很多功夫*/public class FruitAdapter extends ArrayAdapter<Fruit> {  //resourceId是我们自定义的布局的id,在后面的getView()方法中需要用来给View加载布局  private int resourceId;  //第二个参数之所以叫textViewResourceId是因为我们继承的ArrayAdapter就是只用来展示TextView的  //我们自定义的时候就可以传入我们自定义的布局id  public FruitAdapter(Context context, int textViewResourceId, List<Fruit> objects) {    super(context, textViewResourceId, objects);    resourceId = textViewResourceId;  }  @Override  public View getView(int position, View convertView, ViewGroup parent) {    View view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);    //对View中的控件进行设置    TextView fruitName = (TextView) view.findViewById(R.id.name);    ImagView fruitImage = (ImageView) view.findViewById(R.id.image)    //getItem()方法是继承的ArrayAdapter中实现的方法,用于获取当前项的数据的实例    Fruit fruit = getItem(position);    fruitName.setText(fruit.getName());    fruitImage.setImageResource(fruit.getImageId);    return view;  }}

​ 自定义Adapter就是这样子了,应该没什么问题吧, 使用的话就跟ArrayAdapter的用法类似就可以了。

下面来学习怎么优化ListView的性能。

​ 首先由于每次子项进入怕屏幕的时候都会调用getView()方法,这样会导致每次都重新加载布局,当ListView快速滚动的时候性能就很差。

​ 仔细看Adapter的getView()方法,还会发现它的第二个参数convertView我们没有用到,这个参数就是用来缓存之前加载好的布局的。所以我们修改一下上面例子中getView()的内容:

@Override  public View getView(int position, View convertView, ViewGroup parent) {    View view;    if (convertView == null) {      view = = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);    } else {      view = convertView;    }    ...  }}

​ 其次由于getView()方法中每次都会调用findViewById()来获取控件实例,因此我们可以借助一个ViewHolder来进行优化:

@Override  public View getView(int position, View convertView, ViewGroup parent) {    Fruit fruit = getItem(position);    View view;    ViewHolder viewHolder;    if (convertView == null) {      view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);      viewHolder = new ViewHolder();      viewHolder.image = (ImageView) view.findViewById(R.id.iamge);      viewHolder.name = (TextView) view.findViewById(R.id.name);      //调用View的setTag()方法,该方法可以存储和View相关联的信息,然后调用View的getTag()可以读取信息      view.setTag(viewHolder);    } else {      view = convertView;      viewHolder = (ViewHolder) view.getTag();    }    viewHolder.name.setText(fruit.getName());    viewHolder.image.setImageResource(fruit.getImageId());    return view;  }}class ViewHolder {  ImageView image;  TextView name;}

​ 至此ListView的性能就很不错了。

ListView的每一个子项是可以点击的,下面学习一下如何注册点击事件。

ListView listView = (ListView) findViewById(R.id.list_View);listView.setAdapter(adapter);lsitView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  @Override  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {    Fruit fruit = fruitList.get(position);    Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();  }});

​ 其实跟Button和TextView等的监听器差不多,过一下就可以了。

​ ListView的学习就到这里了,初次写博客,有啥错误欢迎批评指出。

主要参考文献:郭霖《第一行代码(第2版)》

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 哈尔滨原房主户口不牵走怎么办 在亲戚家住怎么办居住证 按揭车押金不退怎么办 护照到期韩国签证没到期怎么办 日本签证银行流水不够怎么办 想去日本cm签证怎么办 护照在签让那里怎么办 泰国出境单丢了怎么办 居住证到期了忘记续签了怎么办 贵州交警app忘记密码怎么办 科一第一次没过怎么办 社保转移时学历信息不符怎么办 天津摇号密码忘了怎么办 摇号账号密码忘了怎么办 京牌车去外地没有保险标怎么办 车子被扣12分怎么办 不在北京工作了社保怎么办 5年身份证到期了怎么办 c1驾照剩1分怎么办 c1驾校扣12分怎么办 我驾照扣了12分怎么办 小米手环绑定不了怎么办 小区总有小年青骑摩托车扰民怎么办 摩托车行驶证副本丢了怎么办 摩托车驾照副本丢了怎么办 公司行驶证掉了怎么办 身份证外迁了过户的话怎么办 驾照体检报告丢了怎么办 常州医保卡丢了怎么办 驾驶证违章罚单丢了怎么办 身份证被别人办了信用卡怎么办 被别人办了信用卡怎么办 考驾照体检忘带身份证怎么办 c证扣12分怎么办新规 c照12分不够扣怎么办 扣了18分怎么办一次性 c照累计扣12分怎么办 车辆超速扣12分怎么办 一次超速扣12分怎么办 分扣了罚款未交怎么办 c照一次扣12分怎么办