布局只是main.xml,当将新信息添加到sqlite数据库时,它会显示多个row.xml。单击按钮时,将显示带有数据的AlertDialog。 问题是,当我单击行中的按钮时,AlertDialog正在从数据库中的下一条记录(下一行)中获取数据(当我单击第一个按钮时,AD正在获取第二条记录等),而不是从按钮所在位置获取数据。 我为按钮设置setTag,并在单击Toast消息时显示了良好的ID。
MyCursorAdapter.java
(...)
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView name = (TextView) view.findViewById(R.id.name);
TextView id = (TextView) view.findViewById(R.id.id);
TextView quantity = (TextView) view.findViewById(R.id.quantity);
TextView mu = (TextView) view.findViewById(R.id.mu);
Button bt = (Button) view.findViewById(R.id.rowalertdialog);
CheckBox cb = (CheckBox)view.findViewById(R.id.checkboxmain2);
name.setText(cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_NAME)));
id.setText(cursor.getString(cursor.getColumnIndex(SQLiteAdapter._id)));
quantity.setText(cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_QUANTITY)));
mu.setText(cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_MU)));
bt.setTag(cursor.getString(cursor.getColumnIndex(SQLiteAdapter._id)));
cb.setChecked(cursor.getInt(cursor.getColumnIndex(SQLiteAdapter.KEY_CHECKED)) > 0);
cb.setTag(cursor.getString(cursor.getColumnIndex(SQLiteAdapter._id)));
}
AndroidSQLite.java
(...)
private void manageListView() {
cursor = mySQLiteAdapter.queueAll();
if(myadapter == null){
myadapter = new MyCursorAdapter(this,cursor);
listContent.setAdapter(myadapter);
}else {
myadapter.swapCursor(cursor);
}
}
onClick for button
public void ListViewButtonHandler(View v){
Button bt = v.findViewById(R.id.rowalertdialog);
Toast.makeText(this, "You clicked the Button for ID " + (String)bt.getTag(), Toast.LENGTH_SHORT).show();
int id = Integer.valueOf((String) bt.getTag());
ListView parent = (ListView)findViewById(R.id.contentlist);
Cursor cursor = (Cursor) parent.getItemAtPosition(id);
final int item_id = cursor.getInt(cursor.getColumnIndex(SQLiteAdapter._id));
String item_name = cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_NAME));
String item_quantity = cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_QUANTITY));
AlertDialog.Builder myDialog
= new AlertDialog.Builder(AndroidSQLite.this);
myDialog.setTitle("Delete/Edit?");
TextView dialogTxt_id = new TextView(AndroidSQLite.this);
LayoutParams dialogTxt_idLayoutParams
= new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
dialogTxt_id.setLayoutParams(dialogTxt_idLayoutParams);
dialogTxt_id.setText("#" + String.valueOf(item_id));
final EditText dialogC1_id = new EditText(AndroidSQLite.this);
LayoutParams dialogC1_idLayoutParams
= new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
dialogC1_id.setLayoutParams(dialogC1_idLayoutParams);
dialogC1_id.setText(item_name);
final EditText dialogC2_id = new EditText(AndroidSQLite.this);
LayoutParams dialogC2_idLayoutParams
= new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
dialogC2_id.setLayoutParams(dialogC2_idLayoutParams);
dialogC2_id.setText(item_quantity);
LinearLayout layout = new LinearLayout(AndroidSQLite.this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(dialogTxt_id);
layout.addView(dialogC1_id);
layout.addView(dialogC2_id);
myDialog.setView(layout);
myDialog.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
mySQLiteAdapter.delete_byID(item_id);
updateList();
//manageListView();
}
});
myDialog.setNeutralButton("Update", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
String value1 = dialogC1_id.getText().toString();
String value2 = dialogC2_id.getText().toString();
mySQLiteAdapter.update_byID(item_id, value1, value2);
updateList();
//manageListView();
}
});
myDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
}
});
manageListView();
myDialog.show();
}
我认为问题出在
int id = Integer.valueOf((String) bt.getTag());
ListView parent = (ListView)findViewById(R.id.contentlist);
Cursor cursor = (Cursor) parent.getItemAtPosition(id);
但是我不知道如何解决。我不知道为什么要录下一张唱片。
编辑 我对代码进行了第二次(替代)更改,现在,当我单击按钮活动时,返回到先前的屏幕(mainactivity)。 Logcat显示:
FATAL EXCEPTION: main
Process: com.sjkdev.androidsqlite, PID: 14453
java.lang.IllegalStateException: Could not execute method for android:onClick
at
android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at android.view.View.performClick(View.java:5646)
at android.view.View$PerformClick.run(View.java:22459)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at
android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:831)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:5646)
at android.view.View$PerformClick.run(View.java:22459)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:831)
Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:68)
at com.sjkdev.androidsqlite.AndroidSQLite.ListViewButtonHandler(AndroidSQLite.java:307)
答案 0 :(得分:1)
这是一个基于您之前的问题以及该问题的示例应用程序。
但是
按钮单击处理,无需使用布局的 onCLick (按XML编码)即可处理,但可以在自定义的 bindView 方法中进行设置> CursorAdapter ( MyCursorAdapter.java )。
它演示了获取与按钮关联的id的3种方法
该处理允许删除和更新行(尽管更新非常基本,只是附加一个值而不是使用自定义对话框布局(您似乎对此有所了解))。
与先前的答案不同,还实现了处理添加的行(尽管值有限)的功能。
生成的应用程序看起来像:-
如果点击编辑或删除按钮,则会显示对话框,例如:-
:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/panelup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LIST SQ1"
/>
<ListView
android:id="@+id/contentlist"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/panelup"
android:layout_above="@id/paneldown"/>
<LinearLayout
android:id="@+id/paneldown"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<EditText
android:id="@+id/quantity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:layout_weight="2"
/>
<Spinner
android:id="@+id/mu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/mu_values"
android:layout_weight="2"
/>
<Button
android:id="@+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="+"
/>
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/layoutmain"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:padding="2dip"
android:text="M"/>
<TextView
android:id="@+id/id"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:padding="2dip"
android:paddingRight="10dip"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:padding="2dip"
android:paddingRight="10dip"
android:text="-" />
<TextView
android:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="2dip"/>
</LinearLayout>
<TextView
android:id="@+id/quantity"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="2dip"/>
<CheckBox
android:id="@+id/checkboxmain2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<Button
android:id="@+id/editordelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="EDIT or DELETE"/>
</LinearLayout>
public class SQLiteHelper extends SQLiteOpenHelper {
public static final String MYDATABASE_NAME = "mydatabase";
public static final int MYDATABASE_VERSION = 1;
public static final String MYDATABASE_TABLE = "mytable";
SQLiteDatabase mDB;
public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,int version) {
super(context, name, factory, version);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crt_tbl_sql = "CREATE TABLE IF NOT EXISTS " + MYDATABASE_TABLE + "(" +
SQLiteAdapter._id + " INTEGER PRIMARY KEY, " +
SQLiteAdapter.KEY_NAME + " TEXT, " +
SQLiteAdapter.KEY_SHOP + " TEXT, " +
SQLiteAdapter.KEY_PDATE + " TEXT, " +
SQLiteAdapter.KEY_PRICE + " REAL, " +
SQLiteAdapter.KEY_QUANTITY + " INTEGER, " +
SQLiteAdapter.KEY_MU + " TEXT, " +
SQLiteAdapter.KEY_CHECKED + " INTEGER DEFAULT 0" +
")";
db.execSQL(crt_tbl_sql);
addSomeTestingData(db,10);
}
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long addRow(String name, String shop, String pdate, double price, int quantity, String mu, SQLiteDatabase db) {
ContentValues cv = new ContentValues();
cv.put(SQLiteAdapter.KEY_NAME,name);
cv.put(SQLiteAdapter.KEY_SHOP,shop);
cv.put(SQLiteAdapter.KEY_PDATE,pdate);
cv.put(SQLiteAdapter.KEY_PRICE,price);
cv.put(SQLiteAdapter.KEY_QUANTITY,quantity);
cv.put(SQLiteAdapter.KEY_MU,mu);
return db.insert(MYDATABASE_TABLE,null,cv);
}
private void addSomeTestingData(SQLiteDatabase db, int number_to_add) {
for (int i = 0; i < number_to_add;i++) {
String suffix = String.valueOf(i);
String day_in_month = suffix;
if (i < 10) {
day_in_month = "0" + day_in_month;
}
addRow(
"Test" + suffix,
"Shop" + suffix,
"2019-01-" + day_in_month,
10.5 + new Double(i * 3),
i * 4,
"mu" + suffix,
db
);
}
}
}
public class SQLiteAdapter {
SQLiteDatabase sqLiteDatabase;
SQLiteHelper sqLiteHelper;
Context context;
public static final String KEY_CHECKED = "checked";
public static final String _id = BaseColumns._ID;
public static final String KEY_NAME = "name";
public static final String KEY_QUANTITY = "quantity";
public static final String KEY_PRICE = "price";
public static final String KEY_MU = "mu";
public static final String KEY_PDATE = "pdate";
public static final String KEY_SHOP = "shop";
public SQLiteAdapter(Context context) {
this.context = context;
openToWrite();
}
public SQLiteAdapter openToWrite() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null,
MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
return this;
}
public void close() {
sqLiteHelper.close();
}
public long insertChecked(boolean data1) {
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_CHECKED, data1);
return sqLiteDatabase.insert(MYDATABASE_TABLE, null, contentValues);
}
public int updateChecked(long id,int check) {
ContentValues cv = new ContentValues();
cv.put(KEY_CHECKED,check);
String whereclause = _id + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
return sqLiteDatabase.update(MYDATABASE_TABLE,cv,whereclause,whereargs);
}
public Cursor queueAll() {
String[] columns = new String[]{_id, KEY_NAME, KEY_PRICE,
KEY_QUANTITY, KEY_MU,
KEY_PDATE, KEY_SHOP, KEY_CHECKED};
Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, columns,
null, null, null, null, null);
return cursor;
}
public Cursor queueOneById(long id) {
String whereclause = _id + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
String[] columns = new String[]{_id, KEY_NAME, KEY_PRICE,
KEY_QUANTITY, KEY_MU,
KEY_PDATE, KEY_SHOP, KEY_CHECKED};
return sqLiteDatabase.query(MYDATABASE_TABLE,columns,whereclause,whereargs,
null,null,null);
}
public int delete(long id) {
String whereclause = SQLiteAdapter._id + "=?";
String[] wherargs = new String[]{String.valueOf(id)};
return sqLiteDatabase.delete(MYDATABASE_TABLE,whereclause,wherargs);
}
public long updateById(long id, String column_to_change, String newvalue) {
ContentValues cv = new ContentValues();
cv.put(column_to_change,newvalue);
String whereclause = SQLiteAdapter._id + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
return sqLiteDatabase.update(MYDATABASE_TABLE,cv,whereclause,whereargs);
}
}
public class MyCursorAdapter extends CursorAdapter {
SQLiteAdapter sqliteAdapter;
MyCursorAdapter thisCursorAdapter;
public MyCursorAdapter(Context context, Cursor c) {
super(context, c, true);
sqliteAdapter = new SQLiteAdapter(context);
thisCursorAdapter = this;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
return v;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.row,parent,false);
}
@Override
public void bindView(View view, Context context, final Cursor cursor) {
//Note Cursor will be positioned appropriately
TextView name = (TextView) view.findViewById(R.id.name);
TextView id = (TextView) view.findViewById(R.id.id);
TextView quantity = (TextView) view.findViewById(R.id.quantity);
CheckBox cb = (CheckBox) view.findViewById(R.id.checkboxmain2);
Button eod = (Button) view.findViewById(R.id.editordelete);
name.setText(cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_NAME)));
id.setText(cursor.getString(cursor.getColumnIndex(SQLiteAdapter._id)));
quantity.setText(cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_QUANTITY)));
cb.setChecked(cursor.getInt(cursor.getColumnIndex(SQLiteAdapter.KEY_CHECKED)) > 0);
cb.setTag(cursor.getString(cursor.getColumnIndex(SQLiteAdapter._id))); //<<<<<<<<<< SET TAG to the ID
eod.setTag(cursor.getString(cursor.getColumnIndex(SQLiteAdapter._id)));
// dynamically add the listeners as opposed to coding onCLick in layout XML
eod.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// get the id from the id TextView, within the view hierarchy rather than from the buttons tag
// NOTE assumes the Button's parent is a LinearLayout (for simplicity)
// This in theory is the recommended way rather than setting the tag
LinearLayout ll = (LinearLayout) v.getParent();
TextView id = ll.findViewById(R.id.id), name = ll.findViewById(R.id.name);
final long item_id_fromview = Long.valueOf(id.getText().toString());
final String item_name = name.getText().toString();
// get the id from the tag
long item_id_fromtag = Long.valueOf(v.getTag().toString());
// get the if from the cursor that is the source of the Listview, it should be positioned accordingly
long item_id_fromcursor = cursor.getLong(cursor.getColumnIndex(SQLiteAdapter._id));
// Show both
Toast.makeText(v.getContext(),
"The id (from the view hierarchy) is " + String.valueOf(item_id_fromview) +
" or (from the tag) is " + String.valueOf(item_id_fromtag) +
" or (from the cursor) is" + String.valueOf(item_id_fromcursor)
, Toast.LENGTH_SHORT).show();
AlertDialog.Builder mydialog = new AlertDialog.Builder(v.getContext());
mydialog.setMessage("EDIT or DELETE Row:- ID: " + String.valueOf(item_id_fromview) + "Name: " + item_name);
mydialog.setPositiveButton("DELETE", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sqliteAdapter.delete(item_id_fromview);
refreshList();
}
});
mydialog.setNeutralButton("EDIT", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
sqliteAdapter.updateById(item_id_fromview,SQLiteAdapter.KEY_NAME,item_name + " Updated");
refreshList();
}
});
mydialog.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
mydialog.show();
}
});
}
private void refreshList() {
thisCursorAdapter.swapCursor(sqliteAdapter.queueAll());
thisCursorAdapter.notifyDataSetChanged();
}
}
public class AndroidSQLite extends AppCompatActivity {
ListView listContent;
Button buttonAdd;
Cursor cursor;
SQLiteAdapter mySQLiteAdapter;
EditText name, quantity;
Spinner mu;
//SimpleCursorAdapter cursorAdapter; //<<<<<<<<<< NOT USED ANYMORE
MyCursorAdapter myadapter; //<<<<<<<<<< Use a custom adapter that sets the tag of the checkbox to the respective id
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listContent = (ListView) findViewById(R.id.contentlist);
name = (EditText) findViewById(R.id.name);
quantity = (EditText) findViewById(R.id.quantity);
buttonAdd = (Button) findViewById(R.id.add);
mu = (Spinner) findViewById(R.id.mu);
handleAddButton();
mySQLiteAdapter = new SQLiteAdapter(this);
mySQLiteAdapter.openToWrite();
manageListView(); //<<<<<<<<<< ADDED
}
//<<<<<<<<<< ADDED >>>>>>>>>>
@Override
protected void onResume() {
super.onResume();
manageListView(); //Refresh the List when resuming e.g. returning from another activity
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
cursor.close(); //<<<<<<<<<< SHOULD ALWAYS CLOSE CURSOR
mySQLiteAdapter.close();
}
private void handleAddButton() {
buttonAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if ((name.getText().toString()).length() < 1) {
Toast.makeText(v.getContext(),"Name cannot be empty",Toast.LENGTH_SHORT).show();
name.requestFocus();
return;
}
if ((quantity.getText().toString()).length() < 1) {
Toast.makeText(v.getContext(),"Quantity cannot be empty",Toast.LENGTH_SHORT).show();
quantity.requestFocus();
return;
}
mySQLiteAdapter.sqLiteHelper.addRow(
name.getText().toString(),
// Arbritary values for testing
"2019-01-01",
"The Shop",
100.33,
Integer.valueOf(quantity.getText().toString()),
mu.getSelectedItem().toString(),
mySQLiteAdapter.sqLiteDatabase
);
manageListView();
}
});
}
private void manageListView() {
cursor = mySQLiteAdapter.queueAll(); // get the source data (cursor) for the listview
if (myadapter == null) {
myadapter = new MyCursorAdapter(this,cursor);
listContent.setAdapter(myadapter);
} else {
myadapter.swapCursor(cursor);
}
}
}
答案 1 :(得分:0)
Cursor cursor = (Cursor) parent.getItemAtPosition(id)
;将根据项目在列表中的位置获取该项目,但是您使用的是id(从按钮的Tag中提取)作为位置。即使是正确的,这也很少。
列表中的第一个位置为0,第一个ID为1(假设没有删除任何行,并且您没有手动设置ID),因此报告了症状。
如果已删除行,则每个丢失的ID都会增加ID和位置之间的差异。如果以id以外的其他顺序对行进行排序,则位置v id可能会掉线。如果where子句排除行,则id和位置也会再次变化。
一个简单的事实是,您不能依赖id和列表中位置之间的任何关系。
您可以做的是使用Tag中的ID来查询数据库以提取特定行。该查询将与用于获取列表的游标的查询相同,不同之处在于它将使用第三个(SQLiteAdapter._id + "=?"
)和第四个参数(new String[]{String.valueOf(id)}
)(如果使用查询便捷方法)
我尝试添加我在上一条评论中编写的代码,但这是错误的。我不 知道如何实施您的更改。 –
您的代码可能是:-
public void ListViewButtonHandler(View v){
Button bt = v.findViewById(R.id.rowalertdialog);
Toast.makeText(this, "You clicked the Button for ID " + (String)bt.getTag(), Toast.LENGTH_SHORT).show(); //TODO not needed
int id = Integer.valueOf((String) bt.getTag());
ListView parent = (ListView)findViewById(R.id.contentlist); //<<<<<<<<<< NOT NEEDED (I think)
String whereclause = SQLiteAdapter._id _ "=?"; //<<<<<<<<<< ADDED
String[] whereargs = new String[]{bt.getTag()}; //<<<<<<<<<< ADDED
Cursor cursor = mySQLiteAdapter.getWitableDatabase().query(SQLiteAdapter.MYDATABASE_TABLE,null,whereclause,whereargs,null,null,null); //<<<<<<<<<< ADDED
//Cursor cursor = (Cursor) parent.getItemAtPosition(id); //<<<<<<<<<< REMOVED/COMMENTED OUT
//<<<<<<<<<<< ADDED to move to the extracted row, will toast if no such row
if (!cursor.moveToFirst) {
Toast.makeText(this, "Unable to retrieve row for ID " + (String)bt.getTag(), Toast.LENGTH_SHORT).show();
return;
}
final int item_id = cursor.getInt(cursor.getColumnIndex(SQLiteAdapter._id));
String item_name = cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_NAME));
String item_quantity = cursor.getString(cursor.getColumnIndex(SQLiteAdapter.KEY_QUANTITY))
cursor.close(); //<<<<<<<<<< ADDED should always close a cursor when done with it
.......... the rest of the code
请注意评论
注意,您可能需要将 SQLiteAdapter.MYDATABASE_TABLE 更改为适当的值。
请注意,上面的代码是内部代码,尚未经过测试或运行,因此可能会有一些错误
如果您将以下方法(基于上一个问题)添加到SQLiteAdapter.java中:-
public Cursor queueOneById(long id) {
String whereclause = _id + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
String[] columns = new String[]{_id, KEY_NAME, KEY_PRICE,
KEY_QUANTITY, KEY_MU,
KEY_PDATE, KEY_SHOP, KEY_CHECKED};
return sqLiteDatabase.query(MYDATABASE_TABLE,columns,whereclause,whereargs,
null,null,null);
}
然后您可以更改
Cursor cursor = mySQLiteAdapter.getWitableDatabase().query(SQLiteAdapter.MYDATABASE_TABLE,null,whereclause,whereargs,null,null,null);
收件人
Cursor cursor = mySQLiteAdapter.queueOneById(id);
请注意,这仍然需要上面的其他更改。那是你需要的:-
如果(!cursor.moveToFirst){ Toast.makeText(this,“无法检索ID的行” +(String)bt.getTag(),Toast.LENGTH_SHORT).show(); 返回; }
没有上面的代码。光标将位于位置 -1 (在第一行之前)。因此,需要 cursor.moveToFirst 定位到提取的行(只能是一行)。如果没有行,则moveToFirst将返回false(无法完成移动),并且将发出Toast,然后将返回onClick方法。