上次讲的Android上的 SQLite分页读取 ,只用文本框显示数据而已,这次就讲得更加深入些,实现并封装一个SQL分页表格控件,不仅支持分页还是以表格的形式展示数据。先来看看本文程序运行的动画:

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

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

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

2.支持分页;

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

本文程序代码较多,可以到这里下载整个工程的源码:http://www.rayfile.com/files/72e78b68-f2e5-11df-8469-0015c55db73d/

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

view plain copy to clipboard print ?
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutandroid:id="@+id/LinearLayout01"
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="fill_parent"android:background="#555555"
  5. android:layout_height="wrap_content">
  6. <TextViewandroid:layout_below="@+id/ItemImage"android:text="TextView01"
  7. android:id="@+id/ItemText"android:bufferType="normal"
  8. android:singleLine="true"android:background="#000000"
  9. android:layout_width="fill_parent"android:gravity="center"
  10. android:layout_margin="1dip"android:layout_gravity="center"
  11. android:layout_height="wrap_content">
  12. </TextView>
  13. </LinearLayout>

main.xml的代码如下:

view plain copy to clipboard print ?
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"android:id="@+id/MainLinearLayout">
  5. <Buttonandroid:layout_height="wrap_content"
  6. android:layout_width="fill_parent"android:id="@+id/btnCreateDB"
  7. android:text="创建数据库"></Button>
  8. <Buttonandroid:layout_height="wrap_content"
  9. android:layout_width="fill_parent"android:text="插入一串实验数据"android:id="@+id/btnInsertRec"></Button>
  10. <Buttonandroid:layout_height="wrap_content"android:id="@+id/btnClose"
  11. android:text="关闭数据库"android:layout_width="fill_parent"></Button>
  12. </LinearLayout>

演示程序testSQLite.java的源码:

view plain copy to clipboard print ?
  1. packagecom.testSQLite;
  2. importandroid.app.Activity;
  3. importandroid.database.Cursor;
  4. importandroid.database.SQLException;
  5. importandroid.database.sqlite.SQLiteDatabase;
  6. importandroid.os.Bundle;
  7. importandroid.util.Log;
  8. importandroid.view.View;
  9. importandroid.widget.Button;
  10. importandroid.widget.LinearLayout;
  11. importandroid.widget.Toast;
  12. publicclasstestSQLiteextendsActivity{
  13. GVTabletable;
  14. ButtonbtnCreateDB,btnInsert,btnClose;
  15. SQLiteDatabasedb;
  16. intid;//添加记录时的id累加标记,必须全局
  17. privatestaticfinalStringTABLE_NAME="stu";
  18. privatestaticfinalStringID="id";
  19. privatestaticfinalStringNAME="name";
  20. privatestaticfinalStringPHONE="phone";
  21. privatestaticfinalStringADDRESS="address";
  22. privatestaticfinalStringAGE="age";
  23. @Override
  24. publicvoidonCreate(BundlesavedInstanceState){
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.main);
  27. btnCreateDB=(Button)this.findViewById(R.id.btnCreateDB);
  28. btnCreateDB.setOnClickListener(newClickEvent());
  29. btnInsert=(Button)this.findViewById(R.id.btnInsertRec);
  30. btnInsert.setOnClickListener(newClickEvent());
  31. btnClose=(Button)this.findViewById(R.id.btnClose);
  32. btnClose.setOnClickListener(newClickEvent());
  33. table=newGVTable(this);
  34. table.gvSetTableRowCount(8);//设置每个分页的ROW总数
  35. LinearLayoutly=(LinearLayout)findViewById(R.id.MainLinearLayout);
  36. table.setTableOnClickListener(newGVTable.OnTableClickListener(){
  37. @Override
  38. publicvoidonTableClickListener(intx,inty,Cursorc){
  39. c.moveToPosition(y);
  40. Stringstr=c.getString(x)+"位置:("+String.valueOf(x)+","+String.valueOf(y)+")";
  41. Toast.makeText(testSQLite.this,str,1000).show();
  42. }
  43. });
  44. table.setOnPageSwitchListener(newGVTable.OnPageSwitchListener(){
  45. @Override
  46. publicvoidonPageSwitchListener(intpageID,intpageCount){
  47. Stringstr="共有"+String.valueOf(pageCount)+
  48. "当前第"+String.valueOf(pageID)+"页";
  49. Toast.makeText(testSQLite.this,str,1000).show();
  50. }
  51. });
  52. ly.addView(table);
  53. }
  54. classClickEventimplementsView.OnClickListener{
  55. @Override
  56. publicvoidonClick(Viewv){
  57. if(v==btnCreateDB){
  58. CreateDB();
  59. }elseif(v==btnInsert){
  60. InsertRecord(16);//插入16条记录
  61. table.gvUpdatePageBar("selectcount(*)from"+TABLE_NAME,db);
  62. table.gvReadyTable("select*from"+TABLE_NAME,db);
  63. }elseif(v==btnClose){
  64. table.gvRemoveAll();
  65. db.close();
  66. }
  67. }
  68. }
  69. /**
  70. *在内存创建数据库和数据表
  71. */
  72. voidCreateDB(){
  73. //在内存创建数据库
  74. db=SQLiteDatabase.create(null);
  75. Log.e("DBPath",db.getPath());
  76. Stringamount=String.valueOf(databaseList().length);
  77. Log.e("DBamount",amount);
  78. //创建数据表
  79. Stringsql="CREATETABLE"+TABLE_NAME+"("+
  80. ID+"textnotnull,"+NAME+"textnotnull,"+
  81. ADDRESS+"textnotnull,"+PHONE+"textnotnull,"+
  82. AGE+"textnotnull"+");";
  83. try{
  84. db.execSQL("DROPTABLEIFEXISTS"+TABLE_NAME);
  85. db.execSQL(sql);
  86. }catch(SQLExceptione){}
  87. }
  88. /**
  89. *插入N条数据
  90. */
  91. voidInsertRecord(intn){
  92. inttotal=id+n;
  93. for(;id<total;id++){
  94. Stringsql="insertinto"+TABLE_NAME+"("+
  95. ID+","+NAME+","+ADDRESS+","+PHONE+","+AGE
  96. +")values('"+String.valueOf(id)+"','man','address','123456789','18');";
  97. try{
  98. db.execSQL(sql);
  99. }catch(SQLExceptione){
  100. }
  101. }
  102. }
  103. }

分页表格控件GVTable.java的源码:

view plain copy to clipboard print ?
  1. packagecom.testSQLite;
  2. importjava.util.ArrayList;
  3. importjava.util.HashMap;
  4. importandroid.content.Context;
  5. importandroid.database.Cursor;
  6. importandroid.database.sqlite.SQLiteDatabase;
  7. importandroid.view.View;
  8. importandroid.widget.AdapterView;
  9. importandroid.widget.GridView;
  10. importandroid.widget.LinearLayout;
  11. importandroid.widget.SimpleAdapter;
  12. importandroid.widget.AdapterView.OnItemClickListener;
  13. publicclassGVTableextendsLinearLayout{
  14. protectedGridViewgvTable,gvPage;
  15. protectedSimpleAdaptersaPageID,saTable;//适配器
  16. protectedArrayList<HashMap<String,String>>srcPageID,srcTable;//数据源
  17. protectedintTableRowCount=10;//分页时,每页的Row总数
  18. protectedintTableColCount=0;//每页col的数量
  19. protectedSQLiteDatabasedb;
  20. protectedStringrawSQL="";
  21. protectedCursorcurTable;//分页时使用的Cursor
  22. protectedOnTableClickListenerclickListener;//整个分页控件被点击时的回调函数
  23. protectedOnPageSwitchListenerswitchListener;//分页切换时的回调函数
  24. publicGVTable(Contextcontext){
  25. super(context);
  26. this.setOrientation(VERTICAL);//垂直
  27. //----------------------------------------
  28. gvTable=newGridView(context);
  29. addView(gvTable,newLinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
  30. LayoutParams.WRAP_CONTENT));//宽长式样
  31. srcTable=newArrayList<HashMap<String,String>>();
  32. saTable=newSimpleAdapter(context,
  33. srcTable,//数据来源
  34. R.layout.items,//XML实现
  35. newString[]{"ItemText"},//动态数组与ImageItem对应的子项
  36. newint[]{R.id.ItemText});
  37. //添加并且显示
  38. gvTable.setAdapter(saTable);
  39. gvTable.setOnItemClickListener(newOnItemClickListener(){
  40. @Override
  41. publicvoidonItemClick(AdapterView<?>arg0,Viewarg1,intarg2,
  42. longarg3){
  43. inty=arg2/curTable.getColumnCount()-1;//标题栏的不算
  44. intx=arg2%curTable.getColumnCount();
  45. if(clickListener!=null//分页数据被点击
  46. &&y!=-1){//点中的不是标题栏时
  47. clickListener.onTableClickListener(x,y,curTable);
  48. }
  49. }
  50. });
  51. //----------------------------------------
  52. gvPage=newGridView(context);
  53. gvPage.setColumnWidth(40);//设置每个分页按钮的宽度
  54. gvPage.setNumColumns(GridView.AUTO_FIT);//分页按钮数量自动设置
  55. addView(gvPage,newLinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
  56. LayoutParams.WRAP_CONTENT));//宽长式样
  57. srcPageID=newArrayList<HashMap<String,String>>();
  58. saPageID=newSimpleAdapter(context,
  59. srcPageID,//数据来源
  60. R.layout.items,//XML实现
  61. newString[]{"ItemText"},//动态数组与ImageItem对应的子项
  62. newint[]{R.id.ItemText});
  63. //添加并且显示
  64. gvPage.setAdapter(saPageID);
  65. //添加消息处理
  66. gvPage.setOnItemClickListener(newOnItemClickListener(){
  67. @Override
  68. publicvoidonItemClick(AdapterView<?>arg0,Viewarg1,intarg2,
  69. longarg3){
  70. LoadTable(arg2);//根据所选分页读取对应的数据
  71. if(switchListener!=null){//分页切换时
  72. switchListener.onPageSwitchListener(arg2,srcPageID.size());
  73. }
  74. }
  75. });
  76. }
  77. /**
  78. *清除所有数据
  79. */
  80. publicvoidgvRemoveAll()
  81. {
  82. if(this.curTable!=null)
  83. curTable.close();
  84. srcTable.clear();
  85. saTable.notifyDataSetChanged();
  86. srcPageID.clear();
  87. saPageID.notifyDataSetChanged();
  88. }
  89. /**
  90. *读取指定ID的分页数据,返回当前页的总数据
  91. *SQL:Select*FromTABLE_NAMELimit9Offset10;
  92. *表示从TABLE_NAME表获取数据,跳过10行,取9行
  93. *@parampageID指定的分页ID
  94. */
  95. protectedvoidLoadTable(intpageID)
  96. {
  97. if(curTable!=null)//释放上次的数据
  98. curTable.close();
  99. Stringsql=rawSQL+"Limit"+String.valueOf(TableRowCount)+"Offset"+String.valueOf(pageID*TableRowCount);
  100. curTable=db.rawQuery(sql,null);
  101. gvTable.setNumColumns(curTable.getColumnCount());//表现为表格的关键点!
  102. TableColCount=curTable.getColumnCount();
  103. srcTable.clear();
  104. //取得字段名称
  105. intcolCount=curTable.getColumnCount();
  106. for(inti=0;i<colCount;i++){
  107. HashMap<String,String>map=newHashMap<String,String>();
  108. map.put("ItemText",curTable.getColumnName(i));
  109. srcTable.add(map);
  110. }
  111. //列举出所有数据
  112. intrecCount=curTable.getCount();
  113. for(inti=0;i<recCount;i++){//定位到一条数据
  114. curTable.moveToPosition(i);
  115. for(intii=0;ii<colCount;ii++)//定位到一条数据中的每个字段
  116. {
  117. HashMap<String,String>map=newHashMap<String,String>();
  118. map.put("ItemText",curTable.getString(ii));
  119. srcTable.add(map);
  120. }
  121. }
  122. saTable.notifyDataSetChanged();
  123. }
  124. /**
  125. *设置表格的最多显示的行数
  126. *@paramrow表格的行数
  127. */
  128. publicvoidgvSetTableRowCount(introw)
  129. {
  130. TableRowCount=row;
  131. }
  132. /**
  133. *取得表格的最大行数
  134. *@return行数
  135. */
  136. publicintgvGetTableRowCount()
  137. {
  138. returnTableRowCount;
  139. }
  140. /**
  141. *取得当前分页的Cursor
  142. *@return当前分页的Cursor
  143. */
  144. publicCursorgvGetCurrentTable()
  145. {
  146. returncurTable;
  147. }
  148. /**
  149. *准备分页显示数据
  150. *@paramrawSQLsql语句
  151. *@paramdb数据库
  152. */
  153. publicvoidgvReadyTable(StringrawSQL,SQLiteDatabasedb)
  154. {
  155. this.rawSQL=rawSQL;
  156. this.db=db;
  157. }
  158. /**
  159. *刷新分页栏,更新按钮数量
  160. *@paramsqlSQL语句
  161. *@paramdb数据库
  162. */
  163. publicvoidgvUpdatePageBar(Stringsql,SQLiteDatabasedb)
  164. {
  165. Cursorrec=db.rawQuery(sql,null);
  166. rec.moveToLast();
  167. longrecSize=rec.getLong(0);//取得总数
  168. rec.close();
  169. intpageNum=(int)(recSize/TableRowCount)+1;//取得分页数
  170. srcPageID.clear();
  171. for(inti=0;i<pageNum;i++){
  172. HashMap<String,String>map=newHashMap<String,String>();
  173. map.put("ItemText","No."+String.valueOf(i));//添加图像资源的ID
  174. srcPageID.add(map);
  175. }
  176. saPageID.notifyDataSetChanged();
  177. }
  178. //---------------------------------------------------------
  179. /**
  180. *表格被点击时的回调函数
  181. */
  182. publicvoidsetTableOnClickListener(OnTableClickListenerclick){
  183. this.clickListener=click;
  184. }
  185. publicinterfaceOnTableClickListener{
  186. publicvoidonTableClickListener(intx,inty,Cursorc);
  187. }
  188. //---------------------------------------------------------
  189. /**
  190. *分页栏被点击时的回调函数
  191. */
  192. publicvoidsetOnPageSwitchListener(OnPageSwitchListenerpageSwitch){
  193. this.switchListener=pageSwitch;
  194. }
  195. publicinterfaceOnPageSwitchListener{
  196. publicvoidonPageSwitchListener(intpageID,intpageCount);
  197. }
  198. }

更多相关文章

  1. “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
  2. Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
  3. 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
  4. ListView怎么处理大量的加载数据;比如有10万条数据,你在ListView怎
  5. Android-Intent详解与汇总
  6. Android实现记事本小功能
  7. Android(安卓)应用程序之间数据共享—ContentResolver
  8. Android中实现SQLite数据库CRUD操作的两种方式
  9. Android系统显示原理简介

随机推荐

  1. Android(安卓)ndk r4b开发环境搭建
  2. andriod 4.0以上版本不调用onConfigratio
  3. Android(安卓)抽象回调函数以及接口回调
  4. coredump在Android上的应用
  5. Android(安卓)虚拟按键驱动实现
  6. android 信息(mms)的故事(五)-- 发彩信
  7. android支持有线网--网络上看到
  8. Android(安卓)源代码编后的目录分析
  9. android中实现返回首页功能
  10. android 存储简要分析