Android基础(四) ListView的使用
1.ListView的创建
XML配置:
在主界面main.xml中配置<ListView>标签
在res/layout/文件夹下创建一个新的xml文件,用于指定每个条目的布局
2.使用Java代码构建ListView
在Activity中使用Context.findViewById()获得ListView对象
3.为ListView对象设置适配器(Adapter)
BaseAdapter:直接创建SimpleAdapter对象,传入当前环境(Context),数据(List),布局文件(id),数据和布局文件的映射关系为(String[],int[])
SimpleAdapter:以List<Map<String,?>>的形式封装数据
SimpleCursorAdapter:直接创建SimpleCursorAdapter对象,传入当前环境(Context),布局文件(id),数据(Cursor),数据和布局文件的映射关系为(String[],int[])
4.为ListView设置点击条目的监听事件(OnItemClickListener)
调用ListView.setOnItemClickListener()方法为ListView添加一个OnItemClickListener,在onItemClick()方法中,使用parent.getItemAtPosition(position)方法可以获取到指定位置上的数据
BaseAdapter获取到的是自定义的getItem()方法返回的数据
SimpleAdapter获取到的是指定位置上的Map
SimpleCursorAdapter获取到的是一个已经move到指定位置的Cursor
布局main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/personLV" android:layout_width="fill_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout>
条目布局item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:padding="10dp" > <TextView android:id="@+id/idTV" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/di_text" android:textSize="20sp" /> <TextView android:id="@+id/nameTV" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/name_text" android:textSize="20sp" android:gravity="center" /> <TextView android:id="@+id/balanceTV" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/balance_text" android:textSize="20sp" android:gravity="right" /> </LinearLayout>
BaseAdapter的使用
public class BaseAdapterActivity extends Activity { private List<Person> persons; private PersonDao dao; MyBaseAdapter adapter = new MyBaseAdapter(); /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); dao = new PersonDao(this); persons = dao.queryAll(); // 创建ListView ListView personLV = (ListView) findViewById(R.id.personLV); // 给ListView添加适配器,适配器中做好了内存管理机制,但是需要手动创建视图 personLV.setAdapter(adapter); } private class MyBaseAdapter extends BaseAdapter { public int getCount() {// ListView中总共的条目数 return persons.size(); } public Object getItem(int position) {// 当点击某个条目时返回的数据 return persons.get(position); } public long getItemId(int position) {// 获取条目的id return position; } public View getView(final int position, View convertView, ViewGroup parent) {// 生成指定位置上的视图 System.out.println("position:" + position); // 根据item.xml生成一个View(Linerlayout),返回出去,自动添加到ListView中 /* * View view = View.inflate(getApplicationContext(), R.layout.item, * null); */ // 如果convertView为空,则创建新的View,如果不为空,则重新使用convertView。能够提高效率 View view = convertView == null ? View.inflate( getApplicationContext(), R.layout.item, null) : convertView; // 从创建出来的View(Linerlayout)中获取TextView // 此时View刚刚创建,从activity中是找不到的,所以不能使用this.findViewById(),而是view..findViewById() TextView idTV = (TextView) view.findViewById(R.id.idTV); TextView nameTV = (TextView) view.findViewById(R.id.nameTV); TextView balanceTV = (TextView) view.findViewById(R.id.balanceTV); // 获取指定位置上的Person Person p = persons.get(position); // 给TextView设置文本(注意:不能设置int型数据,如果id设置为int型,则会成为strings.xml中字符串的id,所以应设置字符串型) idTV.setText(p.getId() + ""); nameTV.setText(p.getName()); balanceTV.setText(p.getBalance() + ""); balanceTV.setOnClickListener(new OnClickListener() { public void onClick(View v) { Person person = persons.get(position);//最好在这里独立获取Person,如果将前面的Person定义为final的,则在引用的时候可能会出问题 person.setBalance(person.getBalance()+1);//点击时改变数据 dao.update(person);//更新数据库中的数据 adapter.notifyDataSetChanged();//刷新ListView } }); return view; } } }
SimpleAdapter的使用
public class SimpleAdapterActivity extends Activity { private List<Person> persons; private SimpleAdapter adapter; private PersonDao dao; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); dao = new PersonDao(this); persons = dao.queryAll(); // 创建ListView ListView personLV = (ListView) findViewById(R.id.personLV); List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();// 用于装载数据的集合,每个Map对应一个Person for (Person person : persons) {// 循环遍历Person集合,将Person装入Map中,然后装入data中 Map<String, Object> map = new HashMap<String, Object>(); map.put("id", person.getId()); map.put("name", person.getName()); map.put("balance", person.getBalance()); data.add(map); } adapter = new SimpleAdapter(this, data, R.layout.item, // 指定当前环境、数据和布局文件 new String[] { "id", "name", "balance" }, // Map中的key(指定数据来源) new int[] { R.id.idTV, R.id.nameTV, R.id.balanceTV }); personLV.setAdapter(adapter);// 指定输入要填充到哪里 // 给点击Item添加监听器 personLV.setOnItemClickListener(new MyOnItemClickListener()); } private class MyOnItemClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // c.moveToPosition(position);//将右边移动到点击的位置 Map<String, Object> map=(Map<String, Object>) parent.getItemAtPosition(position);// 获取指定item上的数据,,获取的是指定位置的Map。(因为此处没有定义Cursor) /*// 也可以通过当前的View来获取数据 System.out.println(((TextView) view.findViewById(R.id.nameTV)) .getText()); String name = (String) map.get("name");// 获取要显示的数据 Toast.makeText(getApplicationContext(), name, Toast.LENGTH_SHORT) .show();// 弹出要显示的数据*/ map.put("balance", (Integer)map.get("balance")-1); adapter.notifyDataSetChanged();//更新ListView //更新数据库 dao.update(new Person((Integer)map.get("id"),(String)map.get("name"),(Integer)map.get("balance"))); } } }
SimpleCursorAdapter的使用
public class SimpleCursorAdapterActivity extends Activity { private Cursor c; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //创建ListView ListView personLV = (ListView) findViewById(R.id.personLV); // 查询出所有数据 PersonDao dao = new PersonDao(this); c = dao.queryAllCusor(); // 给ListView添加适配器,适配器中做好了内存管理机制,但是需要手动创建视图 personLV.setAdapter(new SimpleCursorAdapter(this, R.layout.item, c, //指定当前环境、数据和布局 new String[]{"_id","name","balance"}, //游标中的列名,该adpter使用数据时,需要有_id字段,如果数据库中不存在_id字段,可以设置别名 new int[]{R.id.idTV,R.id.nameTV,R.id.balanceTV}));//要填充数据的目标 // 给点击Item添加监听器 personLV.setOnItemClickListener(new MyOnItemClickListener()); } private class MyOnItemClickListener implements OnItemClickListener{ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // c.moveToPosition(position);//将右边移动到点击的位置 Cursor c =(Cursor) parent.getItemAtPosition(position);//获取指定item上的数据,当无法获得Cursor时,可以使用该方法 //也可以通过当前的View来获取数据 System.out.println(((TextView) view.findViewById(R.id.nameTV)) .getText()); String balance = c.getString(c.getColumnIndex("balance"));//获取要显示的数据 Toast.makeText(getApplicationContext(), balance, Toast.LENGTH_SHORT).show();//弹出要显示的数据 } } }