设为首页 收藏本站
查看: 1428|回复: 0

[经验分享] Android提高第九篇之SQLite分页表格 .

[复制链接]

尚未签到

发表于 2016-12-1 09:29:36 | 显示全部楼层 |阅读模式
本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!

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

         这个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 plaincopy to clipboardprint?


  • <?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>  

  <?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的代码如下:
  
view plaincopy to clipboardprint?


  • <?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>  

  <?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的源码:
  
view plaincopy to clipboardprint?


  • 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) {  
  •             }  
  •         }  
  •     }  
  •       
  •       
  • }  

  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";@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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 {@Overridepublic 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的源码:
  
view plaincopy to clipboardprint?


  • 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);  
  •     }  
  • }  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-308024-1-1.html 上篇帖子: 如何访问android模拟器中应用的sqlite数据库 下篇帖子: Android游戏开发之数据库SQLite 详细介绍(十七)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表