效果圖示例:java
一、在配置清單裏配置須要的權限android
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>sql
//res/layout下3個佈局activity_main.xml和dialoug_update_main.xml和item_listview.xml佈局數據庫
二、activity_main.xml佈局異步
代碼ide
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >函數
<ListView
android:id="@+id/listView_main_titlelist"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>工具
</LinearLayout>佈局
==============ui
三、dialoug_update_main.xml佈局
代碼
<?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/text_dialog_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<EditText
android:id="@+id/editText_dialog_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint=""
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/editText_dialog_age"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint=""
android:ems="10" >
</EditText>
</LinearLayout>
================
四、item_listview.xml佈局
代碼
<?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/text_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="@+id/text_item_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
======================
五、res下建立一個menu菜單文件夾 菜單文件夾一個list_menu.xml菜單佈局
代碼
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/list_delete"
android:title="刪除"/>
<item
android:id="@+id/list_change"
android:title="修改"/>
<item
android:id="@+id/list_no"
android:title="不操做"/>
</menu>
==================
//2個java源文件MainActivity.java類和對sqlite數據給操做工具類Sqlite_operate_utils.java
六、Sqlite_operate_utils.java工具類
代碼
public class Sqlite_operate_utils {
private static String DB_PATH = Environment.getExternalStorageDirectory() + File.separator + "studentinfo2.db";
private SQLiteDatabase db;
//構造函數 new 該類的時候 就去找 須要找的 數據庫
public Sqlite_operate_utils() {
db = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
}
//查詢 數據的 方法1
public Cursor sqlite_select(String content, String[] condition){
return db.rawQuery(content, condition);
}
//查詢 數據 的 方法2
public List<Map<String, String>> sqlite_selectlist(String content, String[] condition){
Log.i("data", "cursor:");
Cursor cursor = db.rawQuery(content, condition);
return cursorToList(cursor);
}
//返回List
public List<Map<String, String>> cursorToList(Cursor cursor) {
List<Map<String, String>> list = new ArrayList<Map<String,String>>();
while(cursor.moveToNext()){//數據庫表的 行
Map<String, String> map = new HashMap<String, String>();
for(int i = 0;i<cursor.getColumnCount();i++){//數據庫表的列
map.put(cursor.getColumnName(i), cursor.getString(i));
}
list.add(map);
}
cursor.close();
Log.i("data", "list:" + list.size());
return list;
}
//增刪改 的方法
//返回布爾型 方便 查看 數據 操做 是否成功
public boolean executeData(String execute_content, Object[] bindArgs){
try {
if(bindArgs == null){//要綁定佔位符 的參數值
db.execSQL(execute_content);
return true;
}else{
db.execSQL(execute_content, bindArgs);
return true;
}
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
//關閉db
public void destroy(){
if(db != null){
db.close();
}
}
}
==================
七、MainActivity.java類
代碼
public class MainActivity extends FragmentActivity implements
LoaderCallbacks<Cursor> {
private ListView listView;
private static Cursor cursor;
private static SimpleCursorAdapter adapter;// 自定義遊標適配器
private LoaderManager loaderManager;// 裝載管理器對象聲明
private static Sqlite_operate_utils sql;// 對數據庫操做的工具類對象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.listView = (ListView) this
.findViewById(R.id.listView_main_titlelist);
sql = new Sqlite_operate_utils();
loaderManager = getSupportLoaderManager();// 獲取裝載管理器
// 用裝載管理器來獲取數據初始化加載器
// initLoader -- 若是當前沒有加載器就調用onCreateLoader建立一個 有就根據第一個參數標誌重複利用
// 第一個參數 -- 加載器的標誌 隨便寫
// 第二個參數 -- Bundle -- 用來傳遞數據 沒有能夠寫null
// 第三個參數 -- LoaderCallbacks 對象
loaderManager.initLoader(1, null, this);
// 最後一個參數 標誌 能夠用CursorAdapter.出來
//若是是FLAG_REGISTER_CONTENT_OBSERVER標誌 則適配器會在Cursor上註冊一個內容觀察者
///該觀察者會時時刻刻觀察內容的變更 若是通知到達時就調用onContentChanged()方法
adapter = new SimpleCursorAdapter(this, R.layout.item_listview, cursor,
new String[] { "s_name", "s_age" }, new int[] {
R.id.text_item_name, R.id.text_item_age },
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
listView.setAdapter(adapter);
// 註冊上下文菜單
registerForContextMenu(listView);
}
// 建立一個上下文菜單
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
long id = adapter.getItemId(info.position);
menu.setHeaderIcon(R.drawable.ic_launcher);
menu.setHeaderTitle(id + "");
getMenuInflater().inflate(R.menu.list_menu, menu);
}
// 上下文菜單監聽
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
final long item_id = adapter.getItemId(info.position);
switch (item.getItemId()) {
case R.id.list_delete:
// 彈出一個警告框提示用戶是否刪除
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(item_id + "");
builder.setIcon(R.drawable.ic_launcher);
builder.setMessage("肯定刪除" + item_id + "信息?");
builder.setNegativeButton("取消", null);
builder.setPositiveButton("肯定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 若是肯定就去數據庫刪除數據
boolean result = sql.executeData(
"delete from student where s_id = ?",
new String[] { item_id + "" });
if (result) {
// 若是刪除成功就用LoaderManager調用restartLoader方法從新加載數據
loaderManager.restartLoader(1, null, MainActivity.this);
}
}
});
builder.show();
break;
case R.id.list_change:
AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
builder2.setIcon(R.drawable.ic_launcher);
builder2.setTitle("修改數據");
View view = LayoutInflater.from(this).inflate(R.layout.dialoug_update_main, null);
final TextView id = (TextView) view
.findViewById(R.id.text_dialog_id);
Log.i("data", "0000000");
final EditText name = (EditText) view
.findViewById(R.id.editText_dialog_name);
final EditText age = (EditText) view
.findViewById(R.id.editText_dialog_age);
builder2.setView(view);
// 獲取用戶選擇的數據填充到修改框
// 查詢數據庫
cursor = sql.sqlite_select(
"select s_id _id,s_name,s_age from student where s_id = ?",
new String[] { item_id + "" });
cursor.moveToFirst();
id.setText(item_id + "");
name.setText(cursor.getString(cursor.getColumnIndex("s_name")));
age.setText(cursor.getString(cursor.getColumnIndex("s_age")));
cursor.close();
// 肯定按鈕的事件監聽
builder2.setPositiveButton("肯定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 獲取修改框的信息
String update_id = id.getText().toString();
String update_name = name.getText().toString();
String update_age = age.getText().toString();
String execute_content = "update student set s_name = ?,s_age = ? where s_id = ?";
Object[] bindArgs = { update_name, update_age, update_id };
// 更新數據庫
boolean result = sql.executeData(execute_content, bindArgs);
if (result) {
// 修改數據成功就用加載管理器調用restartLoader方法從新查詢數據
loaderManager.restartLoader(1, null, MainActivity.this);
}
}
});
builder2.show();
break;
}
return super.onContextItemSelected(item);
}
// --------------------繼承AsyncTaskLoader類要重寫的方法--------------------------------
// 繼承了異步裝載類 若是是內部類 就必需要靜態 否則 會報錯
static class MyAsynTaskLoader extends AsyncTaskLoader<Cursor> {
// 繼承AsyncTaskLoader類 的類 沒有無慘構造函數
public MyAsynTaskLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
super.onStartLoading();
// 調用forceLoad()方法 能夠依次調用下一次 即將要執行的方法
forceLoad();
}
@Override
// 子線程進行
public Cursor loadInBackground() {
// 查找數據庫 須要的數據
// 注意:用SimpleCursorAdapter適配器 查詢必需要有_id
cursor = sql.sqlite_select(
"select s_id _id,s_name,s_age from student", null);
return cursor;
}
@Override//執行跟適配器的交換操做
public void deliverResult(Cursor data) {
super.deliverResult(data);
// 新舊cursor交換
adapter.swapCursor(data);
}
}
// ----------繼承LoaderCallbacks接口要重寫的方法---------------
@Override
// 建立一個Loader
public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
return new MyAsynTaskLoader(this);
}
@Override
// Loader建立完成
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
}
@Override // 當一個加載器給重置時 調用 public void onLoaderReset(Loader<Cursor> loader) { adapter.swapCursor(null); }}