#android-listview #android-sqlite
Вопрос:
Я новичок в работе с базой данных SQLite. У меня проблема с обновлением и удалением данных из ListView. Я вставляю свои данные в ListView, когда я нажимаю на свои данные ListView, они будут отображаться в режиме обновления. Теперь я хочу получить выбранное значение ListView в новой активности обновления, чтобы я мог редактировать или удалять. Как это сделать.
ListDataActivity.Java
public void loadData() {
//Create an arraylist so that i can load the data to add in the arraylist
ArrayList<String> listData = new ArrayList<>();
Cursor cursor = databaseHelper.showAllData();
if (cursor.getCount() == 0) {
Toast.makeText(getApplicationContext(), "no data is available", Toast.LENGTH_LONG).show();
} else {
while (cursor.moveToNext()) {
listData.add(cursor.getString(1) " t " cursor.getString(2));
}
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.textViewId, listData);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String selectedValue = adapterView.getItemAtPosition(position).toString();
Toast.makeText(getApplicationContext(), "Selected Value : " selectedValue,
Toast.LENGTH_LONG).show();
Intent intent = new Intent(ListDataActivity.this,UpdateActivity.class);
startActivity(intent);
}
});
UpdateActivity.Java
private DatabaseHelper databaseHelper;
private String selectedName;
private String selectedID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
databaseHelper = new DatabaseHelper(this);
SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase();
Intent receiveIntent = getIntent();
selectedID = receiveIntent.getStringExtra("name");
selectedName = receiveIntent.getStringExtra("surName");
Когда я вставляю данные, а затем нажимаю на свой список, он переходит к этому типу действий по обновлению дизайна. Я хочу, чтобы данные Listview, на которые вы нажали, были в активности обновления. Как я могу это решить?
Ответ №1:
Теперь я хочу получить выбранное значение listview в новой функции обновления, чтобы я мог редактировать или удалять. Как это сделать.
Вот рабочий пример, который обновляет (переходит в UpdateActivity) и удаляет (при длительном щелчке элемента). При этом используется адаптер курсора, а именно стандартный адаптер SimpleCursorAdapter. Использование адаптеров курсоров для данных SQLite довольно просто.
Сначала пользователь базы данных :-
class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(@Nullable Context context) {
super(context, "mydatabase", null, 1);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS mytable (_id INTEGER PRIMARY KEY, name TEXT, surname TEXT, phone TEXT)");
/* Add some test data */
add("Fred","Bloggs","0000000000",sqLiteDatabase);
add("Jane","Doe","1111111111",sqLiteDatabase);
add("Mary","Johnston","2222222222",sqLiteDatabase);
add("Tom","cobboly","3333333333",sqLiteDatabase);
add("Anne","Walker","4444444444",sqLiteDatabase);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public long update(long id, String name, String surname, String phone) {
long rv = 0;
ContentValues cv = new ContentValues();
if (name != null amp;amp; name.length() > 0) cv.put("name",name);
if (surname != null amp;amp; surname.length() > 0) cv.put("surname",surname);
if (phone != null amp;amp; phone.length() > 0) cv.put("phone",phone);
if (cv.size() > 0) rv = this.getWritableDatabase().update("mytable",cv,"_id=?",new String[]{String.valueOf(id)});
return rv;
}
public long delete(long id) {
return this.getWritableDatabase().delete("mytable","_id=?",new String[]{String.valueOf(id)});
}
public Cursor getAll() {
return this.getWritableDatabase().query("mytable",null,null,null,null,null,null);
}
public Cursor getById(long id) {
return this.getWritableDatabase().query("mytable",null,"_id=?",new String[]{String.valueOf(id)},null,null,null);
}
private long add(String name, String surname, String phone, SQLiteDatabase db) {
ContentValues cv = new ContentValues();
cv.put("name",name);
cv.put("surname",surname);
cv.put("phone",phone);
return db.insert("mytable",null,cv);
}
public long add(String name, String surname, String phone) {
return add(name,surname,phone,this.getWritableDatabase());
}
}
- ВАЖНОЕ ПРИМЕЧАНИЕ. Адаптерам курсоров требуется столбец идентификатора с именем _id.
- ОБРАТИТЕ внимание, что это добавляет некоторые данные тестирования.
- Все методы доступа включены
- GetAll возвращает курсор со ВСЕМИ строками из таблицы.
- обновление обновляется в соответствии с переданными значениями, оно предназначено только для обновления значений (например, поскольку editSurname EditText отсутствует, передается значение null, поэтому фамилия остается прежней).
- getById returns a cursor with all values according to the id
- add without the 4th parameter is the typical add, the one with the 4th parameter is to allow it’s use in onCreate before the DatabaaeHelper has been fully instantiated.
ListDataActivity
public class ListDataActivity extends AppCompatActivity {
ListView listview;
SimpleCursorAdapter sca;
DatabaseHelper databaseHelper;
Cursor cursor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = this.findViewById(R.id.mylistview);
databaseHelper = new DatabaseHelper(this);
setOrRefreshListView();
}
/* handles the ListView */
private void setOrRefreshListView() {
cursor = databaseHelper.getAll(); /* Gets the data to be listed */
/* If first time then setup the adapter listeners etc */
if (sca == null) {
sca = new SimpleCursorAdapter(
this,
android.R.layout.simple_expandable_list_item_2,
cursor,
new String[]{"name","phone"},
new int[]{android.R.id.text1, android.R.id.text2},
0
);
listview.setAdapter(sca); // attach the adapter to the listview
// setup On Item Click to start the update activity passing the id
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(ListDataActivity.this,UpdateActivity.class);
intent.putExtra("my_id_extra",l);
startActivity(intent);
}
});
// setup the on Item LONG Click to delete a row
listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
databaseHelper.delete(l);
setOrRefreshListView(); // after deletion refresh the data
return true;
}
});
} else {
sca.swapCursor(cursor); // if not the first time just tell the adapter the data has changed
}
}
@Override
protected void onResume() {
super.onResume();
setOrRefreshListView(); // refresh the listview when returning to the activity
}
@Override
protected void onDestroy() {
super.onDestroy();
cursor.close(); // clean up
}
}
Макет для ListDataActivity (очень простой, просто представление списка) :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ListDataActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<ListView
android:id="@ id/mylistview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/teal_200"
>
</ListView>
</LinearLayout>
- фон установлен так, чтобы было легко видеть представление списка.
Активность обновления :-
public class UpdateActivity extends AppCompatActivity {
DatabaseHelper databaseHelper;
EditText editName, editPhone;
Button saveButtonId,showButtonId;
long currentId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
editName = this.findViewById(R.id.editName);
editPhone = this.findViewById(R.id.editPhone);
saveButtonId = this.findViewById(R.id.savebuttonId);
showButtonId = this.findViewById(R.id.showbuttonId);
databaseHelper = new DatabaseHelper(this);
currentId = this.getIntent().getLongExtra("my_id_extra",-1);
if (currentId < 0 ) {
// do something as invalid id passed
finish();
}
showData();
showButtonId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
saveButtonId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
databaseHelper.update(currentId,editName.getText().toString(),null,editPhone.getText().toString());
}
});
}
private void showData() {
Cursor cursor = databaseHelper.getById(currentId);
if (cursor.moveToFirst()) {
editName.setText(cursor.getString(cursor.getColumnIndex("name")));
editPhone.setText(cursor.getString(cursor.getColumnIndex("phone")));
}
cursor.close();
}
}
- Кнопка showData возвращает в ListDataActivity (я полагаю, что это то, что вы хотели).
Результат :-
- Когда все начиналось заново :-
- Нажмите на Мэри (и измените номер на 999999999, но не сохраняйте) :-
- Нажмите кнопку Сохранить (так же, как 2)
- Нажмите кнопку Показать :-
- Длинный щелчок, Фред :-
- Перезапустите приложение :-
Комментарии:
1. @imtiazeemel код в примере работает, вам нужно посмотреть, какие поправки вы вносите, и посмотреть, чем они отличаются. Я предполагаю, что вы используете позицию слушателя (int, переданный слушателю). НЕ так давно прошло. Последнее будет значением столбца _id, если и только если при использовании адаптера курсора для адаптера массива оба удерживают позицию, которая, вероятно, НЕ будет идентификатором строки.