Beta 1.0 中国家用电器研究院旗下新媒体 | 家电数码互动评测第一平台
查看: 293|回复: 0

【烙印教室】Android提高之SQLite分页表格

[复制链接]

Always_Online

  • TA的每日心情
    奋斗
    2016-3-5 21:07
  • 签到天数: 503 天

    [LV.9]以坛为家II




    【烙印教室】Android提高之SQLite分页表格 [复制链接]
    293 0
    打印 上一主题 下一主题
    2015-6-13 18:55:36
    上次讲的Android上的SQLite分页读取,只用文本框显示数据而已,这次就讲得更加深入些,实现并封装一个SQL分页表格控件,不仅支持分页还是以表格的形式展示数据。先来看看本文程序运行的动画:
    00.gif
    这个SQL分页表格控件主要分为“表格区”和“分页栏”这两部分,这两部分都是基于GridView实现的。网上介绍Android上实现表格的DEMO一般都用ListView。ListView与GridView对比,ListView最大的优势是格单元的大小可以自定义,可以某单元长某单元短,但是难于实现自适应数据表的结构;而GridView最大的优势就是自适应数据表的结构,但是格单元统一大小。。。对于数据表结构多变的情况,建议使用GridView实现表格。
    本文实现的SQL分页表格控件有以下特点:
    1.自适应数据表结构,但是格单元统一大小;
    2.支持分页;
    3.“表格区”有按键事件回调处理,“分页栏”有分页切换事件回调处理。
    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"
            androidrientation="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);
            }
    }
    复制代码


    免责声明                                                   
    本资源来自互联网,如有侵犯您的版权,请发邮件到765673603@qq.com联系我们将其删除。


    +10
    本版积分规则
    您需要登录后才可以回帖 登录 | 注册

    关闭

    站长推荐上一条 /1 下一条

    返回顶部 返回列表