黎活明8天快速掌握android视频教程--19_采用ListView实现数据列表显示

1、首先整个程序也是采用mvc的框架

DbOpenHelper 类
复制代码
package dB;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;


public class DbOpenHelper extends SQLiteOpenHelper
{

    public DbOpenHelper(Context context) {

        super(context, "wy.db", null, 2);
    }

    @Override
    public void onCreate(SQLiteDatabase db)
    {
     db.execSQL("CREATE TABLE person(personid integer primary key autoincrement, name varchar(20), phone VARCHAR(12) NULL)");





    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}
复制代码

数据库操作接口类:

我们可以采用下面的两种方式对数据库进行操作:

方式1:

复制代码
package service;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;
import java.util.List;

import dB.DbOpenHelper;
import domain.Person;


public class OtherPersonService {
private DbOpenHelper dbOpenHelper;

    public OtherPersonService(Context context) {
        this.dbOpenHelper = new DbOpenHelper(context);
    }
    public void save(Person person){
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("name",person.getName());
        values.put("phone",person.getPhone());
        db.insert("person",null,values);
    }
    /**
     * 删除记录
     * @param name 记录ID
     */
    public void delete(String name,String phone){
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
       /* db.execSQL("delete from person where name=? and phone=?", new Object[]{name,phone});*/
        db.delete("person", "name=? and phone= ?", new String[]{name ,phone});
    }
    /**
     * 更新记录
     * @param person
     */
    public void update(Person person,String name,String phone){
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
       /* db.execSQL("update person set name=?,phone=? where name=? and phone=?",
                new Object[]{person.getName(), person.getPhone(),name,phone});*/
        ContentValues values = new ContentValues();
        values.put("name",person.getName());
        values.put("phone",person.getPhone());
        db.update("person",values,"name=? and phone=?",new String[]{name ,phone});
    }
    /**
     * 查询记录
     * @param name 记录ID
     * @return
     */
    public Person find(String name,String phone){
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
       /* Cursor cursor = db.rawQuery("select * from person where name=? and phone = ?", new String[]{name, phone});*/
        Cursor  cursor = db.query("person",null,"name=? and phone=?",new String[]{name,phone},null,null,null);
        if(cursor.moveToNext()){
            int personid = cursor.getInt(cursor.getColumnIndex("personid"));
            String name1 = cursor.getString(cursor.getColumnIndex("name"));
            String phone1 = cursor.getString(cursor.getColumnIndex("phone"));
            return new Person( name1, phone1);
        }
        cursor.close();
        return null;
    }
    /**
     * 分页获取记录
     * @param offset 跳过前面多少条记录
     * @param maxResult 每页获取多少条记录
     * @return
     */
    public List<Person> getScrollData(int offset, int maxResult){
        List<Person> persons = new ArrayList<Person>();
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
       /* Cursor cursor = db.rawQuery("select * from person order by personid asc limit ?,?",*/
        Cursor  cursor = db.query("person",null,null,null,null,null,"personid asc",offset+ ","+ maxResult);
        while(cursor.moveToNext()){
            int personid = cursor.getInt(cursor.getColumnIndex("personid"));

            /*这里也可以写成
            *   String name = cursor.getString(1);
            String phone = cursor.getString(2);
             默认的表自带的id字段为0 ,name为第一个字段所有为1 ,phone为第二个字段为2*/
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String phone = cursor.getString(cursor.getColumnIndex("phone"));
            persons.add(new Person( name, phone));
        }
        cursor.close();
        return persons;
    }

    /**
     * 获取记录总数
     * @return
     */
    public long getCount(){
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        /*Cursor cursor = db.rawQuery("select count(*) from person", null);*/
        Cursor cursor = db.query("person", new String[]{"count(*)"}, null, null, null, null, null);
        cursor.moveToFirst();
        long result = cursor.getLong(0);//统计之后只有一个默认的字段,所以为0
        cursor.close();
        return result;
    }
}
复制代码

直接采用query的方式:

方式二:

复制代码
package service;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import dB.DbOpenHelper;
import domain.Person;


public class PersonService {
private DbOpenHelper dbOpenHelper;

    public PersonService(Context context) {
        this.dbOpenHelper = new DbOpenHelper(context);
    }
    public void save(Person person){
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        db.execSQL("insert into person(name, phone) values(?,?)",
                new Object[]{person.getName(), person.getPhone()});
    }
    /**
     * 删除记录
     * @param name 记录ID
     */
    public void delete(String name,String phone){
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        db.execSQL("delete from person where name=? and phone=?", new Object[]{name,phone});
    }
    /**
     * 更新记录
     * @param person
     */
    public void update(Person person,String name,String phone){
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        db.execSQL("update person set name=?,phone=? where name=? and phone=?",
                new Object[]{person.getName(), person.getPhone(),name,phone});
    }
    /**
     * 查询记录
     * @param name 记录ID
     * @return
     */
    public Person find(String name,String phone){
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select * from person where name=? and phone = ?", new String[]{name,phone});
        if(cursor.moveToNext()){
            int personid = cursor.getInt(cursor.getColumnIndex("personid"));
            String name1 = cursor.getString(cursor.getColumnIndex("name"));
            String phone1 = cursor.getString(cursor.getColumnIndex("phone"));
            return new Person( name1, phone1);
        }
        cursor.close();
        return null;
    }
    /**
     * 分页获取记录
     * @param offset 跳过前面多少条记录
     * @param maxResult 每页获取多少条记录
     * @return
     */
    public List<Person> getScrollData(int offset, int maxResult){
        List<Person> persons = new ArrayList<Person>();
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select * from person order by personid asc limit ?,?",
                new String[]{String.valueOf(offset), String.valueOf(maxResult)});
        while(cursor.moveToNext()){
            int personid = cursor.getInt(cursor.getColumnIndex("personid"));

            /*这里也可以写成
            *   String name = cursor.getString(1);
            String phone = cursor.getString(2);
             默认的表自带的id字段为0 ,name为第一个字段所有为1 ,phone为第二个字段为2*/
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String phone = cursor.getString(cursor.getColumnIndex("phone"));
            persons.add(new Person( name, phone));
        }
        cursor.close();
        return persons;
    }

    /**
     * 获取记录总数
     * @return
     */
    public long getCount(){
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select count(*) from person", null);
        cursor.moveToFirst();
        long result = cursor.getLong(0);//统计之后只有一个默认的字段,所以为0
        cursor.close();
        return result;
    }


    /*使用 SimpleCursorAdapter加装数据的时候,创建的数据库表的主键必须是_id,
    * 这里我们使用personid as _id,将创建表的主键personid变成_id
    * 返回cursor对象的时候,千万不能关闭cursor对象:cursor.close();*/
    public Cursor getScrollCursorData(int offset, int maxResult){
        List<Person> persons = new ArrayList<Person>();
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select personid as _id,name,phone from person order by personid asc limit ?,?",
                new String[]{String.valueOf(offset), String.valueOf(maxResult)});

        return cursor;//返回cursor对象之前,千万不能关闭cursor对象cursor.close();
    }

}
复制代码

在正式的代码中建议使用方式2的这种方式进行操作:

Person对象

复制代码
package domain;


public class Person
{

    private String name;
    private String phone;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }

    public Person(String name, String phone) {
        this.name = name;
        this.phone = phone;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}
复制代码

要显示数据需要新建立一个adapter对象PersonAdapter

复制代码
package adapter;

import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

import domain.Person;
import test.weiyuan.sqllite1.R;

public class PersonAdapter  extends BaseAdapter{
    private List<Person> persons;//要绑定的数据
    private int resource;//布局文件资源
    private Context context;//activity的上下文

    public PersonAdapter(List<Person> persons, int resource, Context context) {
        this.persons = persons;
        this.resource = resource;
        this.context = context;
    }

    //绑定数据的数据大小
    @Override
    public int getCount() {
        return persons.size();
    }

//显示数据在绑定数据List<Person>的位置,getItemAtPosition(position)来获得我们单击的item中的数据的时候,调用的就是
    //getItem(int position)函数来获得我们的数据
    @Override
    public Object getItem(int position)
    {
        return persons.get(position);
    }
//这个可以不管
    @Override
    public long getItemId(int position) {
        return position;
    }
//让数据如何在listview中显示出来
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
       /* if(convertView==null)
        {
          convertView = (View)LayoutInflater.from(context).inflate(resource,null);
        }
        Person person = persons.get(position);
        TextView name = (TextView)convertView.findViewById(R.id.name);
        TextView phone = (TextView)convertView.findViewById(R.id.phone);
        name.setText(person.getName());
        phone.setText(person.getPhone());*/
        //上面的代码不够优化,我们可以使用一个优化的方法给以解决
        TextView name = null;
        TextView phone = null;
        if(convertView==null)
        {
            convertView = (View)LayoutInflater.from(context).inflate(resource,null);
             name = (TextView)convertView.findViewById(R.id.name);
              phone = (TextView)convertView.findViewById(R.id.phone);
            ViewCache cache = new ViewCache();
            cache.name = name;
            cache.phone = phone;
            convertView.setTag(cache);

        }
        else
        {
            ViewCache cache = (ViewCache)convertView.getTag();
            name = cache.name;
            phone =cache.phone;
        }
        Person person = persons.get(position);

        name.setText(person.getName());
        phone.setText(person.getPhone());

        return convertView;
    }
    private  final class  ViewCache
    {
        public  TextView name;
        public  TextView phone;
    }

}
复制代码

接下来看看activity的代码如下:

显示数据的时候采用了下面的三种方式来加载数据的显示:

1、使用下面的三种方式类进行显示

复制代码
package test.weiyuan.sqllite1;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import adapter.PersonAdapter;
import dB.DbOpenHelper;
import domain.Person;
import service.PersonService;


public class MyActivity extends Activity {
    final static String TAG = "weiyuan";
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        listView = (ListView) this.findViewById(R.id.listView);
         /*创建数据库*/
        DbOpenHelper dbOpenHelper = new DbOpenHelper(MyActivity.this);
        dbOpenHelper.getWritableDatabase();
        /*在数据库中保存数据*/
        PersonService service = new PersonService(MyActivity.this);
        for (int i = 0; i < 20; i++) {
            service.save(new Person("weiyuan" + i, "12345" + i));
        }
        Log.i(TAG, "数据保存成功");
        //拖动Listview的时候顶部和底部不会出现阴影
        listView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        listView.setCacheColorHint(0);
        //在Listview中显示数据
        show();
       // show1();
        //show2();
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
               /* //调用SimpleCursorAdapter方式的时候,使用getItemAtPosition(position)函数返回List的数据集合中的元素是Cursor类型
               //parent就是我们单击的Listview
                ListView listView1 = (ListView)parent;
               Cursor cursor = (Cursor)listView1.getItemAtPosition(position);
                String name = cursor.getString(cursor.getColumnIndex("name"));
                String phone  =cursor.getString(cursor.getColumnIndex("phone"));
                Toast.makeText(MyActivity.this,name+","+phone,Toast.LENGTH_LONG).show();*/

         /*    *//*  调用自定义适配器的时候,getItemAtPosition(position)函数返回的是Person类型,
                getItemAtPosition(position)的实现是通过调用BaseAdapter类中的
                @Override
                public Object getItem(int position)
                {
                    return persons.get(position);
                }
                来实现的*//*
                ListView listView1 = (ListView)parent;
                Person person= (Person)listView1.getItemAtPosition(position);
                Toast.makeText(MyActivity.this,person.getName()+","+person.getPhone(),Toast.LENGTH_SHORT).show();*/

                //调用SimpleAdapter来显示ListView的数据,getItemAtPosition(position)返回的是HashMap的数据
                ListView listView1 = (ListView)parent;
                HashMap<String,String> map= (HashMap<String,String>)listView1.getItemAtPosition(position);
                String name =map.get("name");
                String phone = map.get("phone");
                Toast.makeText(MyActivity.this,name+","+phone,Toast.LENGTH_LONG).show();

             /*   总结:通过适配器加载数据的时候:getItemAtPosition(position)返回的就是适配器加载的数据集合中元素的类型,是集合中元素
                        的类型,我们来看一下:比如是SimpleAdapter来显示ListView的数据:
                SimpleAdapter simpleAdapter = new SimpleAdapter(this, datalist, R.layout.item,
                        new String[]{"name", "phone"}, new int[]{R.id.name, R.id.phone});
                其中datalist就是我们加载的数据集合,datalist是List<Map<String, String>>类型,该集合中的元素就是Map<String, String>类型;
                同理通过 SimpleCursorAdapter加载数据:
                SimpleCursorAdapter simplecursoradapter = new SimpleCursorAdapter(this, R.layout.item,
                        cursor, new String[]{"name", "phone"}, new int[]{R.id.name, R.id.phone});
                其中cursor就是加载的数据集合,该集合中的元素也是cursor类型。*/



            }
        });


    }
/*方法三:使用自定义的适配器来加载数据*/
    private void show2()
    {
        List<Person> persons = new ArrayList<Person>();
        PersonService service = new PersonService(MyActivity.this);
        persons = service.getScrollData(0, 20);
        PersonAdapter personAdapter = new PersonAdapter(persons,R.layout.item,this);
        listView.setAdapter(personAdapter);

    }

    /*通过 SimpleCursorAdapter加装游标适配器来显示数据
    * 这里是 new String[]{"name", "phone"}对应的是数据库表中的字段名称*/
    private void show1()
    {
        PersonService service = new PersonService(MyActivity.this);
        Cursor cursor = service.getScrollCursorData(0, 20);
        SimpleCursorAdapter simplecursoradapter = new SimpleCursorAdapter(this, R.layout.item,
                cursor, new String[]{"name", "phone"}, new int[]{R.id.name, R.id.phone});
        listView.setAdapter(simplecursoradapter);
    }

    /*方法一:通过适配器SimpleAdapter来显示ListView的数据*/
    private void show()
    {

        List<Person> persons = new ArrayList<Person>();
        PersonService service = new PersonService(MyActivity.this);
        persons = service.getScrollData(0, 20);
        List<Map<String, String>> datalist = new ArrayList<Map<String, String>>();
        for (Person person : persons) {
            HashMap<String, String> item = new HashMap<String, String>();
            item.put("name", person.getName());
            item.put("phone", person.getPhone());
            datalist.add(item);

        }
      /*  //这里new String[]{"name", "phone"}中的name 以及phone 要和  item.put("name", person.getName());
        item.put("phone", person.getPhone());中的对应起来*/
        SimpleAdapter simpleAdapter = new SimpleAdapter(this, datalist, R.layout.item,
                new String[]{"name", "phone"}, new int[]{R.id.name, R.id.phone});
        listView.setAdapter(simpleAdapter);


    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.my, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
复制代码

1 对应的这三种方式的总结:

调用SimpleCursorAdapter方式的时候,使用getItemAtPosition(position)函数返回List的数据集合中的元素是Cursor类型
//parent就是我们单击的Listview
ListView listView1 = (ListView)parent;
Cursor cursor = (Cursor)listView1.getItemAtPosition(position);
String name = cursor.getString(cursor.getColumnIndex("name"));
String phone =cursor.getString(cursor.getColumnIndex("phone"));
Toast.makeText(MyActivity.this,name+","+phone,Toast.LENGTH_LONG).show();

2、调用自定义适配器的时候,getItemAtPosition(position)函数返回的是Person类型,

ListView listView1 = (ListView)parent;
Person person= (Person)listView1.getItemAtPosition(position);
Toast.makeText(MyActivity.this,person.getName()+","+person.getPhone(),Toast.LENGTH_SHORT).show();

3、调用SimpleAdapter来显示ListView的数据,getItemAtPosition(position)返回的是HashMap的数据

ListView listView1 = (ListView)parent;
HashMap<String,String> map= (HashMap<String,String>)listView1.getItemAtPosition(position);
String name =map.get("name");
String phone = map.get("phone");
Toast.makeText(MyActivity.this,name+","+phone,Toast.LENGTH_LONG).show();

 

我们来看看界面的布局文件:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <!-- 标题 -->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="130dp"
            android:layout_height="wrap_content"
            android:text="姓名"
            />

        <TextView
            android:layout_width="250dp"
            android:layout_height="wrap_content"
            android:text="电话"
            />



    </LinearLayout>
    <!-- ListView控件 -->
    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/listView"
        />
</LinearLayout>
复制代码

adapter的布局文件

复制代码
<?xml version="1.0" encoding="utf-8"?>
<!--item -->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <!-- 名称 -->
    <TextView
        android:layout_width="130dp"
        android:layout_height="40dp"
        android:id="@+id/name"
        android:gravity="center_vertical"
        />
    <!-- 电话 -->
    <TextView
        android:layout_width="250dp"
        android:layout_height="40dp"
        android:id="@+id/phone"
        android:gravity="center_vertical"
        />

</LinearLayout>
复制代码

 

posted on   luzhouxiaoshuai  阅读(455)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示