//此系列博文是《第一行Android代码》的学习笔记,如有错漏,欢迎指正!

  ListView 这个控件比较复杂, 就是因为它有很多的细节可以优化,下面我们在试试提高它的运行效率:
一、提高ListView的运行效率:
  目前我们ListView的运行效率是很低的, 因为在LetterAdapter的getView()方法中每次都将布局重新加载了一遍,当 ListView快速滚动的时候这就会成为性能的瓶颈。

  仔细观察的话,可以发现getView()方法中还有一个 convertView 参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用。

 @Override
public View getView(int position, View convertView, ViewGroup parent) {
Letter letter = getItem(position); // 获取当前项的Letter实例
View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
} else {
view = convertView;
}
ImageView letterImage = (ImageView) view.findViewById(R.id.letter_image);
TextView letterName = (TextView) view.findViewById(R.id.letter_name);
letterImage.setImageResource(letter.getImageId());
letterName.setText(letter.getName());
return view;
}

  可以看到,现在我们在 getView()方法中进行了判断,如果 convertView 为空,则使用LayoutInflater 去加载布局,如果不为空则直接对 convertView 进行重用。这样就大大提高了ListView的运行效率,在快速滚动的时候也可以表现出更好的性能。此外,我们还可以继续优化:

 public class LetterAdapter extends ArrayAdapter<Letter> {
private int resourceId;
public LetterAdapter(Context context, int textViewResourceId, List<Letter> objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Letter letter = getItem(position); // 获取当前项的Letter实例
View view;
ViewHolder viewHolder;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
viewHolder = new ViewHolder();
viewHolder.letterImage = (ImageView) view.findViewById
(R.id.letter_image);
viewHolder.letterName = (TextView) view.findViewById
(R.id.letter_name);
view.setTag(viewHolder); // 将ViewHolder 存储在View
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag(); // 重新获取ViewHolder
}
viewHolder.letterImage.setImageResource(letter.getImageId());
viewHolder.letterName.setText(letter.getName());
return view;
} class ViewHolder {
ImageView letterImage;
TextView letterName;
}
}

  我们新增了一个内部类 ViewHolder,用于对控件的实例进行缓存。当 convertView为空的时候, 创建一个 ViewHolder 对象, 并将控件的实例都存放在 ViewHolder里, 然后调用 View的 setTag()方法,将 ViewHolder 对象存储在 View 中。当 convertView 不为空的时候则调用View的 getTag()方法, 把 ViewHolder重新取出。 这样所有控件的实例都缓存在了 ViewHolder里,就没有必要每次都用findViewById()方法来获取控件实例了。

二、ListView的点击事件:
  为ListView添加点击事件只需在主活动中为ListView注册监听器即可:

  @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initLetters(); // 初始化数据
LetterAdapter adapter = new LetterAdapter(MainActivity.this,
R.layout.letter_item, letterList);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Letter letter = letterList.get(position);
Toast.makeText(MainActivity.this, letter.getName(),
Toast.LENGTH_SHORT).show();
}
});
}

  可以看到,我们使用了 setOnItemClickListener()方法来为 ListView 注册了一个监听器,当用户点击了 ListView 中的任何一个子项时就会回调 onItemClick()方法, 在这个方法中可以通过 position 参数判断出用户点击的是哪一个子项,然后获取到相应的水果,并通过 Toast将字母显示出来。

  //End.

Android学习笔记(十一)——ListView的使用(下)的更多相关文章

  1. android学习笔记12——ListView、ListActivity

    ListView.ListActivity ==> ListView以垂直列表的形式显示所有列表项. 创建ListView的方式: 1.直接使用ListView创建 2.Activity继承Li ...

  2. Android学习笔记之ListView复用机制

    PS:满打满算,差不多三个月没写博客了...前一阵忙的不可开交...总算是可以抽出时间研究研究其他事情了... 学习内容: 1.ListView的复用机制 2.ViewHolder的概念 1.List ...

  3. Android学习笔记:ListView简单应用--显示文字列表

    在activity中的编写如下代码: final List<String> items = new ArrayList<String>(); //设置要显示的数据,这里因为是例 ...

  4. [Android学习笔记]使用ListView

    简单使用ListView 关键在于Adatper Adatper用来连接UI与数据源.Adapter既负责提供数据,又负责创建Item视图. 一般步骤: 1.创建list_item.xml,用来创建L ...

  5. 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView

    目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...

  6. 【转】Pro Android学习笔记(十二):了解Intent(下)

    解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键 ...

  7. 【转】Pro Android学习笔记(四):了解Android资源(下)

    处理任意的XML文件 自定义的xml文件放置在res/xml/下,可以通过R.xml.file_name来获取一个XMLResourceParser对象.下面是xml文件的例子: <rootna ...

  8. 【转】Pro Android学习笔记(七):了解Content Provider(下上)

    我们通过一个Content Provider小例子进行详细说明.数据源是一个SQLite数据库,名字为books.db,该数据库只含有一个表格,名字为books.表格中含有name,isbn,auth ...

  9. 【转】Pro Android学习笔记(二五):用户界面和控制(13):LinearLayout和TableLayout

    目录(?)[-] 布局Layout 线性布局LinearLayout 表格布局TableLayout 布局Layout Layout是容器,用于对所包含的view进行布局.layout是view的子类 ...

  10. 【转】 Pro Android学习笔记(二十):用户界面和控制(8):GridView和Spinner

    目录(?)[-] GridView Spinner GridView GridView是网格状布局,如图所示.在了解ListView后,很容易了解GridView.下面是例子的XML文件. <? ...

随机推荐

  1. java编程思想-java IO系统

    一.输入和输出 编程语言的I/O类库中常使用流这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象."流"屏蔽了实际的I/O设备中处理数据的细节. J ...

  2. 《Java疯狂讲义》(第3版)学习笔记 2 - Java语言的运行机制

    内容 1.高级语言的运行机制 2.Java 语言的运行机制 1.高级语言的运行机制 高级语言主要分为编译型语言和解释型语言两类. 编译型语言是指使用专门的编译器.针对特定平台(操作系统)将高级语言源代 ...

  3. MFC学习-第2,3课 MFC框架的运行机制

    转自:http://blog.163.com/zhigang0633@126/blog/static/38790491200822711526168/ 讲述MFC AppWizard的原理与MFC程序 ...

  4. log4net 记录到数据库和本地文件

    1)配置代码 <?xml version="1.0" encoding="utf-8" ?> <configuration> <c ...

  5. ci重定向

    ci重定向 对于/index.php/abc这种url,Apache和lighttpd会按"index.php?abc"来解释,而nginx会认为是请求名字是"index ...

  6. C#--网络流Stream、字节数组保存到字符串中

    第一种方法: HttpWebRequest httpwebr = (HttpWebRequest)HttpWebRequest.Create(rstr); httpwebr.Method = &quo ...

  7. python中配置文件写法

    import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) print(BASE_DIR) USE ...

  8. PHP页面跳转

    PHP页面跳转一.header()函数 header()函数是PHP中进行页面跳转的一种十分简单的方法.header()函数的主要功能是将HTTP协议标头(header)输出到浏览器. header( ...

  9. jquery.cookie使用方法

    jquery.cookie 使用方法 一个轻量级的 cookie 插件,可以读取.写入.删除 cookie . jquery.cookie.js 的配置 首先包含 jQuery 的库文件,在后面包含 ...

  10. C#通用类型转换 Convert.ChangeType

    ];         object innerValue = ChangeType(value, innerType);         return Activator.CreateInstance ...