传智播客:ListView案例-新闻客户端
通过模拟新闻客户端来学习使用复杂条目的 ListView。
一、编写布局
MainActivity 的布局非常简单,不再给出,只给出作为 ListView 的条目的布局,见【文件 1-23】。
【文件 1-23】 list_item.xml
1. encoding="utf-8"?>
2.
3. android:layout_width="match_parent"
4. android:layout_height="wrap_content" >
5.
6.
7. android:id="@+id/iv"
8. android:contentDescription="@null"
9. android:layout_width="100dp"
10. android:layout_height="70dp"
11. android:src="@drawable/ic_launcher"
12. />
13.
14. android:id="@+id/tv_title"
15. android:layout_marginLeft="5dp"
16. android:layout_toRightOf="@id/iv"
17. android:layout_width="wrap_content"
18. android:layout_height="wrap_content"
19. android:text="这是新闻的标题"
20. android:singleLine="true"
21. android:ellipsize="end"
22. />
23.
24. android:id="@+id/tv_desc"
25. android:layout_marginLeft="5dp"
26. android:layout_below="@id/tv_title"
27. android:layout_toRightOf="@id/iv"
28. android:layout_width="wrap_content"
29. android:layout_height="wrap_content"
30. android:text="这是新闻的描述"
31. android:textSize="12sp"
32. android:textColor="#999999"
33. android:maxLines="2"
34. android:ellipsize="end"
35. />
36.
37. android:id="@+id/tv_type"
38. android:layout_marginRight="5dp"
39. android:layout_alignParentRight="true"
40. android:layout_alignBottom="@id/iv"
41. android:layout_width="wrap_content"
42. android:layout_height="wrap_content"
43. android:text="专题"
44. android:textColor="#Ff0000"
45. android:textSize="12sp"
46. />
47.
48.
技能:
上面布局中使用到了 ImageView 控件,该控件用于显示图片,其 android:src="@drawable/ic_launcher"
属性指定了要显示的图片内容。
二、编写代码
【文件 1-24】 MainActivity.java
1. package com.itheima.android.superlistview;2.
3. importandroid.os.Bundle;
4. importandroid.app.Activity;
5. importandroid.view.View;
6. importandroid.view.ViewGroup;
7. importandroid.widget.BaseAdapter;
8. importandroid.widget.ImageView;
9. importandroid.widget.ListView;
10. import android.widget.TextView;
11.
12. /**
13. *
14. * @author wzy2015-10-24 复杂条目的 ListView
15. */
16. public classMainActivity extends Activity{
17.
18. private ListViewlistView;
19.
20. @Override
21. protected void onCreate(BundlesavedInstanceState){
22. super.onCreate(savedInstanceState);
23. setContentView(R.layout.activity_main);
24. listView=(ListView)findViewById(R.id.lv);
25. // 设置 Adapter
26. listView.setAdapter(new MyAdapter());
27. }
28.
29. private classMyAdapterextends BaseAdapter {
30.
31. @Override
32. publicintgetCount(){
33. // 模拟 1000 条数据
34. return1000;
35. }
36.
37. @Override
38. publicObjectgetItem(intposition){
39. returnnull;
40. }
41.
42. @Override
43. publiclonggetItemId(intposition){
44. return0;
45. }
46.
47. @Override
48. publicViewgetView(int position, View convertView, ViewGroup parent) {
49. ViewHolder holder;
50. if (convertView == null){
51. /*
52. * 使用 View 的 inflate 静态方法将一个 xml 布局文件填充为 View 对象
53. * 参数 1:上下文
54. * 参数 2:xml 布局文件的 id
55. * 参数 3:ViewGroup,如果不为 null 那么就将该布局挂载到 ViewGroup 树中
56. */
57. convertView=View.inflate(MainActivity.this, R.layout.list_item, null);
58. //每新创建一个条目,就创建一个 ViewHolder 类
59. holder=new ViewHolder();
60. /*
61. * 将 convertView 中子控件对象赋值给 ViewHolder 对应的成员变量,
62. * 这样就相当于将 convertView 的所有子控件都封装成了一个 ViewHolder 对象,
63. * 这样当需要 convertView 的子控件的时候就不需要再调用 findViewById 方法了,
64. * 因此该方法内部是递归操作,性能比较低
65. */
66. holder.iv =(ImageView) convertView.findViewById(R.id.iv);
67. holder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
68. holder.tv_desc =(TextView) convertView.findViewById(R.id.tv_desc);
69. holder.tv_type =(TextView) convertView.findViewById(R.id.tv_type);
70. /*
71. * 将封装好的 holder 对象作为 convertView 的属性,
72. * 只有这样拿到了 convertView,就能拿到 holder,
73. * 拿到了 holder 就拿到了里面的子控件,
74. * 从而避免了过度执行 findViewById 方法
75. *
76. */
77. convertView.setTag(holder);
78. }
79. //从 convertView 中获取 ViewHolder 对象
80. holder=(ViewHolder)convertView.getTag();
81. //给 holder 中的子控件赋值
82. switch(position% 4){
83. case 0:
91. case 2:
92. holder.iv.setImageResource(R.drawable.image2);
93. holder.tv_type.setText("跟帖");
94. break;
95. case 3:
96. holder.iv.setImageResource(R.drawable.image3);
97. holder.tv_type.setText("推广");
98. break;
99. default:
103. holder.tv_title.setText("这是标题" + position);
104. holder.tv_desc.setText("这是新闻的描述信息"+ position);
105.
106. returnconvertView;
107. }
108.
109. }
110. /*
111. * 定义一个静态类,该类的成员变量跟 ListView 条目中用到的控件类型一致,
112. * 目的是为了用该类将 ListView 中的控件封装起来,
113. * 然后将该类跟 ListView 的条目绑定起来,
114. * 目的是为了减少 findViewById 方法被调用次数
115. */
116. staticclass ViewHolder {
117. ImageView iv;
118. TextViewtv_title;
119. TextViewtv_desc;
120. TextViewtv_type;
121. }
122. }
123.
技能:
上面代码使用 ViewHolder 对 ListView 作了进一步的优化,其优化的核心思想是: findViewById 方法是一个内部递归遍历的方法,查找 view 比较耗时,因此我们应该尽量避免过多的使用该方法。
当第一次执行 findViewById 获取到子控件的时候,将这些子控件封装到 ViewHolder 中,然后再将ViewHolder 作为属性设置给 convertView,这样当 convertView 需要子控件的时候就不用执行 findViewById
了,而是直接找 ViewHolder 类就可以了。
本文来源:https://www.2haoxitong.net/k/doc/0b83a00232687e21af45b307e87101f69f31fb43.html
文档为doc格式