一.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 = 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