Android提高之SQLite分页表格实现方法
程序员文章站
2022-05-16 12:27:25
继前一篇文章讲到android上的sqlite分页读取,其功能只是用文本框显示数据而已。本文就讲得更加深入些,实现并封装一个sql分页表格控件,不仅支持分页还是以表格的形式...
继前一篇文章讲到android上的sqlite分页读取,其功能只是用文本框显示数据而已。本文就讲得更加深入些,实现并封装一个sql分页表格控件,不仅支持分页还是以表格的形式展示数据。
先来看看本文程序运行的动画如下图所示:
这个sql分页表格控件主要分为“表格区”和“分页栏”这两部分,这两部分都是基于gridview实现的。网上介绍android上实现表格的demo一般都用listview。listview与gridview对比,listview最大的优势是格单元的大小可以自定义,可以某单元长某单元短,但是难于实现自适应数据表的结构;而gridview最大的优势就是自适应数据表的结构,但是格单元统一大小。对于数据表结构多变的情况,建议使用gridview实现表格。
本文实现的sql分页表格控件有以下特点:
1.自适应数据表结构,但是格单元统一大小;
2.支持分页;
3.“表格区”有按键事件回调处理,“分页栏”有分页切换事件回调处理。
本文程序代码较多,可以到这里下载整个工程的源码:http://xiazai.jb51.net/201408/yuanma/testsqlite(jb51.bet).rar
items.xml的代码如下,它是“表格区”和“分页栏”的格单元实现:
<?xml version="1.0" encoding="utf-8"?> <linearlayout android:id="@+id/linearlayout01" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:background="#555555" android:layout_height="wrap_content"> <textview android:layout_below="@+id/itemimage" android:text="textview01" android:id="@+id/itemtext" android:buffertype="normal" android:singleline="true" android:background="#000000" android:layout_width="fill_parent" android:gravity="center" android:layout_margin="1dip" android:layout_gravity="center" android:layout_height="wrap_content"> </textview> </linearlayout>
main.xml的代码如下:
<?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" android:id="@+id/mainlinearlayout"> <button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btncreatedb" android:text="创建数据库"></button> <button android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="插入一串实验数据" android:id="@+id/btninsertrec"></button> <button android:layout_height="wrap_content" android:id="@+id/btnclose" android:text="关闭数据库" android:layout_width="fill_parent"></button> </linearlayout>
演示程序testsqlite.java的源码如下:
package com.testsqlite; import android.app.activity; import android.database.cursor; import android.database.sqlexception; import android.database.sqlite.sqlitedatabase; import android.os.bundle; import android.util.log; import android.view.view; import android.widget.button; import android.widget.linearlayout; import android.widget.toast; public class testsqlite extends activity { gvtable table; button btncreatedb, btninsert, btnclose; sqlitedatabase db; int id;//添加记录时的id累加标记,必须全局 private static final string table_name = "stu"; private static final string id = "id"; private static final string name = "name"; private static final string phone = "phone"; private static final string address = "address"; private static final string age = "age"; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); btncreatedb = (button) this.findviewbyid(r.id.btncreatedb); btncreatedb.setonclicklistener(new clickevent()); btninsert = (button) this.findviewbyid(r.id.btninsertrec); btninsert.setonclicklistener(new clickevent()); btnclose = (button) this.findviewbyid(r.id.btnclose); btnclose.setonclicklistener(new clickevent()); table=new gvtable(this); table.gvsettablerowcount(8);//设置每个分页的row总数 linearlayout ly = (linearlayout) findviewbyid(r.id.mainlinearlayout); table.settableonclicklistener(new gvtable.ontableclicklistener() { @override public void ontableclicklistener(int x,int y,cursor c) { c.movetoposition(y); string str=c.getstring(x)+" 位置:("+string.valueof(x)+","+string.valueof(y)+")"; toast.maketext(testsqlite.this, str, 1000).show(); } }); table.setonpageswitchlistener(new gvtable.onpageswitchlistener() { @override public void onpageswitchlistener(int pageid,int pagecount) { string str="共有"+string.valueof(pagecount)+ " 当前第"+string.valueof(pageid)+"页"; toast.maketext(testsqlite.this, str, 1000).show(); } }); ly.addview(table); } class clickevent implements view.onclicklistener { @override public void onclick(view v) { if (v == btncreatedb) { createdb(); } else if (v == btninsert) { insertrecord(16);//插入16条记录 table.gvupdatepagebar("select count(*) from " + table_name,db); table.gvreadytable("select * from " + table_name,db); }else if (v == btnclose) { table.gvremoveall(); db.close(); } } } /** * 在内存创建数据库和数据表 */ void createdb() { // 在内存创建数据库 db = sqlitedatabase.create(null); log.e("db path", db.getpath()); string amount = string.valueof(databaselist().length); log.e("db amount", amount); // 创建数据表 string sql = "create table " + table_name + " (" + id + " text not null, " + name + " text not null," + address + " text not null, " + phone + " text not null," + age + " text not null "+");"; try { db.execsql("drop table if exists " + table_name); db.execsql(sql); } catch (sqlexception e) {} } /** * 插入n条数据 */ void insertrecord(int n) { int total = id + n; for (; id < total; id++) { string sql = "insert into " + table_name + " (" + id + ", " + name+", " + address+", " + phone+", "+age + ") values('" + string.valueof(id) + "', 'man','address','123456789','18');"; try { db.execsql(sql); } catch (sqlexception e) { } } } }
分页表格控件gvtable.java的源码如下:
package com.testsqlite; import java.util.arraylist; import java.util.hashmap; import android.content.context; import android.database.cursor; import android.database.sqlite.sqlitedatabase; import android.view.view; import android.widget.adapterview; import android.widget.gridview; import android.widget.linearlayout; import android.widget.simpleadapter; import android.widget.adapterview.onitemclicklistener; public class gvtable extends linearlayout { protected gridview gvtable,gvpage; protected simpleadapter sapageid,satable;// 适配器 protected arraylist<hashmap<string, string>> srcpageid,srctable;// 数据源 protected int tablerowcount=10;//分页时,每页的row总数 protected int tablecolcount=0;//每页col的数量 protected sqlitedatabase db; protected string rawsql=""; protected cursor curtable;//分页时使用的cursor protected ontableclicklistener clicklistener;//整个分页控件被点击时的回调函数 protected onpageswitchlistener switchlistener;//分页切换时的回调函数 public gvtable(context context) { super(context); this.setorientation(vertical);//垂直 //---------------------------------------- gvtable=new gridview(context); addview(gvtable, new linearlayout.layoutparams(layoutparams.fill_parent, layoutparams.wrap_content));//宽长式样 srctable = new arraylist<hashmap<string, string>>(); satable = new simpleadapter(context, srctable,// 数据来源 r.layout.items,//xml实现 new string[] { "itemtext" },// 动态数组与imageitem对应的子项 new int[] { r.id.itemtext }); // 添加并且显示 gvtable.setadapter(satable); gvtable.setonitemclicklistener(new onitemclicklistener(){ @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { int y=arg2/curtable.getcolumncount()-1;//标题栏的不算 int x=arg2 % curtable.getcolumncount(); if (clicklistener != null//分页数据被点击 && y!=-1) {//点中的不是标题栏时 clicklistener.ontableclicklistener(x,y,curtable); } } }); //---------------------------------------- gvpage=new gridview(context); gvpage.setcolumnwidth(40);//设置每个分页按钮的宽度 gvpage.setnumcolumns(gridview.auto_fit);//分页按钮数量自动设置 addview(gvpage, new linearlayout.layoutparams(layoutparams.fill_parent, layoutparams.wrap_content));//宽长式样 srcpageid = new arraylist<hashmap<string, string>>(); sapageid = new simpleadapter(context, srcpageid,// 数据来源 r.layout.items,//xml实现 new string[] { "itemtext" },// 动态数组与imageitem对应的子项 new int[] { r.id.itemtext }); // 添加并且显示 gvpage.setadapter(sapageid); // 添加消息处理 gvpage.setonitemclicklistener(new onitemclicklistener(){ @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { loadtable(arg2);//根据所选分页读取对应的数据 if(switchlistener!=null){//分页切换时 switchlistener.onpageswitchlistener(arg2,srcpageid.size()); } } }); } /** * 清除所有数据 */ public void gvremoveall() { if(this.curtable!=null) curtable.close(); srctable.clear(); satable.notifydatasetchanged(); srcpageid.clear(); sapageid.notifydatasetchanged(); } /** * 读取指定id的分页数据,返回当前页的总数据 * sql:select * from table_name limit 9 offset 10; * 表示从table_name表获取数据,跳过10行,取9行 * @param pageid 指定的分页id */ protected void loadtable(int pageid) { if(curtable!=null)//释放上次的数据 curtable.close(); string sql= rawsql+" limit "+string.valueof(tablerowcount)+ " offset " +string.valueof(pageid*tablerowcount); curtable = db.rawquery(sql, null); gvtable.setnumcolumns(curtable.getcolumncount());//表现为表格的关键点! tablecolcount=curtable.getcolumncount(); srctable.clear(); // 取得字段名称 int colcount = curtable.getcolumncount(); for (int i = 0; i < colcount; i++) { hashmap<string, string> map = new hashmap<string, string>(); map.put("itemtext", curtable.getcolumnname(i)); srctable.add(map); } // 列举出所有数据 int reccount=curtable.getcount(); for (int i = 0; i < reccount; i++) {//定位到一条数据 curtable.movetoposition(i); for(int ii=0;ii<colcount;ii++)//定位到一条数据中的每个字段 { hashmap<string, string> map = new hashmap<string, string>(); map.put("itemtext", curtable.getstring(ii)); srctable.add(map); } } satable.notifydatasetchanged(); } /** * 设置表格的最多显示的行数 * @param row 表格的行数 */ public void gvsettablerowcount(int row) { tablerowcount=row; } /** * 取得表格的最大行数 * @return 行数 */ public int gvgettablerowcount() { return tablerowcount; } /** * 取得当前分页的cursor * @return 当前分页的cursor */ public cursor gvgetcurrenttable() { return curtable; } /** * 准备分页显示数据 * @param rawsql sql语句 * @param db 数据库 */ public void gvreadytable(string rawsql,sqlitedatabase db) { this.rawsql=rawsql; this.db=db; } /** * 刷新分页栏,更新按钮数量 * @param sql sql语句 * @param db 数据库 */ public void gvupdatepagebar(string sql,sqlitedatabase db) { cursor rec = db.rawquery(sql, null); rec.movetolast(); long recsize=rec.getlong(0);//取得总数 rec.close(); int pagenum=(int)(recsize/tablerowcount) + 1;//取得分页数 srcpageid.clear(); for (int i = 0; i < pagenum; i++) { hashmap<string, string> map = new hashmap<string, string>(); map.put("itemtext", "no." + string.valueof(i));// 添加图像资源的id srcpageid.add(map); } sapageid.notifydatasetchanged(); } //--------------------------------------------------------- /** * 表格被点击时的回调函数 */ public void settableonclicklistener(ontableclicklistener click) { this.clicklistener = click; } public interface ontableclicklistener { public void ontableclicklistener(int x,int y,cursor c); } //--------------------------------------------------------- /** * 分页栏被点击时的回调函数 */ public void setonpageswitchlistener(onpageswitchlistener pageswitch) { this.switchlistener = pageswitch; } public interface onpageswitchlistener { public void onpageswitchlistener(int pageid,int pagecount); } }
希望本文所述实例对于大家进行android项目开发能起到参考借鉴作用。
上一篇: ai怎么设计靓丽的短发女孩头像?
推荐阅读
-
Android入门之ActivityGroup+GridView实现Tab分页标签的方法
-
Android提高之MediaPlayer播放网络音频的实现方法
-
Android提高之AudioRecord实现助听器的方法
-
Android提高之自定义Menu(TabMenu)实现方法
-
Android提高之SQLite分页表格实现方法
-
Android提高之ListView实现自适应表格的方法
-
Android提高之SQLite分页读取实现方法
-
Android提高之MediaPlayer播放网络视频的实现方法
-
Android入门之ActivityGroup+GridView实现Tab分页标签的方法
-
Android提高之自定义Menu(TabMenu)实现方法