亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何修復使用#2nd 記錄而不是#1st(#3rd 而不是#2nd 等)的游標?

如何修復使用#2nd 記錄而不是#1st(#3rd 而不是#2nd 等)的游標?

HUH函數 2022-11-02 16:49:24
布局只是 main.xml,它在將新信息添加到 sqlite 數據庫時顯示多個 row.xml。單擊按鈕時,將顯示帶有數據的 AlertDialog。問題是,當我單擊行中的按鈕時,AlertDialog 正在從數據庫中的下一條記錄(下一行)獲取數據(當我單擊第一個按鈕時,AD 正在獲取第二條記錄等),而不是從按鈕所在的位置獲取數據。我為按鈕和 toast 消息設置標簽,單擊它時顯示良好的 ID。MyCursorAdapter.java(...)@Overridepublic 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)));}安卓SQLite.java(...)private void manageListView() {cursor = mySQLiteAdapter.queueAll();if(myadapter == null){    myadapter = new MyCursorAdapter(this,cursor);    listContent.setAdapter(myadapter);}else {    myadapter.swapCursor(cursor);}}
查看完整描述

2 回答

?
PIPIONE

TA貢獻1829條經驗 獲得超9個贊

工作示例

這是一個基于您之前的問題和這個問題的工作示例應用程序。

然而,

  • 按鈕單擊處理,在不使用布局的onCLick(如 XML 中編碼)的情況下進行處理,但在自定義CursorAdapter ( MyCursorAdapter.java ) 的bindView方法中設置。

  • 它演示了 3 種獲取與按鈕關聯的 id 的方法

    • item_id_fromcursor顯示了如何從作為列表源的 Cursor 獲取值(在本例中為該 id),該列表的位置應適當。

    • item_id_fromtag展示了如何從標簽中獲取 id(有些人不贊成這種技術)。

    • item_id_fromview展示了如何根據傳遞給按鈕的視圖從視圖層次結構中獲取值。

該處理允許刪除和更新行(盡管更新非常基本,只是附加一個值而不是使用自定義對話框布局(您似乎掌握了這方面的知識))。

與前面的答案不同,還實現了處理添加的行(盡管值有限)。

生成的應用程序看起來像:-

http://img1.sycdn.imooc.com//63622f3300010cd905840854.jpg

  • A表示行已被刪除(即 id 為 5-7 的行不存在)

  • B顯示已更新的行(即已附加更新(如果更新更新則該行已更新兩次))

  • C顯示已添加的行。

如果單擊編輯或刪除按鈕,則會出現對話框,例如:-

http://img1.sycdn.imooc.com//63622f3e000129fc04850225.jpg

  • 單擊取消從對話框中返回,什么也不做。

  • 單擊刪除將刪除相應的行(如對話框消息中所述)。

  • 單擊 EDIT 通過附加更新的值來編輯名稱(編輯已經編輯的行將添加進一步更新的行)

    • 顯然這可能不是所需的操作,它只是為了演示。

編碼

activity_main.xml

<?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

<?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>

注意 CheckBox 已隱藏

SQLiteHelper.java

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

            );

        }

    }

}

SQLiteAdapter.java

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

    }

}

增加了一些方法

MyCursorAdapter.java

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();

    }

}

查看綁定視圖時如何設置 onCLickListener

查看獲取id的 3 種不同方法

請參閱類似于 AndroidSQLite 活動中使用的 ManageListView 方法的 refreshList 方法。

AndroidSQlite.java(活動)

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

        }

    }

}


查看完整回答
反對 回復 2022-11-02
?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

Cursor cursor = (Cursor) parent.getItemAtPosition(id); 將根據它在列表中的位置獲取項目,但您使用的是 id(從按鈕的標簽中提取)作為它的位置。這將很少是正確的。


列表中的第一個位置是 0,第一個 id 將是 1(假設沒有刪除任何行并且您沒有手動設置 id),因此您報告的癥狀。


如果行已被刪除,那么每個缺失的 id 都會增加 id 和 position 之間的差異。如果行按 id 以外的任何其他順序排序,則位置 v id 可能會出路。如果 where 子句不包括行,那么 id 和位置也會有所不同。


簡單的事實是您不能依賴 id 和列表中的位置之間的任何關系。


您可以做的是使用標簽中的 id 來查詢數據庫以提取特定行。該查詢將與用于獲取列表光標的查詢相同,只是它將使用第三個 ( SQLiteAdapter._id + "=?") 和第四個參數 ( new String[]{String.valueOf(id)}) (如果使用查詢便利方法)。


注釋已更正(缺少S添加到 QLiteAdapter),因為評論。

已修改

我嘗試添加我在上一條評論中寫的代碼,但這是錯誤的。我不知道如何實施您的更改。–


您的代碼可能是:-


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更改為適當的值。


注意上面的代碼是in-principal code,它沒有經過測試或運行,因此可能有一些錯誤


選擇

如果您將以下方法(基于上一個問題)添加到 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);

請注意,這仍然需要上述其他更改。那就是你需要:-


if (!cursor.moveToFirst) { Toast.makeText(this, "無法檢索 ID 行" + (String)bt.getTag(), Toast.LENGTH_SHORT).show(); 返回; }


沒有上面的代碼。光標將位于位置-1(在第一行之前)。所以cursor.moveToFirst需要定位到提取的行(應該只有一行)。如果沒有行,則 moveToFirst 將返回 false(無法完成移動)并且將發出 Toast,然后 onClick 方法將返回。


查看完整回答
反對 回復 2022-11-02
  • 2 回答
  • 0 關注
  • 129 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號