当前位置:首页>> Android提高之SQLite分页表格

Android提高之SQLite分页表格

发布时间:2011-11-26作者:智汇小新

     本文实现并封装一个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 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";
 
 @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的源码:

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

公司简介

宜科(天津)电子有限公司是中国工业自动化的领军企业,于2003年在天津投资成立,销售和服务网络覆盖全国。作为中国本土工业自动化产品的提供商和智能制造解决方案的供应商,宜科在汽车、汽车零部件、工程机械、机器人、食品制药、印刷包装、纺织机械、物流设备、电子制造等诸多领域占据领先地位。宜科为智慧工厂的整体规划实施提供自系统层、控制层、网络层到执行层自上而下的全系列服务,产品及解决方案涵盖但不局限于云平台、MES制造执行系统、工业现场总线、工业以太网、工业无线通讯、机器人及智能设备组成的自动化生产线、自动化电气控制系统集成、智能物流仓储系统等,以实现真正智能化的生产制造,从而带来生产力和生产效率的大幅提升,以及对生产灵活性和生产复杂性的管理能力的大幅提升。多年来,宜科以创新的技术、卓越的解决方案和产品坚持不懈地为中国制造业的发展提供全面支持,并以出众的品质和令人信赖的可靠性、领先的技术成就、不懈的创新追求,在业界独树一帜。帮助中国制造业转型升级,加速智能制造进程,成为中国工业4.0智慧工厂解决方案当之无愧的践行者。

更多详情>>

联系我们

  • 联系人:章清涛
  • 热线:18611695135
  • 电话:
  • 传真:
  • 邮箱:18210150532@139.com

Copyright © 2015 ilinki.net Inc. All rights reserved. 智汇工业版权所有

电话:010-62314658 邮箱:service@ilinki.net

主办单位:智汇万联(北京)信息技术有限公司

京ICP备15030148号-1