黎活明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 2017-04-24 17:14 luzhouxiaoshuai 阅读(455) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!