`

Curso Adapter ListView ContextMenu

阅读更多

通过CursorAdapter在ListView中的数据呈现

在上一个例子中,我们可以对SQLite中的数据库进行增删改查,将数据读到游标Cursor中,然后一一读出。在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()的操作。具体实现不在此罗嗦,可以参见Android学习笔记(八):Activity-OpenMenu和LinearLayout

第二步:在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<Void, Void ,Cursor>{
    //步骤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.changeCursor(newCursor);//网上看到很多问如何更新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触发的菜单,见Android 学习笔记(二七):Menu。这里通过这个例子详细展开。实现场景:用户长按某个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;可以显示数据库的内容。

分享到:
评论

相关推荐

    Curso-CSS-SASS, Curso da Webschool.io sobre.zip

    Curso-CSS-SASS, Curso da Webschool.io sobre Curso-CSS-SASSCurso da Webschool.io sobre 。使用 Através destes recursos arquivos produzir e manter grandes CSS organiza

    curso_tour_of_heroes_api:Ruby on Rails作为API课程-源码

    英雄之旅API Ruby on Rails 6课程作为创建Heroes ...PostgreSQL(产品)运行项目的初始设置# clone the projectgit clone https://github.com/peimelo/curso_tour_of_heroes_api.git# enter the cloned directorycd ...

    Curso de Eletrônica

    【标题】"Curso de Eletrônica" 涵盖了电子学这一广泛的学科领域,旨在为学习者提供全面的电子技术知识。这个课程可能包括理论基础、实践技能以及使用多种软件和工具的训练。 在电子学的基础理论部分,学生可以...

    埃森哲2021年:Curso角钢

    【标题】:“埃森哲2021年:Curso角钢” 这个标题提及的是一个由全球知名咨询公司埃森哲(Accenture)在2021年提供的名为“Curso角钢”的课程。"Curso"在西班牙语中意为课程,而“角钢”通常指的是建筑行业中的一种...

    PyPI 官网下载 | curso-2.0.tar.gz

    《PyPI官网下载 | curso-2.0.tar.gz——深入理解Python库的发布与使用》 在Python的世界里,PyPI(Python Package Index)是最重要的软件仓库,它为全球的Python开发者提供了一个集中地,用来发布、分享和安装...

    Curso-Java-Completo:Exercíciospropostos durante o curso

    【标题】"Curso-Java-Completo:Exercíciospropostos durante o curso" 提供了一个关于Java编程的学习资源,这很可能是一个全面的Java教程,涵盖了从基础到高级的各种主题,并通过一系列的练习来强化学习者的编程...

    Curso C++_CursoC++_C++Curso_C++_

    本资源是一个以西班牙语讲解的C++编程课程,名为"Curso C++",旨在帮助学习者掌握C++这一强大的编程语言。C++是一种通用的、面向对象的编程语言,由Bjarne Stroustrup于1979年在贝尔实验室创建,作为C语言的增强版。...

    curso-tdd:Cursa de Desarrollo Para Asegurar la Calidad del软件

    Curso de desarrolloágil-4月edición :heart_decoration: :heart_decoration: :heart_decoration: :heart_decoration: :heart_decoration: 取消对任何人的照料,应将其保留下来,再将其保存到可可食品中。 从...

    curso-de-matlab-master.zip

    《MATLAB基础与实践——基于"curso-de-matlab-master.zip"的学习指南》 MATLAB,全称为“矩阵实验室”(Matrix Laboratory),是一款强大的数学计算软件,被广泛应用于科学计算、数据分析、算法开发以及图形可视化...

    Curso-Python:Curso Python

    Curso-Python Curso Python

    curso_java:Curso Java

    【标题】:“curso_java:Curso Java” 这个标题表明我们正在探讨的是一个关于Java编程的课程资源,"curso_java"可能是课程的代码库或者项目名称,而"Curso Java"直译为“Java课程”,暗示这是一个教育性的资料,...

    Curso-[removed]Curso de JS do Curso em视频

    【标题】:“Curso-[removed]Curso de JS do Curso em视频” 暗示这是一个关于JavaScript的在线课程,可能由“Curso em Vídeo”提供。这个课程可能包含一系列的视频教程,旨在帮助学习者掌握JavaScript这门编程语言...

    curso-php:curso de php do Curso Em视频

    【标题】:“curso-php:curso de php do Curso Em视频”是一个关于PHP编程语言的在线课程,由“Curso Em Video”提供。这个课程旨在教授初学者和有一定基础的学习者如何使用PHP进行网页开发和服务器端脚本。 【描述...

    primer_curso_de_cracking_crack_

    primer_curso_de_cracking_de_ricardo_narvaja_completo.

    Curso 在线 Python 基础知识库.zip

    Curso 在线 Python 基础知识库Python 基础知识数据科学学院 - Python 分析基础知识本教程是关于 Python 分析基础知识库的文章。您可以使用 Jupyter Notebooks 进行所有操作,但不要使用光标,而是要进行练习。...

    curso-de-python3-mundo-2:我从Curso emVídeo的Gustavo Guanabara教授的“ Curso de Python 3:Mundo 2”课程中学到的东西。 注意:这些是“ curso-de-python3-mundo-1”存储库的以下内容

    curso-de-python3-mundo-2 我是从Curso emVídeo的Gustavo Guanabara教授的“ Curso de Python 3:Mundo 2”课程中学到的。 注意:这些是“ curso-de-python3-mundo-1”存储库的以下内容。 截至2020年10月,此存储库...

    Curso para aprender desarrollo frontend Web con Python to desde cero. MoureDev 直接在 Twitch 上精心制作 .zip

    Sobre el curso非常重要在版本 0.4.0 中,Reflex 使用Radix(在Chakra中)与 UI 组件系统一起使用。十个版本的美国框架,你可以使用 podido cambiar ligeramente 的元素。建议修改原始项目的代码。 0.4.0 版本的一...

    Curso-JS:Curso JavaScript-Curso emVídeo

    本"Curso-JS:Curso JavaScript-Curso em Vídeo"课程专注于教授JavaScript的基础知识及实际应用,帮助初学者快速掌握这一强大的脚本语言。 在HTML(超文本标记语言)的基础上,JavaScript起到了桥梁的作用,它能够...

    Curso-PHP:Curso php

    【标题】:“Curso-PHP:Curso php”是一个关于PHP编程语言的在线课程资源,旨在帮助学习者掌握PHP的基础和进阶知识。 【描述】:“光标PHP Curso PHP”可能指的是该课程聚焦于PHP编程中的“光标”概念,通常在...

    Udemy:Curso de udemy

    【标题】:“Udemy:Curso de udemy”这一标题暗示了这是一个在Udemy平台上提供的在线课程,可能涵盖了各种主题和技术。Udemy是一个知名的在线学习平台,它提供了广泛的课程,包括编程、设计、营销等多个领域。在这...

Global site tag (gtag.js) - Google Analytics