使用 CursorAdapter 时无法编辑 ListView 项目
Cannot edit ListView items while using CursorAdapter
我正在构建一个应用程序,它使用 SQLite 来实现持久性并且还包含一个 CursorAdapter。我能够将项目添加到 ListView 和 SQLite table 中,并且可以在应用程序重新启动时查看这些项目。我还可以删除项目并在再次重新启动后查看更改。我添加了一个带有 onClickListener
的编辑功能,一旦我点击一个项目,它应该会带我到编辑屏幕,我可以在其中编辑该特定项目。这是我的:
Mainactivity.java
public class MainActivity extends AppCompatActivity {
DatabaseHelper databaseHelper;
private final int REQUEST_CODE = 10;
ArrayList <String> toDoItems;
ArrayAdapter<String> adapter;
SimpleCursorAdapter altAdapter;
Cursor itemListCursor;
ListView listItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listItems = (ListView) findViewById(R.id.listViewItems);
toDoItems = new ArrayList<>();
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, toDoItems);
databaseHelper = new DatabaseHelper(this);
getItemListAsCursor();
altAdapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
itemListCursor,
new String[]{TO_DO},
new int[]{android.R.id.text1},
0);
listItems.setAdapter(altAdapter);
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapter, View item, int position, long id) {
itemDeleteFromDatabase(id);
getItemListAsCursor();
altAdapter.swapCursor(itemListCursor);
return true;
}
});
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter, View item, int pos, long id) {
Intent intent = new Intent(MainActivity.this, EditItemActivity.class);
intent.putExtra("itemName", toDoItems.get(pos));
intent.putExtra("itemPos", id);
startActivityForResult(intent, REQUEST_CODE);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
itemListCursor.close();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
String item = data.getStringExtra("item");
int itemPosition = Integer.parseInt(data.getStringExtra("itemPos"));
toDoItems.add(itemPosition, item);
databaseHelper.insertData(item);
toDoItems.remove(itemPosition + 1);
itemDeleteFromDatabase((long) (itemPosition + 1));
adapter.notifyDataSetChanged();
}
}
public void addItem(View v) {
EditText newItem = (EditText) findViewById(R.id.itemInputEditText);
if (newItem.getText().length() == 0) {
Toast.makeText(this, "You need to enter a to do.", Toast.LENGTH_SHORT).show();
} else {
String item = newItem.getText().toString();
databaseHelper.insertData(item);
getItemListAsCursor();
altAdapter.swapCursor(itemListCursor);
adapter.notifyDataSetChanged();
newItem.setText("");
}
}
public void getToDos(){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
Cursor cursor = database.rawQuery("select * from student",null);
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
String name = cursor.getString(cursor.getColumnIndex("todo"));
adapter.add(name);
adapter.notifyDataSetChanged();
cursor.moveToNext();
}
}
}
public void getItemListAsCursor() {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
itemListCursor = database.query(TABLE_NAME,null,null,null,null,null,null);
}
public boolean itemDeleteFromDatabase(Long id) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
boolean databaseDelete = database.delete(TABLE_NAME, ID + "=?", new String[]{Long.toString(id)}) > 0;
return databaseDelete;
}
}
EditItemActivity.java
public class EditItemActivity extends AppCompatActivity {
EditText editToDo;
Long itemPos;
Button saveChanges;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_item);
editToDo = (EditText) findViewById(R.id.edit_todo_item);
saveChanges = (Button)findViewById(R.id.save_changes);
String itemName = getIntent().getStringExtra("itemName");
editToDo.setText(itemName);
itemPos = getIntent().getLongExtra("itemPos", 0);
saveChanges.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onSubmit();
}
});
}
public void onSubmit() {
Intent item = new Intent();
item.putExtra("itemName", editToDo.getText().toString());
item.putExtra("itemPos", itemPos);
setResult(RESULT_OK, item);
finish();
}
}
但是当我点击一个项目时,我得到了臭名昭著的 indexOutOfBounds
异常。这是堆栈跟踪:
FATAL EXCEPTION: main
Process: ca.ozbek.preworktodoapp, PID: 13721
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at ca.ozbek.preworktodoapp.MainActivity.onItemClick(MainActivity.java:65)
我知道因为我使用的是 CursorAdapter,所以我应该在我的 intent.putExtra("item", toDoItems.get(pos));
和 intent.putExtra("itemPos", String.valueOf(pos));
代码行中使用 id
而不是 pos
但我可以不要那样做,因为 id
是一个 long 值。
如果你创建一个DBHelperClass生活用会很容易处理所有的CRUD功能
因此,当您单击 btnDelete 时,您的列表有一个位置并且您的记录有一个 ID Activity 您正在使用这样的代码
// Calls the Method deleteDBRow in DatabaseHelper
// which acts on the TABLE_INFO to remove a record by getting the record ID
helper.deleteDBRow(String.valueOf(dbList.get(position).getID()));
ListActivity.removeListRow(position);
// 上面的代码行调用 ListActivity 中的方法来通知回收者视图的变化
// 注意 List 按位置而不是 ID 保存项目 <== READ
好的,现在在你的 DBHelper 中结束 Class 你在下面实现这个方法代码
/* Delete a record from database table named "TABLE_INFO" */
/* based on the selected records id in Col_ID*/
public void deleteDBRow(String rowid){
db = this.getWritableDatabase();
db.delete(TABLE_INFO, Col_ID + " = ?", new String[] { rowid });
db.close();
return;
}
我正在构建一个应用程序,它使用 SQLite 来实现持久性并且还包含一个 CursorAdapter。我能够将项目添加到 ListView 和 SQLite table 中,并且可以在应用程序重新启动时查看这些项目。我还可以删除项目并在再次重新启动后查看更改。我添加了一个带有 onClickListener
的编辑功能,一旦我点击一个项目,它应该会带我到编辑屏幕,我可以在其中编辑该特定项目。这是我的:
Mainactivity.java
public class MainActivity extends AppCompatActivity {
DatabaseHelper databaseHelper;
private final int REQUEST_CODE = 10;
ArrayList <String> toDoItems;
ArrayAdapter<String> adapter;
SimpleCursorAdapter altAdapter;
Cursor itemListCursor;
ListView listItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listItems = (ListView) findViewById(R.id.listViewItems);
toDoItems = new ArrayList<>();
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, toDoItems);
databaseHelper = new DatabaseHelper(this);
getItemListAsCursor();
altAdapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
itemListCursor,
new String[]{TO_DO},
new int[]{android.R.id.text1},
0);
listItems.setAdapter(altAdapter);
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapter, View item, int position, long id) {
itemDeleteFromDatabase(id);
getItemListAsCursor();
altAdapter.swapCursor(itemListCursor);
return true;
}
});
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter, View item, int pos, long id) {
Intent intent = new Intent(MainActivity.this, EditItemActivity.class);
intent.putExtra("itemName", toDoItems.get(pos));
intent.putExtra("itemPos", id);
startActivityForResult(intent, REQUEST_CODE);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
itemListCursor.close();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
String item = data.getStringExtra("item");
int itemPosition = Integer.parseInt(data.getStringExtra("itemPos"));
toDoItems.add(itemPosition, item);
databaseHelper.insertData(item);
toDoItems.remove(itemPosition + 1);
itemDeleteFromDatabase((long) (itemPosition + 1));
adapter.notifyDataSetChanged();
}
}
public void addItem(View v) {
EditText newItem = (EditText) findViewById(R.id.itemInputEditText);
if (newItem.getText().length() == 0) {
Toast.makeText(this, "You need to enter a to do.", Toast.LENGTH_SHORT).show();
} else {
String item = newItem.getText().toString();
databaseHelper.insertData(item);
getItemListAsCursor();
altAdapter.swapCursor(itemListCursor);
adapter.notifyDataSetChanged();
newItem.setText("");
}
}
public void getToDos(){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
Cursor cursor = database.rawQuery("select * from student",null);
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
String name = cursor.getString(cursor.getColumnIndex("todo"));
adapter.add(name);
adapter.notifyDataSetChanged();
cursor.moveToNext();
}
}
}
public void getItemListAsCursor() {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
itemListCursor = database.query(TABLE_NAME,null,null,null,null,null,null);
}
public boolean itemDeleteFromDatabase(Long id) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
boolean databaseDelete = database.delete(TABLE_NAME, ID + "=?", new String[]{Long.toString(id)}) > 0;
return databaseDelete;
}
}
EditItemActivity.java
public class EditItemActivity extends AppCompatActivity {
EditText editToDo;
Long itemPos;
Button saveChanges;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_item);
editToDo = (EditText) findViewById(R.id.edit_todo_item);
saveChanges = (Button)findViewById(R.id.save_changes);
String itemName = getIntent().getStringExtra("itemName");
editToDo.setText(itemName);
itemPos = getIntent().getLongExtra("itemPos", 0);
saveChanges.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onSubmit();
}
});
}
public void onSubmit() {
Intent item = new Intent();
item.putExtra("itemName", editToDo.getText().toString());
item.putExtra("itemPos", itemPos);
setResult(RESULT_OK, item);
finish();
}
}
但是当我点击一个项目时,我得到了臭名昭著的 indexOutOfBounds
异常。这是堆栈跟踪:
FATAL EXCEPTION: main
Process: ca.ozbek.preworktodoapp, PID: 13721
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at ca.ozbek.preworktodoapp.MainActivity.onItemClick(MainActivity.java:65)
我知道因为我使用的是 CursorAdapter,所以我应该在我的 intent.putExtra("item", toDoItems.get(pos));
和 intent.putExtra("itemPos", String.valueOf(pos));
代码行中使用 id
而不是 pos
但我可以不要那样做,因为 id
是一个 long 值。
如果你创建一个DBHelperClass生活用会很容易处理所有的CRUD功能 因此,当您单击 btnDelete 时,您的列表有一个位置并且您的记录有一个 ID Activity 您正在使用这样的代码
// Calls the Method deleteDBRow in DatabaseHelper
// which acts on the TABLE_INFO to remove a record by getting the record ID
helper.deleteDBRow(String.valueOf(dbList.get(position).getID()));
ListActivity.removeListRow(position);
// 上面的代码行调用 ListActivity 中的方法来通知回收者视图的变化 // 注意 List 按位置而不是 ID 保存项目 <== READ
好的,现在在你的 DBHelper 中结束 Class 你在下面实现这个方法代码
/* Delete a record from database table named "TABLE_INFO" */
/* based on the selected records id in Col_ID*/
public void deleteDBRow(String rowid){
db = this.getWritableDatabase();
db.delete(TABLE_INFO, Col_ID + " = ?", new String[] { rowid });
db.close();
return;
}