一、ListView理解
1、ListView是一种用来显示多个可滑动项(Item)列表的的ViewGroup
2、需要使用Adapter将集合数据和每一个Item所对应的布局动态适配到ListView中显示
3、显示列表: listView.setAdapter(adapter)
4、更新列表: adapter.notifyDataSetChanged()
二、Adapter
1、结构
1)ArrayAdapter: 显示最简单的列表(文本) 集合数据为List<String>或String[]
2)SimpleAdapter: 显示复杂的列表 集合数据必须是List<Map<String,Object>>类型
3)BaseAdapter: 显示复杂的列表 集合数据可以是任意类型的集合List<自定义类型>
4)SimpleCursorAdapter: 显示复杂的列表 集合数据是数据库查询结果集
2、ListView+ArrayAdapter 显示简单列表
context: 上下文件对象, 一般为Acivity对象
resource: Item的布局文件标识
objects: 需要显示的数据集合(Array或List)
1)新建一个ListView
2)创建item布局
3)准备数据设置Adapter显示列表
public class MainActivity extends Activity { //定义ListView private ListView lv_main; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化ListView lv_main = (ListView)findViewById(R.id.lv_main); //准备集合数据 String[] data = {"A","B","C","A","B","C","A","B","C","A","B","C","A","B","C"}; //准备ArrayAdapter对象 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item_array_adpter,data); //设置Adapter显示列表 lv_main.setAdapter(adapter); } }
4)运行结果
2、ListView + SimpleAdapter 显示复杂列表
context: 上下文件对象, 一般为Acivity对象
data: 需要显示的数据集合
resource: Item布局文件标识
from: map对象中的key的数组, 用于得到对应的value
to: Item布局文件中的子view的id的数组
1)因为结构和上面一样,所以直接上代码
public class MainActivity extends Activity { //定义ListView private ListView lv_main; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化ListView lv_main = (ListView)findViewById(R.id.lv_main); //准备集合数据 List<Map<String,Object>> data = new ArrayList<Map<String,Object>>(); Map<String,Object> map = new HashMap<String, Object>(); map.put("icon", R.drawable.tou); map.put("name", "name-1"); map.put("content", "name-1"); data.add(map); map = new HashMap<String, Object>(); map.put("icon", R.drawable.tou); map.put("name", "name-2"); map.put("content", "name-2"); data.add(map); map = new HashMap<String, Object>(); map.put("icon", R.drawable.tou); map.put("name", "name-3"); map.put("content", "name-3"); data.add(map); map = new HashMap<String, Object>(); map.put("icon", R.drawable.tou); map.put("name", "name-4"); map.put("content", "name-4"); data.add(map); map = new HashMap<String, Object>(); map.put("icon", R.drawable.tou); map.put("name", "name-5"); map.put("content", "name-5"); data.add(map); //from:map对象中的key的数组, 用于得到对应的value String[] from = {"icon","name","content"}; //to:Item布局文件中的子view的id的数组 int[] to = {R.id.ig_simple,R.id.tv1_simple,R.id.tv2_simple}; //准备SimplAdapter对象 SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item_simple_adapter, from, to); //设置Adapter显示列表 lv_main.setAdapter(adapter); } }
结果
3、ListView + BaseAdapter(抽象的) 显示复杂列表
BaseAdapter是实现了ListAdapter和SpinnerAdapter两个接口,当然它也可以直接给ListView和Spinner等UI组件直接提供数据。
int getCount();得到集合数据的个数,决定了能显示多少行
Object getItem(int position):根据position得到对应的数据对象
View getView(int position,View convertView,ViewGroup parrent){
//根据position返回对应的带数据的Item视图对象
position:下标
conbertView:可复用的Item视图对象
为null:没有可复用的,我们必须加载一个item的布局文件,并赋值给convertView
不为null:直接使用此视图对象
后面:找到子View,找到对应的数据,设置数据
parent:ListView
}
给ListView的Item设置监听
item的点击监听:listView.setOnItemClickListener(listener);
item的长按监听:listView.setOnItemLongClickListener(listener);
代码如下:
public class MainActivity extends Activity { //定义ListView private ListView lv_main; private List<ShowInfo> data; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化ListView lv_main = (ListView)findViewById(R.id.lv_main); //准备集合数据 data = new ArrayList<ShowInfo>(); data.add(new ShowInfo(R.drawable.tou, "name-1", "name-2")); data.add(new ShowInfo(R.drawable.tou, "name-2", "name-3")); data.add(new ShowInfo(R.drawable.ic_launcher, "name-3", "name-4")); data.add(new ShowInfo(R.drawable.tou, "name-4", "name-5")); data.add(new ShowInfo(R.drawable.tou, "name-5", "name-6")); //准备BaseAdapter对象 MyAdapter adapter = new MyAdapter(); //设置Adapter显示列表 lv_main.setAdapter(adapter); } //继承BaseAdapter class MyAdapter extends BaseAdapter{ @Override //返回集合数据数量 public int getCount() { return data.size(); } @Override //返回指定下标对应对像 public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return 0; } @Override /** * 返回指定下标所对应的item的view对象 * position:下标 * convertView:可复用的缓存Item视图对象 * parent:ListView对象 */ public View getView(int position, View convertView, ViewGroup parent) { //使用可复用的缓存优化ListView if(convertView==null){ //加载item的布局,得到view对象 convertView = View.inflate(MainActivity.this, R.layout.item_simple_adapter, null); } //根据position设置对应的数据 //得到当前的数据对象 ShowInfo si = data.get(position); ImageView iv = (ImageView)convertView.findViewById(R.id.ig_simple); TextView tv = (TextView)convertView.findViewById(R.id.tv1_simple); TextView tv1 = (TextView)convertView.findViewById(R.id.tv2_simple); iv.setImageResource(si.getId()); tv.setText(si.getName()); tv1.setText(si.getContent()); return convertView; } } }
注意ListView的优化问题
内存中最多存在n+1个convertView对象
只有当convertView为null时才去加载item的布局文件(当不断滑动加载item就会出现内存溢出的异常,程序强制停止)