通过CursorAdapter在ListView中的数据呈现

在Android中可以通过CursorAdapter直接将数据映射到ListView中,如下处理:

public
class Chapter22Test1 extends ListActivity{
    private SQLiteDatabase  db = null;
    private Cursor cursor = null;    
    private SimpleCursorAdapter adapter = null;

    protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
        db= (new Chapter22Db (getApplicationContext())).getWritableDatabase();    
        cursor =db.rawQuery("SELECT _id,Name,Weight from mytable ORDER BY Weight", null);
        //layout/chapter_22_test1.xml的Android XML文件定义了ListView中每个单元的排列方式,每个单元R.id.c22_name和R.id.c22_gravity都是TextView,分列左右
        adapter = new SimpleCursorAdapter(this,
                R.layout.chapter_22_test1, 
                cursor, 
                new String[]{"Name","Weight"},//游标数据的名称,实际是Table列名字
                new int[]{R.id.c22_name, R.id.c22_gravity});//对应的UI微件的id
        setListAdapter(adapter);
    }

    protected void onDestroy() {
        super.onDestroy();
        cursor.close();  //我们在onCreate()中没有关闭游标,因为需要和ListView进行数据关联,关闭curosr,会导致List无数据,故在最后释放资源
        db.close(); //断开和数据库的连接,释放相关资源
    }
}

更新数据(以增加为例)

我们要实现:通过Menu弹出菜单,有一个为增加,按之,弹出一个Dialog,可以在当中填入数据,按Dialog的确定按键,在SQLite数据库的表格mytable中加入相关的数据,并且同步ListView的显示。

第一步:建立OptionsMenu,里面有菜单“Add”,按键后,触发执行add()的操作。

第二步:在add()中,要完成弹出指定格式的 Dialog,采用AlertDialog的方式,Dialog的格式在xml中给出。处理方式之前都学过,但是没有合并使用的例子,包括Dialog的 格式,同ListView中自定义元素的格式一样,采用LayoutInflater。具体如下:

private
void add(){
    //步骤2.1:通过LayoutInflater从Android的XML文件中生成View
    LayoutInflater inflater = LayoutInflater.from(this);
    final View addView = inflater.inflate(R.layout.add_dialgo,null);

    //步骤2.2:通过AlertDialog弹出对话框,并且在第一个button,即PositiveButton监听事件,触发操作
    new AlertDialog.Builder(this)
    .setTitle("添加框")
    .setView(addView)
    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
        //我们希望得到addView中的数据,但是这个inner class,只能获取final的值,所以之前将addView设置为final,也就是所有addView的地址是固定的,而不是动态生成。
        public void onClick(DialogInterface dialog, int which) {
            EditText nameView = (EditText)addView.findViewById(R.id.c22_name);
            EditText weigthView = (EditText)addView.findViewById(R.id.c22_weight);
            // addData是下面步骤三,实现SQLite的数据更新和ListView的显示同步add(name,weight);
            addData(nameView.getText().toString(), new Float(weigthView.getText().toString()).floatValue());
        }
    })
    .setNegativeButton("取消",null)
    .show();
}

第三步:更新数据库和同步ListView,具体如下:

   
private void addData(String name ,float weight){
        /* 略去数据的判断,例如如果name一样,采用update的方式等等*/
        //步骤3.1 在数据库表格中添加数据
        ContentValues values = new ContentValues(2);
        values.put("Name",name);
        values.put("Weight",weight);
        db.insert("mytable","Name",values);
        //步骤3.2 同步ListView,更新游标的信息
        cursor.requery();
    }

异步后台同步数据

在上面的例子,貌似可以,而且的确是可以,但是在Android的API文档中,Cursor的方法requery()这样写道:This method is deprecated.Don't use this. Just request a new cursor, so you can do this asynchronously and update your list view once the new cursor comes back. 这提示我们风险的存在,如果数据量大,会导致重写读取的事件长(也就是requery()的执行时间)。虽然手机是人手操作,互动频率较低,在数据库数据
少的时候,例如上面的例子,我们仍然可以安全地使用requery。但是对于具有大量数据时,我们就需要修改上面的程序。

修订的方式步骤如下:1,通过后台线程来读取数据库;2、通过更换cursor来更新ListView,具体如下:

//步骤1:通过后台线程AsyncTask来读取数据库,放入更换Cursor
private class RefreshList extends AsyncTask { 
    //步骤1.1:在后台线程中从数据库读取,返回新的游标newCursor 
    protected Cursor doInBackground(Void... params) { 
        Cursor newCursor =  db.rawQuery("SELECT _id,Name,Weight from mytable ORDER BY Weight", null); 
        return newCursor; 
    } 
    //步骤1.2:线程最后执行步骤,更换adapter的游标,并奖原游标关闭,释放资源  
    protected void onPostExecute(Cursor newCursor) { 
        adapter. changeCursornewCursor); //网上看到很多问如何更新ListView的信息,采用CusorApater其实很简单,换cursor就可以 
        cursor.close(); 
        cursor = newCursor; 
    }         

//步骤2:取缔requrey的方式,采用后台线程更新形式 
private void addData(String name ,float weight){ 
      ... ... 
    //cursor.requery(); 
    new RefreshList().execute(); 
}

通过ContextMenu来删除ListView的数据

ContextMenu用户手指长按某个View触发的菜单。这里通过这个例子详细展开。实现场景:用户长按某个List元素,则弹出ContextMenu,选择菜单“Delete”,按下后,弹出AlertDialog,请用户再去确定是否删除,确定后将数据从SQLite中删除,并更新ListView的显示。具体如下:

    protected void onCreate(Bundle savedInstanceState) { 
        ... ... 
        //步骤1:向ListView注册Context Menu,当系统检测到用户长按某单元是,触发Context Menu弹出 
        registerForContextMenu(getListView()); 
    } 

    // 步骤2:创建ContextMenu同OptionMenu,用户长按元素后,会弹出菜单 
    public void onCreateContextMenu(ContextMenu menu, View v,  ContextMenuInfo menuInfo) { 
        menu.add(Menu.NONE,DELETE_ID,Menu.NONE,"Delete"); 
        super.onCreateContextMenu(menu, v, menuInfo); 
    } 

    //步骤 3: ContextMenu的触发操作,例子将触发delete() 
    public boolean onContextItemSelected(MenuItem item) { 
        switch(item.getItemId()){ 
        case DELETE_ID: 
            /* 在此处,我们关键引入 AdapterView.AdapterContextMenuInfo来获取单元的信息。在有三个重要的信息。 1、id:The row id of the item for which the context menu is being displayed ,在cursorAdaptor中,实际就是表格的_id序号; 2、position 是list的元素的顺序;3、view就可以获得list中点击元素的View,通过view可以获取里面的显示的信息   */ 
            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); 
            delete(info.id); 
            return true;
        default:
            break; 
        } 
         return super.onContextItemSelected(item); 
    } 

    //步骤4: 对触发弹框,和Add的相似,确定后,更新数据库和更新ListView的显示,其中getNameById是通过id查名字的方法,上次学习已有相类的例子,不再重复。值得注意的是,为了内部类中使用,delete的参数采用来final的形式。 
    private void delete(final long  rowId){ 
        if(rowId>0){ 
            new AlertDialog.Builder(this) 
            .setTitle("删除" + getNameById(rowId))
            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                      deleteData(rowId);
                }
            })
            .setNegativeButton("取消", null)
            .show(); 
        } 
    } 
     
    private void deleteData(long rowId){ 
        String[] str = {String.valueOf(rowId)};
        db.delete("mytable","_id=?",str); 
        new RefreshList().execute();  //采用后台方式,当然也可以用crusor.requery()来处理。 
    } 

通过模拟器的Console进行数据库操作

通过android-sdk-linux_x86/platform-tools目录下面有adb命令,使用adb shell,可提供模拟器的console窗口。数据库文件存放的位置为/data/data/your.app.package/databases/ your-db-name,进入相关的目录,可以使用#sqlite3
your-db-name,进入相关的数据库,可以在里面执行SQL语句,例如在整个例子中,通过#.schema来查看表格的格式,通过#select * from mytable;可以显示数据库的内容。 

时间: 2024-10-29 22:26:59

通过CursorAdapter在ListView中的数据呈现的相关文章

listview-关于listView中修改数据

问题描述 关于listView中修改数据 在做一个分组功能,listview上显示如图 想实现点击某一个item然后可以让用户修改组号.想法是点击到这个item到了另一个activity然后用户可以输入组号,然后返回用户修改的组号显示到原来的listView上 解决方案 在A.Activity中调用startActivityForResult()启动B.Activity后,再B.Activity中调用setResult() 方法后,A.Activity中的onResultActivity将会执行

listview 中数据库数据如何实时跟新

问题描述 listview 中数据库数据如何实时跟新 listview 中button,当点击button时跟新数据库数据, 是在自定义的sampleadapter中实现button的点击事件, 如何在点击后实时更新在listview上? 解决方案 实时数据库 解决方案二: notifyDataSetChanged 试试这个.

android listview-利用dialog来编辑listview中的数据

问题描述 利用dialog来编辑listview中的数据 package com.example.wightandheight; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.content.DialogInterface; import android.os.Bundle; import android.view.Layou

asp.net C#中ListView中数据导出到Excel实例

具体代码  代码如下 复制代码 private void 导出数据_Click(object sender, EventArgs e) { ExportToExecl(); } /// <summary> /// 执行导出数据 /// </summary> public void ExportToExecl() { System.Windows.Forms.SaveFileDialog sfd = new SaveFileDialog(); sfd.DefaultExt = &qu

将ListView中的内容导出到Word和Excel(新)

经常看到有网友发帖子询问如何将ListView中的内容导出到Excel或Word文档中,其实在BCB中用OLE技术来操作,并不复杂,大概是有的人懒的写吧,于是ccrun(老妖)花了点时间写了以下两个函数,实现了将本程序中ListView中内容导出到Excel文档和Word文档.看在写代码很辛苦的份上,请在转载时留下出处和原作者信息.Thank了.:D 如果您有好的想法,欢迎来信讨论: info@ccrun.com2005.10.13 v0.2+ 导出表格增加了标题一栏2005.10.12 v0.

服务器-谁能帮我解释下 这个代码 然后最好能让里面数据显示到listview中去

问题描述 谁能帮我解释下 这个代码 然后最好能让里面数据显示到listview中去 package com.httppost.main; import java.io.IOException; import java.io.InterruptedIOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.uti

android开发 listview-Android中,刷新ListView中的item导致ListView闪烁的解决方法

问题描述 Android中,刷新ListView中的item导致ListView闪烁的解决方法 如题,因为下载列表使用ListView实现的,所以必须实时更新ListView中的数据. 我采用的是Service+BroadcastReceiver的搭配.更新数据 在Activity里面再用notifySetDataChange()的方法对ListView进行动态刷新 但是发现一个很严重的问题.刷新的时候ListView有明显的闪烁. 求解决方法

如何从sqlite数据库中获取数据并显示在listview中?

问题描述 如何从sqlite数据库中获取数据并显示在listview中? 在登录页面后,我想在listview中把Apple显示成A,Boy显示成B等等,直到F.但是在程序中当我完全登录后,只有登录表成功创建,主菜单还是没有创建. 我想在test database中创建主菜单,然后我想从主菜单表(mainmenu table)中获取数据再显示在listview中. 我使用了下面的代码: if(username.length()>0&&password.length()>0) {

listview-点击ListView中条目后,刷新数据又返回到另一个条目的数据页面,怎么解决

问题描述 点击ListView中条目后,刷新数据又返回到另一个条目的数据页面,怎么解决 "点击ListView中条目后,刷新数据又返回到另一个条目的数据页面,怎么解决" 解决方案 清除原数据 解决方案二: 点击ListView中条目后,刷新数据又返回到另一个条目的数据页面,怎么解决 没看明白,怎么叫"刷新数据又返回到另一个条目的数据页面"? 建议把问题描述清楚些 解决方案三: 你可能是把要加载的数据放在onStart()方法中了,自己写个方法 放在oncreate中