首页 > 代码库 > java攻城狮之路(Android篇)--ListView与ContentProvider

java攻城狮之路(Android篇)--ListView与ContentProvider

一.ListView
1.三种Adapter构建ListView
ListView添加条目的时候, 可以使用setAdapter(ListAdapter)方法, 常用的ListAdapter有三种
BaseAdapter: 定义一个类继承BaseAdapter, 重写4个抽象方法, ListView的条目是由getView()方法构建出来的
SimpleAdapter: 创建SimpleAdapter对象时, 传入数据(List<Map<String, ?>>), 并指定数据的绑定关系
SimpleCursorAdapter: 创建SimpleCursorAdapter对象时, 传入一个Cursor, 指定数据的绑定关系

练习一:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.shellway.sqlite.MainActivity"     android:background="@color/abc_search_url_text_normal">    <ListView        android:id="@+id/id_LV"        android:layout_width="fill_parent"        android:layout_height="fill_parent"         /></RelativeLayout>
activity_main.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:textSize="20sp"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="1"        android:gravity="center"        android:text="1"        />    <TextView         android:id="@+id/nameTV"        android:textSize="20sp"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="2"        android:gravity="center"        android:text="张三"        />    <TextView         android:id="@+id/balanceTV"        android:textSize="20sp"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_weight="2"        android:gravity="center"        android:text="10000"        /></LinearLayout>
item.xml
package com.shellway.sqlite;import java.util.List;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;public class MainActivity extends ActionBarActivity {    private ListView lv;    private List<Person> persons;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        lv = (ListView) findViewById(R.id.id_LV); //获取ListView        PersonDAO dao = new PersonDAO(this);        persons = dao.findAll();        //给ListView添加Adapter,按照Adapter中的方法对ListView添加条目        lv.setAdapter(new myAdapter());             }    //定义Adapter,把每个Person对象生成一个条目,将所有条目装入ListView    private class myAdapter extends BaseAdapter{        @Override        public int getCount() {  //返回ListView中要装入的条目的数量            return persons.size();        }        @Override        public Object getItem(int position) {//点哪个条目就返回哪个条目的对象            return persons.get(position);        }        @Override        public long getItemId(int position) {//返回条目的ID            return position;        }        @Override        //返回指定位置上的View,会被添加到ListView中(即一个Person构建成一个View,然后挂到ListView)        public View getView(int position, View convertView, ViewGroup parent) {            Person p = persons.get(position);            //构建成一个条目(View),第三个参数是要挂到谁身上,这里写null它会自动返回到LListView中            View item = View.inflate(getApplicationContext(), R.layout.item, null);            TextView idTV = (TextView) item.findViewById(R.id.idTV);            TextView nameTV = (TextView) item.findViewById(R.id.nameTV);            TextView balanceTV = (TextView) item.findViewById(R.id.balanceTV);            idTV.setText(p.getId()+"");            nameTV.setText(p.getName());            balanceTV.setText(p.getBalance()+"");            return item;        }    }}
MainActivity

SimpleAdapter:

注意:若要修改成SimpleAdapter,不要忘记了修改AndroidManifest.xml中下面加粗位置部分。

        <activity            android:name=".SimpleAdapterActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>
package com.shellway.sqlite;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.TextView;public class SimpleAdapterActivity extends ActionBarActivity {    private ListView lv;    private List<Person> persons;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        lv = (ListView) findViewById(R.id.id_LV); //获取ListView        PersonDAO dao = new PersonDAO(this);        persons = dao.findAll();        List<Map<String, Object>> data = http://www.mamicode.com/new ArrayList<Map<String,Object>>();        for (Person p : persons) {            Map<String, Object> map = new HashMap<String, Object>();            map.put("id", p.getId());            map.put("name", p.getName());            map.put("balance", p.getBalance());            data.add(map);        }        lv.setAdapter(new SimpleAdapter(this, data , R.layout.item,                 new String[]{"id","name","balance"},                new int[]{R.id.idTV,R.id.nameTV,R.id.balanceTV}));        /**SimpleAdapter         * 参数1:上下文环境         * 参数2:数据,List<Map<String, Object>>每个Person装入一个Map,再将Map装入List         * 参数3:布局文件的资源id         * 参数4:Map中的Key,和参数5中的id对应,将指定key的value放入View中指定id对应和组件上         * 参数5:View中的id         */    }}
SimpleAdapter

SimpleCusorAdapter:

注意:使用SimpleCusorAdapter,在查询结果中要包含有“_id”这一列,这里我把id取别名为_id的方法解决。

    public Cursor queryAllCusor(){        SQLiteDatabase db = helper.getReadableDatabase();        //Cursor c = db.rawQuery("select id,name,balance from people", null);        Cursor c = db.query("people", new String[]{"id as _id","name","balance"}, null, null, null, null, null, null);        return c;    }
package com.shellway.sqlite;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.support.v4.widget.SimpleCursorAdapter;import android.support.v7.app.ActionBarActivity;import android.database.Cursor;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.TextView;public class SimpleCusorAdapterActivity extends ActionBarActivity {    private ListView lv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        lv = (ListView) findViewById(R.id.id_LV); //获取ListView        PersonDAO dao = new PersonDAO(this);        Cursor c = dao.queryAllCusor();        lv.setAdapter(new SimpleCursorAdapter(this, R.layout.item, c,                 new String[]{"_id","name","balance"},                 new int[]{R.id.idTV,R.id.nameTV,R.id.balanceTV}));        /**SimpleAdapter         * 参数1:上下文环境         * 参数2:布局文件的资源id         * 参数3:包含数据的游标         * 参数4:游标中的列名         * 参数5:条目中的组件的ID,游标中的数据就会放在对应的这些组件上         */    }}
SimpleCusorAdapterActivity

运行结果:

2.监听ListView的点击
调用ListView.setOnItemClickListener(OnItemClickListener)方法注册一个监听器
在监听器的onItemClick()方法中使用 parent.getItemAtPosition(position) 方法可以获取指定条目上的数据
BaseAdapter: 返回的就是自定义的getItem()方法中返回的数据
SimpleAdapter: 返回的是一个Map, 就是创建SimpleAdapter时List中的一个Map
SimpleCursorAdapter: 返回的是一个Cursor, 这个Cursor就是创建时传入的Cursor, 但是已经通过moveToPosition()方法指定到点击的索引了

二.内容提供者(ContentProvider)
1.什么是ContentProvider
ContentProvider可以用来把程序中的数据对外进行共享, 提供增删改查的方法
ContentProvider中可以注册观察者, 监听数据的变化
* 2.怎么创建
定义类继承ContentProvider, 实现抽象方法
在清单文件中注册
3.在手机上注册
将应用安装到手机上即可, 不用运行程序
* 4.怎么访问
获取解析器ContentResolver, 指定Uri
通过ContentResolver.insert(), delete(), update(), query()方法访问Uri关联的ContentProvider
5.Uri的处理
使用UriMatcher可以检查传入的Uri是否和指定的匹配
如果Uri带了id, 可以使用ContentUris获取id, 插入方法可以使用ContentUris给Uri加上id

java攻城狮之路(Android篇)--ListView与ContentProvider