Android实例:利用listview控件操作SQLite数据库

在本实例中,首先我们利用SQLiteOpenHelper类建立一个数据库,并写好增、删、查等方法,通过SimpleCursorAdapter连接listview实现数据库的增加、查询以及长按删除的功能。

Paste_Image.png

首先,我们先认识一下什么是SQLiteOpenHelper类。

Android为了操作SQlite数据库,提供了SQLiteDatabase类,其内封装了insert 、delete、update 、query 、执行SQL命令等操作。同时又为SQLiteDatabase提供了一个辅助类,SQLiteOpenHelper。它提供了两个重要的方法,分别是:

onCreate(SQLiteDatabase db):用户初次使用软件时生成数据库,一旦数据库存在则不会调用此方法。函数是在第一次创建数据库的时候执行的,仅仅生成DataBaseHelper对(SQLiteOpenHelper类型)的时候是不会调用该函数的,而只有当调用DataBaseHelper对象的getReadableDataBase时或者是调用了getWritableDataBase时,如果是第一次创建数据库,那么就一定会调用onCreate()函数。

onUpgrade(SQLiteDatabase db,int oldVersion,int vewVersion):用于升级软件时更新数据库表结构,如增加表、列字段等操作。

实现了这两个方法,就可以用它的getWritableDatabase()getReadableDatabase()来获得数据库(SQLiteDatabase 对象)。

如果用户需要升级数据库表结构,需要主动调用onUpgrade(SQLiteDatabase db,int oldVersion,int vewVersion),传入一个新的版本的号。

建立一个新数据库的代码如下:


package com.example.listview_sqlite_xu;

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteDatabase.CursorFactory;

import android.database.sqlite.SQLiteOpenHelper;

public class NewsSearchDatabaseHelper extends SQLiteOpenHelper {

final String SQL_CREATE_TABLE = "create table news_table (" +

"_id integer primary key autoincrement, " +

"news_tittle varchar(50), " +

"news_content varchar(5000))";
public NewsSearchDatabaseHelper(Context context, String name, int version) {
        super(context, name, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_TABLE);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        System.out.println("call update");
    }      
}

接下来我们建立MainActivity:

package com.example.listview_sqlite_xu;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class MainActivity extends Activity {

    private NewsSearchDatabaseHelper helper;    //数据库帮助类
    private EditText et_tittle;                 //输入新闻标题
    private EditText et_content;                //输入新闻内容
    private ListView listView;                                 //显示新闻列表
    ArrayList<HashMap<String, Object>> listData; //    key-value
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        helper = new NewsSearchDatabaseHelper(getApplicationContext(), "news", 1);             //创建一个名为“news”的数据库
        
        //初始化控件
        et_tittle = (EditText) findViewById(R.id.et_news_tittle);
        et_content = (EditText) findViewById(R.id.et_news_content);
        listView = (ListView) findViewById(R.id.lv_news);
        listView.setOnCreateContextMenuListener(listviewLongPress);  
            // 设置长按事件  
           
        
    }

    /*
     * 按钮点击事件
     * 通过判断被点击的组件, 执行不同的操作
     */
    public void onClick(View view) {
        int id = view.getId();
        if(id==R.id.bt_add) 
         insertNews();
    
        else if(id== R.id.bt_query)
                queryNews();
            
        }

    /*
     * 刷新数据库列表显示
     * 1. 关联SimpleCursorAdapter与数据库表, 获取数据库表中的最新数据
     * 2. 将最新的SimpleCursorAdapter设置给ListView
     */
    private void inflateListView(Cursor cursor) {
    SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.item, cursor, new String[]{"news_tittle", "news_content"}, new int[]{R.id.tittle, R.id.content},1);
        
        listView.setAdapter(cursorAdapter);
    }
    
    /*
     * 插入新闻数据
     * 1. 从EditText组件中获取新闻的标题 和 新闻内容
     * 2. 获取数据库并从将 新闻标题 和 内容 插入到数据库中
     * 3. 重新查询数据库 获得Cursor对象
     * 4. 根据cursor对象创建SimpleCursorAdapter对象
     * 5. 将SimpleCursorAdapter设置给ListView, 显示新闻列表
     */
    private void insertNews() {
        String tittle = et_tittle.getText().toString();
        String content = et_content.getText().toString();
        
        helper.getReadableDatabase().execSQL("insert into news_table values(null, ?, ?)", new String[]{tittle, content});
        
        Cursor cursor = helper.getReadableDatabase().rawQuery("select * from news_table", null);
        inflateListView(cursor);           //刷新listview
    }
    
    /*
     * 删除新闻数据
     * 根据_id删除指定数据,并进行刷新
     */
    private boolean deleteNews(int _id) {
          String whereClause = "_id=?";  
          String[] whereArgs = new String[] { String.valueOf(_id) }; 
          try{
          helper.getReadableDatabase().delete("news_table", whereClause,whereArgs);
          Cursor cursor = helper.getWritableDatabase().rawQuery("select * from news_table", null);
          inflateListView(cursor);
          }catch (SQLException e) {  
              Toast.makeText(getApplicationContext(), "删除数据库失败",  
                      Toast.LENGTH_LONG).show();  
              return false;  
          }  
          return true;  
      } 
     

     
    //长按listview删除item     
    OnCreateContextMenuListener listviewLongPress = new OnCreateContextMenuListener() { 
          public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {  
                final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;  
                new AlertDialog.Builder(MainActivity.this)  
                       //  弹出窗口的最上头文字   
                        .setTitle("删除当前数据")  
                         //设置弹出窗口的图式   
                        .setIcon(android.R.drawable.ic_dialog_info)  
                        // 设置弹出窗口的信息   
                        .setMessage("确定删除当前记录")  
                        .setPositiveButton("是",  
                         new DialogInterface.OnClickListener() {  
                         public void onClick( DialogInterface dialoginterface, int i) {  
                                        // 获取位置索引  
                       int mListPos = info.position;  
                                        // 将listview中所有的数据都传入hashmap-listData中
                       Cursor c = helper.getReadableDatabase().rawQuery("select * from news_table", null);
                       int columnsSize = c.getColumnCount();
                        listData = new ArrayList<HashMap<String, Object>>();
                         while (c.moveToNext()) {  
                        HashMap<String, Object> map = new HashMap<String, Object>();  
                         for (int j = 0; j < columnsSize; j++) {  
                         map.put("_id", c.getString(0));  
                          map.put("news_tittle", c.getString(1));  
                          map.put("news_content", c.getString(2));  
                          }  
                          listData.add(map);  
                          }  
                           HashMap<String, Object> map = listData .get(mListPos);  
                           // 获取id  
                            int id = Integer.valueOf((map.get("_id").toString())); 
                          deleteNews(id);  
                             // 移除数据     
                          }  
                         }  
                     )  
               .setNegativeButton("否",  
                   new DialogInterface.OnClickListener() {  
                      public void onClick(  
                         DialogInterface dialoginterface, int i) {  
                                        // 什么也没做  
      
                                    }  
                                }).show();  
            }  
        };
      
        
    
    
    
    /*
     * 查询新闻
     * 1. 获取要查询的新闻标题 和 新闻内容
     * 2. 查询数据库 获取 Cursor, 并将Cursor转化为List<Map<String, String>>类型的集合
     * 3. 将集合放入bundle, Intent开启另一个Activity, 将bundle放入intent对象, 跳转Activity
     * 
     */
    private void queryNews() {
        String tittle = et_tittle.getText().toString();
        String content = et_content.getText().toString();
        
        Cursor cursor = helper.getReadableDatabase().rawQuery(
                "select * from news_table where news_tittle like ? and news_content like ?", 
                new String[]{"%" + tittle + "%", "%" + content + "%"});
        
        Bundle bundle = new Bundle();
        bundle.putSerializable("news", cursor2list(cursor));
        Intent intent = new Intent(this, SearchResultActivity.class);
        intent.putExtras(bundle);
        startActivity(intent);  
    }
    
    /*
     * 返回一个ArrayList集合, 这个集合中每个元素是一个Map集合, 每个Map集合有两个元素
     * 解析Cursor对象 : 
     * 1. cursor光标向下移动一格; 
     * 2. 创建一个HashMap对象
     * 3. 使用 cursor.getString(列标号)获取该行中某列值, 将这个值放入map中
     * 4. 将Map对象放入
     */
    private ArrayList<Map<String, String>> cursor2list(Cursor cursor) {
        ArrayList<Map<String, String>> list = new ArrayList<Map<String,String>>();
        
        //遍历Cursor
        while(cursor.moveToNext()){
            Map<String, String> map = new HashMap<String, String>();
            map.put("tittle", cursor.getString(1));
            map.put("content", cursor.getString(2));
            list.add(map);
        }
        return list;
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //释放数据库资源
        if(helper !=null)
            helper.close();
    }
}

新建一个Activity用来显示查询的结果:

package com.example.listview_sqlite_xu;

import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class SearchResultActivity extends Activity {

    private ListView listView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        //设置布局文件
        setContentView(R.layout.news_search_result);
        //初始化组件
        listView = (ListView) findViewById(R.id.lv_search_result);
        //获取跳转到该Activity的intent对象
        Intent intent = getIntent();
        //获取Intent对象所携带的数据
        Bundle bundle = intent.getExtras();
        //从Bundle中取出List<Map<String,String>>数据
        @SuppressWarnings("unchecked")
        List<Map<String, String>> list = (List<Map<String, String>>)bundle.getSerializable("news");
        
        SimpleAdapter adapter = new SimpleAdapter(
                getApplicationContext(),    //上下文对象
                list,                       //数据源
                R.layout.item,              //List显示布局
                new String[]{"tittle", "content"}, //List中map的键值
                new int[]{R.id.tittle, R.id.content});  //填充到的布局文件
        
        listView.setAdapter(adapter);
    }
    
}

main_activity的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" 
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="新闻标题" />
    
    <EditText 
        android:id="@+id/et_news_tittle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:hint="点击此处输入新闻标题"/>
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="新闻内容" />
    
    <EditText 
        android:id="@+id/et_news_content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:lines="2"
        android:hint="点击此处输入新闻内容"/>
    
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center_horizontal">
        <Button
            android:id="@+id/bt_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="添加新闻" />
        
        <Button
            android:id="@+id/bt_query"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="查找新闻" />
    </LinearLayout>
    
    <ListView 
        android:id="@+id/lv_news"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>

</LinearLayout>

listview的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView 
        android:id="@+id/tittle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp"
        android:textColor="#CC0000"
        />
    
    <TextView 
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="10dp"
        android:textColor="#00FF00"/>

</LinearLayout>

查询结果页面布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <ListView 
        android:id="@+id/lv_search_result"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
    
</LinearLayout>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容