zoukankan      html  css  js  c++  java
  • Android提高第九篇之GridView和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
    的代码如下,它是“表格区”和“分页栏”的格单元实现:

    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>    
    <?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的代码如下:

    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>    
    <?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的源码:

    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. }    
    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的源码:

    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. }    
  • 相关阅读:
    转载--gulp入门
    grunt之easy demo
    CentOS下vm虚拟机桥接联网
    Webstorm & PhpStorm
    2.使用Package Control组件安装
    virtual方法和abstract方法
    sql server 2008 跨服务器查询
    .NET开源项目常用记录
    vs2010 安装MVC 3.0
    所有运行命令指令大全
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3391388.html
Copyright © 2011-2022 走看看