服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android提高之SQLite分页表格实现方法

Android提高之SQLite分页表格实现方法

2021-03-06 23:31Android开发网 Android

这篇文章主要介绍了Android提高之SQLite分页表格实现方法,在项目开发中有很高的实用价值,需要的朋友可以参考下

继前一篇文章讲到android上的sqlite分页读取,其功能只是用文本框显示数据而已。本文就讲得更加深入些,实现并封装一个sql分页表格控件,不仅支持分页还是以表格的形式展示数据。

先来看看本文程序运行的动画如下图所示:

Android提高之SQLite分页表格实现方法

这个sql分页表格控件主要分为“表格区”和“分页栏”这两部分,这两部分都是基于gridview实现的。网上介绍android上实现表格的demo一般都用listview。listview与gridview对比,listview最大的优势是格单元的大小可以自定义,可以某单元长某单元短,但是难于实现自适应数据表的结构;而gridview最大的优势就是自适应数据表的结构,但是格单元统一大小。对于数据表结构多变的情况,建议使用gridview实现表格。

本文实现的sql分页表格控件有以下特点:

1.自适应数据表结构,但是格单元统一大小;

2.支持分页;

3.“表格区”有按键事件回调处理,“分页栏”有分页切换事件回调处理。

本文程序代码较多,可以到这里下载整个工程的源码:testsqlite.rar

items.xml的代码如下,它是“表格区”和“分页栏”的格单元实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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的代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
<?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的源码如下:

?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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的源码如下:

?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
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项目开发能起到参考借鉴作用。

延伸 · 阅读

精彩推荐
  • AndroidAndroid CardView+ViewPager实现ViewPager翻页动画的方法

    Android CardView+ViewPager实现ViewPager翻页动画的方法

    本篇文章主要介绍了Android CardView+ViewPager实现ViewPager翻页动画的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Abby代黎明9592022-03-02
  • AndroidAndroid实现固定屏幕显示的方法

    Android实现固定屏幕显示的方法

    这篇文章主要介绍了Android实现固定屏幕显示的方法,实例分析了Android屏幕固定显示所涉及的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    鉴客6182021-03-27
  • Android汇总Android视频录制中常见问题

    汇总Android视频录制中常见问题

    这篇文章主要汇总了Android视频录制中常见问题,帮助大家更好地解决Android视频录制中常见的问题,需要的朋友可以参考下...

    yh_thu5192021-04-28
  • AndroidAndroid中AsyncTask详细介绍

    Android中AsyncTask详细介绍

    这篇文章主要介绍了Android中AsyncTask详细介绍,AsyncTask是一个很常用的API,尤其异步处理数据并将数据应用到视图的操作场合,需要的朋友可以参考下...

    Android开发网7432021-03-11
  • AndroidAndroid程序设计之AIDL实例详解

    Android程序设计之AIDL实例详解

    这篇文章主要介绍了Android程序设计的AIDL,以一个完整实例的形式较为详细的讲述了AIDL的原理及实现方法,需要的朋友可以参考下...

    Android开发网4622021-03-09
  • AndroidAndroid编程解析XML方法详解(SAX,DOM与PULL)

    Android编程解析XML方法详解(SAX,DOM与PULL)

    这篇文章主要介绍了Android编程解析XML方法,结合实例形式详细分析了Android解析XML文件的常用方法与相关实现技巧,需要的朋友可以参考下...

    liuhe68810042021-05-03
  • AndroidAndroid实现Service获取当前位置(GPS+基站)的方法

    Android实现Service获取当前位置(GPS+基站)的方法

    这篇文章主要介绍了Android实现Service获取当前位置(GPS+基站)的方法,较为详细的分析了Service基于GPS位置的技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    Ruthless8332021-03-31
  • AndroidAndroid界面效果UI开发资料汇总(附资料包)

    Android界面效果UI开发资料汇总(附资料包)

    android ui界面设计,友好的界面会提高用户体验度;同时也增强了android ui界面设计的难度,本文提供了一些常用开发资料(有下载哦)感兴趣的朋友可以了解下...

    Android开发网4652021-01-03