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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。