zoukankan      html  css  js  c++  java
  • Android增高第九篇之GridView和SQLite实现分页表格

     

     Android提高第九篇之GridView和SQLite实现分页表格
    http://blog.csdn.net/hellogv/archive/2010/11/18/6019301.aspx
    上次讲的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
    的代码如下,它是“表格区”和“分页栏”的格单元实现:

    items.xml

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

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

    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);  
        }  
    }  
  • 相关阅读:
    BZOJ3732: Network(Kruskal重构树)
    AtCoder Beginner Contest 103
    2018.7.21NOIP模拟赛?解题报告
    PE刷题记
    杜教筛入门
    浅谈积性函数的线性筛法
    BZOJ4916: 神犇和蒟蒻(杜教筛)
    BZOJ2818: Gcd(莫比乌斯反演)
    LD1-B(最短路径-SPFA)
    UVa 10837 A Research Problem 欧拉函数
  • 原文地址:https://www.cnblogs.com/a354823200/p/3919041.html
Copyright © 2011-2022 走看看