Android提高第九篇之SQLite分页表格

Android提高第九篇之SQLite分页表格 

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

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

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

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

2.支持分页;

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

本文程序代码较多,可以到这里下载整个工程的源码:  testSQLite.rar (58.65 KB, 下载次数: 397)

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout android: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.         <TextView android: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的代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns: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.         <Button android:layout_height="wrap_content"
  6.                 android:layout_width="fill_parent" android:id="@+id/btnCreateDB"
  7.                 android:text="创建数据库"></Button>
  8.         <Button android:layout_height="wrap_content"
  9.                 android:layout_width="fill_parent" android:text="插入一串实验数据" android:id="@+id/btnInsertRec"></Button>
  10.         <Button android:layout_height="wrap_content" android:id="@+id/btnClose"
  11.                 android:text="关闭数据库" android:layout_width="fill_parent"></Button>
  12. </LinearLayout>
复制代码
演示程序testSQLite.java的源码:

  1. package com.testSQLite;
  2. import android.app.Activity;
  3. import android.database.Cursor;
  4. import android.database.SQLException;
  5. import android.database.sqlite.SQLiteDatabase;
  6. import android.os.Bundle;
  7. import android.util.Log;
  8. import android.view.View;
  9. import android.widget.Button;
  10. import android.widget.LinearLayout;
  11. import android.widget.Toast;
  12. public class testSQLite extends Activity {
  13.         GVTable table;
  14.         Button btnCreateDB, btnInsert, btnClose;
  15.         SQLiteDatabase db;
  16.         int id;//添加记录时的id累加标记,必须全局
  17.         private static final String TABLE_NAME = "stu";
  18.         private static final String ID = "id";
  19.         private static final String NAME = "name";
  20.         private static final String PHONE = "phone";
  21.         private static final String ADDRESS = "address";
  22.         private static final String AGE = "age";
  23.         
  24.         @Override
  25.         public void onCreate(Bundle savedInstanceState) {
  26.                 super.onCreate(savedInstanceState);
  27.                 setContentView(R.layout.main);
  28.                 btnCreateDB = (Button) this.findViewById(R.id.btnCreateDB);
  29.                 btnCreateDB.setOnClickListener(new ClickEvent());
  30.                 btnInsert = (Button) this.findViewById(R.id.btnInsertRec);
  31.                 btnInsert.setOnClickListener(new ClickEvent());
  32.                 btnClose = (Button) this.findViewById(R.id.btnClose);
  33.                 btnClose.setOnClickListener(new ClickEvent());
  34.                 table=new GVTable(this);
  35.                 table.gvSetTableRowCount(8);//设置每个分页的ROW总数
  36.                 LinearLayout ly = (LinearLayout) findViewById(R.id.MainLinearLayout);
  37.                 table.setTableOnClickListener(new GVTable.OnTableClickListener() {
  38.                         @Override
  39.                         public void onTableClickListener(int x,int y,Cursor c) {
  40.                                 c.moveToPosition(y);
  41.                                 String str=c.getString(x)+" 位置:("+String.valueOf(x)+","+String.valueOf(y)+")";
  42.                                 Toast.makeText(testSQLite.this, str, 1000).show();
  43.                         }
  44.                 });
  45.                 table.setOnPageSwitchListener(new GVTable.OnPageSwitchListener() {
  46.                         
  47.                         @Override
  48.                         public void onPageSwitchListener(int pageID,int pageCount) {
  49.                                 String str="共有"+String.valueOf(pageCount)+
  50.                                 " 当前第"+String.valueOf(pageID)+"页";
  51.                                 Toast.makeText(testSQLite.this, str, 1000).show();
  52.                         }
  53.                 });
  54.                 
  55.                 ly.addView(table);
  56.         }
  57.         class ClickEvent implements View.OnClickListener {
  58.                 @Override
  59.                 public void onClick(View v) {
  60.                         if (v == btnCreateDB) {
  61.                                 CreateDB();
  62.                         } else if (v == btnInsert) {
  63.                                 InsertRecord(16);//插入16条记录
  64.                                 table.gvUpdatePageBar("select count(*) from " + TABLE_NAME,db);
  65.                                 table.gvReadyTable("select * from " + TABLE_NAME,db);
  66.                         }else if (v == btnClose) {
  67.                                 table.gvRemoveAll();
  68.                                 db.close();
  69.                                 
  70.                         }
  71.                 }
  72.         }
  73.         
  74.         /**
  75.          * 在内存创建数据库和数据表
  76.          */
  77.         void CreateDB() {
  78.                 // 在内存创建数据库
  79.                 db = SQLiteDatabase.create(null);
  80.                 Log.e("DB Path", db.getPath());
  81.                 String amount = String.valueOf(databaseList().length);
  82.                 Log.e("DB amount", amount);
  83.                 // 创建数据表
  84.                 String sql = "CREATE TABLE " + TABLE_NAME + " (" + 
  85.                         ID        + " text not null, " + NAME + " text not null," +
  86.                         ADDRESS        + " text not null, " + PHONE + " text not null," +
  87.                         AGE        + " text not null "+");";
  88.                 try {
  89.                         db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
  90.                         db.execSQL(sql);
  91.                 } catch (SQLException e) {}
  92.         }
  93.         /**
  94.          * 插入N条数据
  95.          */
  96.         void InsertRecord(int n) {
  97.                 int total = id + n;
  98.                 for (; id < total; id++) {
  99.                         String sql = "insert into " + TABLE_NAME + " (" + 
  100.                         ID + ", " + NAME+", " + ADDRESS+", " + PHONE+", "+AGE
  101.                                         + ") values('" + String.valueOf(id) + "', 'man','address','123456789','18');";
  102.                         try {
  103.                                 db.execSQL(sql);
  104.                         } catch (SQLException e) {
  105.                         }
  106.                 }
  107.         }
  108.         
  109.         
  110. }
复制代码
分页表格控件GVTable.java的源码:

  1. package com.testSQLite;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import android.content.Context;
  5. import android.database.Cursor;
  6. import android.database.sqlite.SQLiteDatabase;
  7. import android.view.View;
  8. import android.widget.AdapterView;
  9. import android.widget.GridView;
  10. import android.widget.LinearLayout;
  11. import android.widget.SimpleAdapter;
  12. import android.widget.AdapterView.OnItemClickListener;
  13. public class GVTable extends LinearLayout {
  14.         protected GridView gvTable,gvPage;        
  15.         protected SimpleAdapter saPageID,saTable;// 适配器
  16.         protected ArrayList<HashMap<String, String>> srcPageID,srcTable;// 数据源
  17.         
  18.         protected int TableRowCount=10;//分页时,每页的Row总数
  19.         protected int TableColCount=0;//每页col的数量
  20.         protected SQLiteDatabase db;
  21.         protected String rawSQL="";
  22.         protected Cursor curTable;//分页时使用的Cursor
  23.         protected OnTableClickListener clickListener;//整个分页控件被点击时的回调函数
  24.         protected OnPageSwitchListener switchListener;//分页切换时的回调函数
  25.         
  26.         public GVTable(Context context) {
  27.                 super(context);
  28.                 this.setOrientation(VERTICAL);//垂直
  29.                 //----------------------------------------
  30.                 gvTable=new GridView(context);
  31.                 addView(gvTable, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
  32.                 LayoutParams.WRAP_CONTENT));//宽长式样
  33.                 
  34.                 srcTable = new ArrayList<HashMap<String, String>>();
  35.                 saTable = new SimpleAdapter(context,
  36.                                 srcTable,// 数据来源
  37.                                 R.layout.items,//XML实现
  38.                                 new String[] { "ItemText" },// 动态数组与ImageItem对应的子项
  39.                                 new int[] { R.id.ItemText });
  40.                 // 添加并且显示
  41.                 gvTable.setAdapter(saTable);
  42.                 gvTable.setOnItemClickListener(new OnItemClickListener(){
  43.                         @Override
  44.                         public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
  45.                                         long arg3) {
  46.                                 int y=arg2/curTable.getColumnCount()-1;//标题栏的不算
  47.                                 int x=arg2 % curTable.getColumnCount();
  48.                                 if (clickListener != null//分页数据被点击
  49.                                                 && y!=-1) {//点中的不是标题栏时
  50.                                         clickListener.onTableClickListener(x,y,curTable);
  51.                                 }
  52.                         }
  53.                 });
  54.                 
  55.                 //----------------------------------------
  56.                 gvPage=new GridView(context);
  57.                 gvPage.setColumnWidth(40);//设置每个分页按钮的宽度
  58.                 gvPage.setNumColumns(GridView.AUTO_FIT);//分页按钮数量自动设置
  59.                 addView(gvPage, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
  60.                 LayoutParams.WRAP_CONTENT));//宽长式样
  61.                 srcPageID = new ArrayList<HashMap<String, String>>();
  62.                 saPageID = new SimpleAdapter(context,
  63.                                 srcPageID,// 数据来源
  64.                                 R.layout.items,//XML实现
  65.                                 new String[] { "ItemText" },// 动态数组与ImageItem对应的子项
  66.                                 new int[] { R.id.ItemText });
  67.                 // 添加并且显示
  68.                 gvPage.setAdapter(saPageID);
  69.                 // 添加消息处理
  70.                 gvPage.setOnItemClickListener(new OnItemClickListener(){
  71.                         @Override
  72.                         public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
  73.                                         long arg3) {
  74.                                 LoadTable(arg2);//根据所选分页读取对应的数据
  75.                             if(switchListener!=null){//分页切换时
  76.                                     switchListener.onPageSwitchListener(arg2,srcPageID.size());
  77.                             }
  78.                         }
  79.             });
  80.         }
  81.         /**
  82.          * 清除所有数据
  83.          */
  84.         public void gvRemoveAll()
  85.         {
  86.                 if(this.curTable!=null)
  87.                         curTable.close();
  88.                 srcTable.clear();
  89.                 saTable.notifyDataSetChanged();
  90.         
  91.                 srcPageID.clear();
  92.                 saPageID.notifyDataSetChanged();
  93.                 
  94.         }
  95.         /**
  96.          * 读取指定ID的分页数据,返回当前页的总数据
  97.          * SQL:Select * From TABLE_NAME Limit 9 Offset 10;
  98.          * 表示从TABLE_NAME表获取数据,跳过10行,取9行
  99.          * @param pageID 指定的分页ID
  100.          */
  101.         protected void LoadTable(int pageID)
  102.         {
  103.                 if(curTable!=null)//释放上次的数据
  104.                         curTable.close();
  105.                 
  106.             String sql= rawSQL+" Limit "+String.valueOf(TableRowCount)+ " Offset " +String.valueOf(pageID*TableRowCount);
  107.             curTable = db.rawQuery(sql, null);
  108.             
  109.             gvTable.setNumColumns(curTable.getColumnCount());//表现为表格的关键点!
  110.             TableColCount=curTable.getColumnCount();
  111.             srcTable.clear();
  112.             // 取得字段名称
  113.             int colCount = curTable.getColumnCount();
  114.                 for (int i = 0; i < colCount; i++) {
  115.                         HashMap<String, String> map = new HashMap<String, String>();
  116.                         map.put("ItemText", curTable.getColumnName(i));
  117.                         srcTable.add(map);
  118.                 }
  119.                 
  120.                 // 列举出所有数据
  121.                 int recCount=curTable.getCount();
  122.                 for (int i = 0; i < recCount; i++) {//定位到一条数据
  123.                         curTable.moveToPosition(i);
  124.                         for(int ii=0;ii<colCount;ii++)//定位到一条数据中的每个字段
  125.                         {
  126.                                 HashMap<String, String> map = new HashMap<String, String>();
  127.                                 map.put("ItemText", curTable.getString(ii));
  128.                                 srcTable.add(map);
  129.                         }
  130.                 }
  131.                 
  132.                 saTable.notifyDataSetChanged();
  133.         }
  134.         /**
  135.          * 设置表格的最多显示的行数
  136.          * @param row 表格的行数
  137.          */
  138.         public void gvSetTableRowCount(int row)
  139.         {
  140.                 TableRowCount=row;
  141.         }
  142.         
  143.         /**
  144.          * 取得表格的最大行数        
  145.          * @return 行数
  146.          */
  147.         public int gvGetTableRowCount()
  148.         {
  149.                 return TableRowCount;
  150.         }
  151.         
  152.         /**
  153.          * 取得当前分页的Cursor
  154.          * @return 当前分页的Cursor
  155.          */
  156.         public Cursor gvGetCurrentTable()
  157.         {
  158.                 return curTable;
  159.         }
  160.                 
  161.         /**
  162.          * 准备分页显示数据
  163.          * @param rawSQL sql语句
  164.          * @param db 数据库
  165.          */
  166.         public void gvReadyTable(String rawSQL,SQLiteDatabase db)
  167.         {
  168.                 this.rawSQL=rawSQL;
  169.                 this.db=db;
  170.         }
  171.         
  172.         /**
  173.          * 刷新分页栏,更新按钮数量
  174.          * @param sql SQL语句
  175.          * @param db 数据库
  176.          */
  177.         public void gvUpdatePageBar(String sql,SQLiteDatabase db)
  178.         {
  179.                 Cursor rec = db.rawQuery(sql, null);
  180.                 rec.moveToLast();
  181.                 long recSize=rec.getLong(0);//取得总数
  182.                 rec.close();
  183.                 int pageNum=(int)(recSize/TableRowCount) + 1;//取得分页数
  184.                 
  185.                 srcPageID.clear();
  186.                 for (int i = 0; i < pageNum; i++) {
  187.                         HashMap<String, String> map = new HashMap<String, String>();
  188.                         map.put("ItemText", "No." + String.valueOf(i));// 添加图像资源的ID
  189.                         srcPageID.add(map);
  190.                 }
  191.                 saPageID.notifyDataSetChanged();
  192.         }
  193.         //---------------------------------------------------------
  194.         /**
  195.          * 表格被点击时的回调函数
  196.          */
  197.         public void setTableOnClickListener(OnTableClickListener click) {
  198.                 this.clickListener = click;
  199.         }
  200.         
  201.         public interface OnTableClickListener {
  202.                 public void onTableClickListener(int x,int y,Cursor c);
  203.         }
  204.         //---------------------------------------------------------
  205.         /**
  206.          * 分页栏被点击时的回调函数
  207.          */
  208.         public void setOnPageSwitchListener(OnPageSwitchListener pageSwitch) {
  209.                 this.switchListener = pageSwitch;
  210.         }
  211.         public interface OnPageSwitchListener {
  212.                 public void onPageSwitchListener(int pageID,int pageCount);
  213.         }
  214. }
复制代码


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值