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閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容