- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我用 SQLite 数据库制作了一个 Android 应用程序。我希望用户能够在 ListView 中选择数据库的一行并能够删除该特定行。我已经有了数据库和 ListView 。但我找不到如何删除一行。有人可以帮帮我吗?这是我的数据库助手:
package com.persoonlijk.rooster.test2;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import java.util.ArrayList;
import java.util.List;
public class DataManipulator
{
public static final String KEY_ROWID = "id";
public static final String KEY_DAG = "dag";
public static final String KEY_UUR = "uur";
public static final String KEY_VAK = "vak";
public static final String KEY_LOKAAL = "lokaal";
private static final String DATABASE_NAME = "mydatabase.db";
static final String TABLE_NAME = "newtable";
private static final int DATABASE_VERSION = 11;
private static Context context;
static SQLiteDatabase db;
private SQLiteStatement insertStmt;
private static final String INSERT = "insert into " + TABLE_NAME + " (dag,uur,vak,lokaal) values (?,?,?,?)";
public DataManipulator(Context context) {
DataManipulator.context = context;
OpenHelper openHelper = new OpenHelper(DataManipulator.context);
DataManipulator.db = openHelper.getWritableDatabase();
this.insertStmt = DataManipulator.db.compileStatement(INSERT);
}
public long insert(String dag,String uur,String vak,String lokaal) {
this.insertStmt.bindString(1, dag);
this.insertStmt.bindString(2, uur);
this.insertStmt.bindString(3, vak);
this.insertStmt.bindString(4, lokaal);
return this.insertStmt.executeInsert();
}
public void deleteAll() {
db.delete(TABLE_NAME, null, null);
}
public List<String[]> selectAll()
{
List<String[]> list = new ArrayList<String[]>();
Cursor cursor = db.query(TABLE_NAME, new String[] { "id","dag","uur","vak","lokaal" }, null, null, null, null, "dag asc");
int x=0;
if (cursor.moveToFirst()) {
do {
String[] b1=new String[] {cursor.getString(0),cursor.getString(1),cursor.getString(2),
cursor.getString(3),cursor.getString(4)};
list.add(b1);
x=x+1;
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
cursor.close();
return list;
}
public void delete(int rowId) {
db.delete(TABLE_NAME, null, null);
}
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (id INTEGER PRIMARY KEY, dag TEXT, uur TEXT, vak TEXT, lokaal TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
}
这是我对数据库中数据的 ListView : 包 com.persoonlijk.rooster.test2;
import java.util.ArrayList;
import java.util.List;
import com.persoonlijk.rooster.test2.SaveData;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.view.View.OnClickListener;
import android.app.Activity;
public class MainActivity extends ListActivity{
TextView selection;
public int idToModify;
DataManipulator dm;
List<String[]> list = new ArrayList<String[]>();
List<String[]> names2 =null ;
String[] stg1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.check);
dm = new DataManipulator(this);
names2 = dm.selectAll();
stg1=new String[names2.size()];
int x=0;
String stg;
for (String[] dag : names2) {
stg = dag[1]+" - "+dag[2]+ " - "+dag[3]+" - "+dag[4];
stg1[x]=stg;
x++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,stg1);
this.setListAdapter(adapter);
selection=(TextView)findViewById(R.id.selection);
}
public void onListItemClick(ListView parent, View v, int position, long id) {
selection.setText(stg1[position]);
}
//menuknoppen
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, 0, 0, "Voeg gegevens toe");
menu.add(Menu.NONE, 1, 1, "Verwijder gegevens");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0:
startActivity(new Intent(this, SaveData.class));
return true;
case 1:
startActivity(new Intent(this, VerwijderData.class));
return true;
}
return false;
}
}
这就是代码现在的样子: 包 com.persoonlijk.rooster.test2;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends ListActivity{
TextView selection;
public int idToModify;
DataManipulator dm;
List<String[]> list = new ArrayList<String[]>();
List<String[]> names2 =null ;
String[] stg1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.check);
dm = new DataManipulator(this);
names2 = dm.selectAll();
stg1=new String[names2.size()];
int x=0;
String stg;
for (String[] dag : names2) {
stg = dag[1]+" - "+dag[2]+ " - "+dag[3]+" - "+dag[4];
stg1[x]=stg;
x++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,stg1);
this.setListAdapter(adapter);
selection=(TextView)findViewById(R.id.selection);
}
//menuknoppen
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, 0, 0, "Voeg gegevens toe");
menu.add(Menu.NONE, 1, 1, "Verwijder gegevens");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0:
startActivity(new Intent(this, SaveData.class));
return true;
case 1:
startActivity(new Intent(this, VerwijderData.class));
return true;
}
return false;
}
}
现在,在我的 MainActivity 菜单中,您可以单击“verwijder”,然后转到 VerwijderData Activity 。这个 VerwijderData Activity 曾经是 MainActivity。在 VerwijderData Activity 中,用户删除了数据,这是我的应用程序不会自行刷新的 Activity 。这是来自 VerwijderData Activity 的代码:包 com.persoonlijk.rooster.test2;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class VerwijderData extends ListActivity{
TextView selection;
public int idToModify;
DataManipulator dm;
ArrayAdapter<String> adapter;
List<String[]> list = new ArrayList<String[]>();
List<String[]> names2 =null ;
String[] stg1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.verwijder);
dm = new DataManipulator(this);
names2 = dm.selectAll();
stg1=new String[names2.size()];
int x=0;
String stg;
for (String[] dag : names2) {
stg = dag[1]+" - "+dag[2]+ " - "+dag[3]+" - "+dag[4];
stg1[x]=stg;
x++;
}
adapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,stg1);
this.setListAdapter(adapter);
selection=(TextView)findViewById(R.id.selection);
}
public void onListItemClick(ListView parent, View v, int position, long id) {
String[] delete = names2.get(position);
String idString = delete[0];
long idLong = Long.valueOf(idString);
Log.d("Deleting...", idLong + "");
dm.delete(idLong);
names2.remove(position);
stg1=new String[names2.size()];
int x=0;
String stg;
for (String[] dag : names2) {
stg = dag[1]+" - "+dag[2]+ " - "+dag[3]+" - "+dag[4];
stg1[x]=stg;
x++;
}
adapter.notifyDataSetChanged();
}
}
自从我第一次提出问题以来,我的申请发生了一些变化,希望您仍然理解我的意思。
最佳答案
首先,我们需要重新处理您的数据库删除方法。它不会像现在这样做任何事情。
public boolean delete(long rowId) {
/* this is what your database delete method should look like
this method deletes by id, the first column in your database*/
return db.delete(TABLE_NAME, KEY_ROWID + "=" + rowId, null) > 0;
}
现在剩下的就是Activity的onListItemClick
方法
public void onListItemClick(ListView parent, View v, int position, long id) {
/* it looks like you're using an ArrayAdapter so you're gonna need to delete
both from the listview and from the database.
first we refer specifically to the corresponding item in the list by position
which is provided by the listItemClick parameter*/
String[] delete = names2.get(position);
/* we do this because we want the id to delete by in the database by id
based on your dm.selectAll() method, it should be at the first index of the array*/
String idString = delete[0];
// you've made it into a string, but we need it back to being a long value
long idLong = Long.valueOf(idString);
Log.d("Deleting...", idLong + "");
/* i put in the log statement for debugging purposes, it will put the id value on Logcat
so if something goes wrong, we can at least rule out the step since we see the value being
removed, but!
finally we can delete it from our database because we have the parameter we need*/
dm.delete(idLong);
/* There it's done, but surely you want it off the listview too so no one is confused.
unfortunately you've made stg1 an array so we can't just remove the index from it*/
names2.remove(position);
stg1=new String[names2.size()];
int x=0;
String stg;
for (String[] dag : names2) {
stg = dag[1]+" - "+dag[2]+ " - "+dag[3]+" - "+dag[4];
stg1[x]=stg;
x++;
}
/* can you see what happened? the `List` collection is able have its components dynamically
added and removed, so i removed from that, then i remade the stg1 collection using your method.*/
adapter.notifyDataSetChanged();
// ^ that command refreshes the listview to see changes.
}
考虑到所有因素,您已经使这项任务比当前设置所需的繁琐得多。首先,您在输入到适配器之前已经制作了大量的中间集合,然后您将一个数组作为数据源,它不能被动态调整。
更令人满意的是使用 CursorAdapter
进行设置。然后您可以使用 ListItemClick
方法中提供的 id 参数,因为它就是我们想要的确切 ID。此外,您只需要从一个数据库源中删除,然后只需刷新适配器即可。
让你的适配器像其他一些变量一样成为一个字段,以便在整个类中引用它:
public class MainActivity extends ListActivity{
TextView selection;
public int idToModify;
DataManipulator dm;
......
ArrayAdapter<String> adapter; <--------- add that
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.check);
.........
adapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,stg1); <------ edit that
this.setListAdapter(adapter);
}
}
关于android - 如何在 ListView 中由用户删除 Android 应用程序中 Sqlite 数据库中的一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14111769/
我正在开发一个 SQLite 数据库。数据库已经填满了,但我想重构它。这是我需要做的一个示例: 我目前有一张 table : CREATE TABLE Cars (ID INTEGER PRIMARY
我正在使用 Mono、SQLite、Dapper 和 Dapper 扩展。我可以从数据库中读取数据,但插入不起作用。我正在使用 sqlite 的 Mono 驱动程序。 错误并不能提供太多信息,至少对我
我有一个使用 SQLite 的 Windows Phone 8 应用程序。该应用程序具有许多数据库功能,并包含一个 sqlite 数据库文件,在运行该应用程序时,该文件将被复制到本地文件夹并进行访问。
为 sqlite 创建索引时有排序顺序。 https://sqlite.org/lang_createindex.html Each column name or expression can be
顾名思义,我怀疑如果有一些引用被删除的表会发生什么,例如表的某些字段的索引。 SQLite是否会自动处理?在执行drop命令之前,数据库所有者是否应注意任何实例? 最佳答案 我认为不需要家政服务。 S
我想知道是否有可能将从计数中获得的整数转换为REAL 类似于以下内容(尽管这不起作用) SELECT CAST (COUNT (ColumnA) AS Count) AS REAL) FROM Tab
我无法在SQLite数据库上执行一些更新。我正在Windows上使用SQLite 3 Shell。 我正在运行以下命令: update resovled_chrom_counts set genus
我知道SQLite中的触发器顺序是不确定的(您不能确定将首先执行哪个触发器),但是表约束和触发器之间的关系又如何呢? 我的意思是,假设我在一个列中有一个UNIQUE(或CHECK)约束,并且在该表上有
我的 CustomTags 表可能有一系列“临时”记录,其中 Tag_ID 为 0,并且 Tag_Number 将有一些五位数的值。 定期,我想清理我的 Sqlite 表以删除这些临时值。 例如,我可
我有A,B,C和D的记录。 我的SQL1 SELECT * FROM main_table order by main_table.date desc limit 2返回A和B。 我的SQL2 SEL
select round(836.0)返回836.0 我如何删除sqlite查询中的尾随零。 836.00应该是836 836.440应该是836.44 最佳答案 如果需要836.44,则需要十进制返
我正在研究RQDA中的文本,并且正在使用Firefox SQLite Manager访问数据库,以便可以更轻松地搜索文件。我创建并填充了虚拟表: CREATE VIRTUAL TABLE texts
我有这样的数据: table1 id | part | price 1 | ox900 | 100 2 | ox980 | 200 和 table2 id | part | price 1
我正在尝试将一些数据插入现有的SQLite表中。该表和数据库是使用相同的API创建的,但是由于某种原因,插入操作无效,并且从不给我任何错误消息。 我正在BlackBerry 9550模拟器上对此进行测
例如,我在名为SALARY的列中插入一个值。如果插入的值大于1000,我想将字符串HIGH插入到RANK列中,否则将插入LOW中。 我可以使用SQLite做到吗? 最佳答案 在插入之前使用触发器,然后
假设我有一个包含三列A,B,C的表t1,其中(A,B)包含唯一键(具有数十万行)。由于90%的查询将采用SELECT C FROM t1 WHERE A =?和B = ?,我想我要为A,B和C提供覆盖
在一个SQLite3数据库中,我有一个表“ projects”,其id字段由以下方式组成: [user id]_[user's project id] 例如,用户ID = 45,这是一些数据: 45_
我了解PRAGMA foreign_key和ON DELETE RESTRICT/NO ACTION的概念,但是我面临的是另一种情况。 我需要删除一个父行,但保持与之关联的子行。例如: CREATE
我的c#应用程序从Web服务1读取文件列表,并将完整的文件名插入table1,然后从第二个Web服务读取list并将它们插入到table2。 这些表具有相同的结构,如下所示: create table
我在以下情况下尝试将Record1的ID更新为Record2的ID: 两个表中的名称相同,并且 在Record2中权重更大。 记录1 | ID | Weight | Name | |----|----
我是一名优秀的程序员,十分优秀!