Android开发

Android——ListView与数据库的结合

2016-10-23  本文已影响2482人  猪肉馅饺子

前言

ListView与数据库结合使用也是一种非常常见的手段。例如歌单的ListView,在我们重新启动应用的时候数据依旧存在,如下图:

具体实现

一、准备Activity和ListView

二、创建数据库

MySQLite(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        //this.mContext = context;    //自定义变量mContext 
}

其中形式参数的意义分别是:

所以也可以写成

MySQLite(Context context) {
      super(context, "music_msg.db", null, 1);
      this.mContext = context;
}

2、onCreate方法,用于创建数据库的表

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
      sqLiteDatabase.execSQL("create table music_msg(_id integer primary key autoincrement, singer varchar, songname varchar, url varchar)");
}

通过execSQL()方法执行SQL语句创建数据库的表
如果你不懂数据库,那你只需要改变下图框出的部分,第一个是表名,第二个是变量名和数据类型


3、onUpgrade方法,用于升级软件时更新数据库表结构,此方法在数据库的版本发生变化时会被调用

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    Toast.makeText(mContext, "onUpgrade", Toast.LENGTH_SHORT).show();
}

该方法这里不做演示分析,只是弹个Toast,想具体了解的可自行谷歌百度

三、关联ListView与数据库

SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags)

其中形式参数的意义分别是:

SimpleCursorAdapter mSimpleCursorAdapter = new SimpleCursorAdapter(MyListviewActivity.this, R.layout.listview_sql_item, null,
                new String[]{"songname", "singer"}, new int[]{R.id.songname, R.id.singer}, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

  mListView.setAdapter(mSimpleCursorAdapter);     //给ListView设置适配器
  refreshListview();      //自定义的方法,用于当数据列表改变时刷新ListView

四、刷新ListView(很关键)

Cursor mCursor = mDbWriter.query("music_msg", null, null, null, null, null, null);

上面说到要用数据库的对象去调用query方法,所以我们就得先拿到数据库的对象。数据库对象的获取有两个方法——getWritableDatabase() 和 getReadableDatabase()

要调用这两个方法,先再Activity的onCreate()方法里实例化之前自定义的MySQLite类,代码如下:

MySQLite mMySQLite = new MySQLite(this);
SQLiteDatabase mDbWriter = mMySQLite.getWritableDatabase();
SQLiteDatabase mDbReader = mMySQLite.getReadableDatabase();
//刷新数据列表
public void refreshListview() {
      Cursor mCursor = mDbWriter.query("music_msg", null, null, null, null, null, null);
      mSimpleCursorAdapter.changeCursor(mCursor);
}

五、增

//增
 public void insertData() {
       ContentValues mContentValues = new ContentValues();
       mContentValues.put("songname", mEt_songName.getText().toString().trim());
       mContentValues.put("singer", mEt_singer.getText().toString().trim());
       mDbWriter.insert("music_msg", null, mContentValues);
       refreshListview();
 }

其中的insert()方法的3个参数


mBtn_insert.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
           insertData();
           mEt_songName.setText("");    //数据添加完成后,把文本输入框清空,方便下次输入
           mEt_singer.setText("");
       }
});

六、删

//删
public void deleteData(int positon) {
        Cursor mCursor = mSimpleCursorAdapter.getCursor();
        mCursor.moveToPosition(positon);
        int itemId = mCursor.getInt(mCursor.getColumnIndex("_id"));
        mDbWriter.delete("music_msg", "_id=?", new String[]{itemId + ""});
        refreshListview();
}

这里主要说一下数据库对象的 delete方法的3个参数


七、改

//改
public void updateData(int positon) {
        Cursor mCursor = mSimpleCursorAdapter.getCursor();
        mCursor.moveToPosition(positon);
        int itemId = mCursor.getInt(mCursor.getColumnIndex("_id"));
        ContentValues mContentValues = new ContentValues();
        mContentValues.put("songname", mEt_dialog_songName.getText().toString().trim());
        mContentValues.put("singer", mEt_dialog_singer.getText().toString().trim());
        mDbWriter.update("music_msg", mContentValues, "_id=?", new String[]{itemId + ""});
        refreshListview();
}
//单击修改item
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, final View view, final int position, long l) {
                View mView = View.inflate(MyListviewActivity.this, R.layout.dialog_et_layout, null);       //将放置了两个EditText的布局dialog_et_layout渲染成view对象
                mEt_dialog_songName = (EditText) mView.findViewById(R.id.et_dialog_songname);       //要用对应布局的view对象去findViewById获取控件对象
                mEt_dialog_singer = (EditText) mView.findViewById(R.id.et_dialog_singer);
                mEt_dialog_songName.setText(((TextView) view.findViewById(R.id.songname)).getText());   //获取并显示原来的歌曲
                mEt_dialog_singer.setText(((TextView) view.findViewById(R.id.singer)).getText());       //获取并显示原来的歌手
                new AlertDialog.Builder(MyListviewActivity.this)
                        .setTitle("提示")
                        .setMessage("是否修改数据")
                        .setView(mView)
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                updateData(position);
                            }
                        })
                        .setNegativeButton("取消", null)
                        .show();
        }
});

八、查

String mInput = mEt_input.getText().toString().trim();
 Cursor mCursor1 = mDbReader.query("music_msg", new String[]{"singer"}, "songname=?", new String[]{mInput}, null, null, null);
 Cursor mCursor2 = mDbReader.query("music_msg", new String[]{"songname"}, "singer=?", new String[]{mInput}, null, null, null);

若mCursor1.getCount() > 0,表示输入的是歌曲,并且有查询到结果,这时定义一个全局变量List<Map<String, String>> mStringList = new ArrayList<>();然后通过游标的向下滑动,把歌曲和歌名都存进List里面,最后别忘了关闭游标。具体看代码去理解:

 //查
 public void queryData() {
        String mInput = mEt_input.getText().toString().trim();
        //第二个参数是你需要查找的列
        //第三和第四个参数确定是从哪些行去查找第二个参数的列
        Cursor mCursor1 = mDbReader.query("music_msg", new String[]{"singer"}, "songname=?", new String[]{mInput}, null, null, null);
        Cursor mCursor2 = mDbReader.query("music_msg", new String[]{"songname"}, "singer=?", new String[]{mInput}, null, null, null);
        if (mCursor1.getCount() > 0) {
            mStringList.clear();        //清空List
            while (mCursor1.moveToNext()) {     //游标总是在查询到的上一行
                Map<String, String> mMap = new HashMap<>();
                String output_singer = mCursor1.getString(mCursor1.getColumnIndex("singer"));
                mMap.put("tv1", mInput);
                mMap.put("tv2", output_singer);
                mStringList.add(mMap);
            }
            mCursor1.close();
        } else if (mCursor2.getCount() > 0) {
            mStringList.clear();        //清空List
            while (mCursor2.moveToNext()) {     //游标总是在查询到的上一行
                Map<String, String> mMap = new HashMap<>();
                String output_songname = mCursor2.getString(mCursor2.getColumnIndex("songname"));
                mMap.put("tv1", output_songname);
                mMap.put("tv2", mInput);
                mStringList.add(mMap);
            }
            mCursor2.close();
        } else {
            mStringList.clear();        //清空List
            Map<String, String> mMap = new HashMap<>();
            mMap.put("tv1", "未能查询到结果");
            mStringList.add(mMap);
        }
}
 mBtn_query.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
              queryData();
              mEt_input.setText("");      //清空输入框
              new AlertDialog.Builder(MyListviewActivity.this)
                      .setTitle("查询结果")
                      .setAdapter(new SimpleAdapter(MyListviewActivity.this, mStringList, R.layout.dialog_tv_layout, new String[]{"tv1", "tv2"}, new int[]{R.id.tv1_dialog, R.id.tv2_dialog}), null)
                      .setPositiveButton("确定", null)
                      .show();
        }
});

其中AlertDialog的setAdapter方法跟ListView设置SimpleAdapter基本一样,只是最后那个点击监听设置为null。

后话

上一篇下一篇

猜你喜欢

热点阅读