有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何修复使用#第二条记录而不是#第一条记录的游标(#第三条记录而不是#第二条记录等)?

布局只是主要的。显示多行的xml。将新信息添加到sqlite数据库时使用xml。单击按钮时,将显示包含数据的对话框。 问题是,当我单击行中的按钮时,AlertDialog从数据库中的下一条记录(下一行)获取数据(当我单击第一个按钮时,AD从第二条记录等),而不是从按钮所在的位置获取数据。 我为按钮和toast消息设置标签,点击时显示良好的ID

我的游标适配器。爪哇

(...)

@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)));
}

安德罗伊特。爪哇

(...)

private void manageListView() {
cursor = mySQLiteAdapter.queueAll();
if(myadapter == null){
    myadapter = new MyCursorAdapter(this,cursor);
    listContent.setAdapter(myadapter);
}else {
    myadapter.swapCursor(cursor);
}
}

点击按钮

 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.安卓sqlite, PID: 14453
 java.lang.IllegalStateException: Could not execute method for 安卓:onClick
    at 

安卓.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at 安卓.view.View.performClick(View.java:5646)
at 安卓.view.View$PerformClick.run(View.java:22459)
at 安卓.os.Handler.handleCallback(Handler.java:761)
at 安卓.os.Handler.dispatchMessage(Handler.java:98)
at 安卓.os.Looper.loop(Looper.java:156)
at 
安卓.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:831)
 Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at 安卓.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at 安卓.view.View.performClick(View.java:5646) 
at 安卓.view.View$PerformClick.run(View.java:22459) 
at 安卓.os.Handler.handleCallback(Handler.java:761) 
at 安卓.os.Handler.dispatchMessage(Handler.java:98) 
at 安卓.os.Looper.loop(Looper.java:156) 
at 安卓.app.ActivityThread.main(ActivityThread.java:6523) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941) 
at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:831) 
 Caused by: 安卓.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
at 安卓.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
at 安卓.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at 安卓.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:68)
at com.sjkdev.安卓sqlite.AndroidSQLite.ListViewButtonHandler(AndroidSQLite.java:307)

共 (1) 个答案

  1. # 1 楼答案

    Cursor cursor = (Cursor) parent.getItemAtPosition(id);将根据项目在列表中的位置获取项目,但您使用的是id(从按钮标签中提取的id)作为其位置。这几乎是不正确的

    列表中的第一个位置是0,第一个id将是1(假设没有删除任何行,并且您没有手动设置id),因此您报告的症状

    如果行已被删除,则每个缺少的id都会增加id和位置之间的差异。如果这些行是按id以外的任何其他顺序排序的,那么位置v id可能是错误的。如果where子句排除行,则id和位置也会发生变化

    简单的事实是,你不能依赖id和列表中的位置之间的任何关系

    您可以使用标记中的id来查询数据库,以提取特定的行。该查询将与用于获取列表光标的查询相同,只是它将使用第三个(SQLiteAdapter._id + "=?")和第四个参数(new String[]{String.valueOf(id)})(如果使用查询便利方法)

    • 注释已更正(缺少S添加到QLiteAdapter)自注释以来

    阿梅米德

    I tried add code as I wrote in last comment, but it's wrong. I don't know how to implement your changes. –

    您的代码可能是:-

    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添加了以下方法(基于上一个问题)。爪哇:-

    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){ 干杯makeText(这是“无法检索ID为“+(String)bt.getTag()的行”,Toast。长度(短)。show(); 回来 }

    • 没有上面的代码。光标将位于位置-1(第一行之前)。因此,光标。moveToFirst需要定位到提取的行(应仅为一行)。如果没有行,moveToFirst将返回false(移动无法完成),Toast将被发出,然后onClick方法将返回