簡體   English   中英

Android 工作室列表視圖更改項目

[英]Android studio listview change item

誰能幫我更改列表視圖中的項目名稱? 我不知道該怎么做。 我正在使用 SQLite 數據庫,這是我的更新名稱:

public void doneName(String finishedName,int id, String oldName)
    {

        SQLiteDatabase db = this.getWritableDatabase();
        String query = "UPDATE " + TABLE_NAME + " SET " + COL2 + " = '" + finishedName + "' WHERE " + COL1 +
                " = '" + id + "'" + " AND " + COL2 + " = '" + oldName + "'";
        db.execSQL(query );
    }

之后在我的活動中,我設置了 onItemClickListener 應該更改名稱但它沒有,它只顯示吐司:

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String name = parent.getItemAtPosition(position).toString();
                Cursor cursor =th.getItemID(name);
                int itemID = -1;
                while(cursor.moveToNext())
                {
                    itemID = cursor.getInt(0);
                }
                if(itemID>-1) {
                    String item = "Done";
                    th.doneName(item, selectedID, selectedName);
                    Toast.makeText(HomePageActivity.this, "You have accomplished this task!", Toast.LENGTH_SHORT).show();
                }}
        });

恐怕你沒有更新相關適配器項的實例。 如果您有與此 ListView 適配器連接的字符串列表,您應該使用您要顯示的名稱初始化相關 position 中的字符串項。 然后調用 Adapter.notifyDataSetChanged 用更新后的列表刷新 ListView 中的所有 UI 元素。

看來,您永遠不會更新適配器列表中的 String 實例

你的問題是雙重的。

  1. 首先,您沒有從數據庫中提取更新的數據(您可以假設基礎數據已被更新,這是有風險的)。
  2. 您沒有使用更改刷新 Listview,因此它顯示了它知道的數據。

我建議使用CursorAdapter可以簡化問題,因為 Cursor 適配器設計用於光標,它們特別使所有數據都可以通過適配器輕松獲得,因為 Cursor 通常位於適當的行(例如,當使用 onItemClick 和 onItemLongClick 時)

以下是一個基於您的代碼的示例,該代碼利用SimpleCursorAdapter在單擊列表中的項目時更改數據庫和列表視圖(演示單擊同一行而不是將測試更改為 Done 它會反轉文本,因此它將翻轉每次點擊)。

However, to use a Cursor Adapoter you MUST have a column named _id and that column should be a unique integer (should really be a long rather than int) and typically it would be an alias of the rowid (ie defined using _id INTEGER PRIMARY KEY (有或沒有自動增量,最好沒有))。 因此,有一個常量 BaseColumns._ID 包含值_id

首先是DatabaseHelper (SQLiteOpenHelper 的子類)在這種情況下DatabaseHelper.java :-

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final  int DBVERSION = 1;

    public static final String TABLE_NAME = "mytable";
    /*<<<<<<<<<< id column must be _id (BaseColumns._ID) for Cursor Adapters >>>>>>>>>*/
    public static final String COLID = BaseColumns._ID;
    public static final String COL1 = "mycol1";
    public static final String COL2 = "mycol2";

    public DatabaseHelper(@Nullable Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
                COLID + " INTEGER PRIMARY KEY, " +
                COL1 + " TEXT, " +
                COL2 + " TEXT " +
                ")"
        );
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long insert(String col1, String col2) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COL1,col1);
        cv.put(COL2,col2);
        return db.insert(TABLE_NAME,null,cv);
    }

    public int doneName(String finishedName,int id, String oldName) {

        /*
            Alternative using the update convenience method
            Based upon :-
            String query = "UPDATE " + TABLE_NAME + " SET " + COL2 + " = '" + finishedName + "' WHERE " + COL1 +
                " = '" + id + "'" + " AND " + COL2 + " = '" + oldName + "'";

                writes the SQL for you.
                protects against SQL Injection
                returns the number of rows updated
         */
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COL2,finishedName);
        return db.update(TABLE_NAME,cv,COLID + "=? AND " + COL2 + "=?",new String[]{String.valueOf(id),oldName});
    }

    public Cursor getAll() {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.query(TABLE_NAME,null,null,null,null,null,null);
    }
}
  • 三個自定義方法insert (插入一行)、 getAll (返回包含所有行的 Cursor)和您的doneName方法(重寫以利用方便的更新方法)。

  • 您可能會注意到沒有任何方法可以將提取的數據轉換為 List/ArrayList/Array 對象。 這是因為在使用 Cursor 適配器時不需要。

活動MainActivity.java

public class MainActivity extends AppCompatActivity {

    ListView mListView;
    DatabaseHelper th;
    Cursor csr;
    SimpleCursorAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = this.findViewById(R.id.listview);
        th = new DatabaseHelper(this);
        addSomeTestData();
        manageAdapter();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        csr.close(); //<<<<<<<<<< Should always close Cursors when done with them
    }

    private void manageAdapter() {
        /* This handles but the initialisation and the refreshing of the Listview */
        /* First time it is called it initialises the Adapter and Listview */
        /* On subsequent calls it refreshes the ListView */
        csr = th.getAll();
        if (adapter == null) {
            adapter = new SimpleCursorAdapter(
                    this,
                    android.R.layout.simple_expandable_list_item_2,csr,
                    new String[]{
                            DatabaseHelper.COL1,
                            DatabaseHelper.COL2
                    },
                    new int[]{
                            android.R.id.text1,
                            android.R.id.text2},
                    0
            );
            mListView.setAdapter(adapter);
            mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    if (th.doneName(
                            /* reverses string to test multiple updates of the same row */
                            new StringBuilder(csr.getString(csr.getColumnIndex(DatabaseHelper.COL2))).reverse().toString()
                            /* "Done" */,
                            (int )id /* NOTE ID IS PASSED to onItemClick FOR CURSOR ADAPTER */,
                            csr.getString(csr.getColumnIndex(DatabaseHelper.COL2)) /* NOTE Oldname isn't required as ID will identify the row */
                    ) > 0) {
                        manageAdapter(); //<<<<<<<<< after updating refresh the Cursor and the ListView
                        Toast.makeText(view.getContext(),"Updated OK.",Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(view.getContext(),"Not Updated!!!",Toast.LENGTH_SHORT).show();
                    }
                }
            });
        } else {
            adapter.swapCursor(csr);
        }
    }

    private void addSomeTestData() {
        //Add some data but only if none exists
        if (DatabaseUtils.queryNumEntries(th.getWritableDatabase(),DatabaseHelper.TABLE_NAME) > 0) return;
        th.insert("TEST1 COL1","TEST1 COL2");
        th.insert("TEST2 COL1","TEST2 COL2");
        th.insert("TEST3 COL1","TEST3 COL2");
        th.insert("TEST4 COL1","TEST4 COL2");
        th.insert("TEST5 COL1","TEST5 COL2");
    }
}
  • 請注意,您可以將自己的布局與 SimpleCursorAdapter 一起使用(第 4 個(String[])和第 5 個(int[])用於指定數據來自的列以及數據進入相應視圖的 id)

結果:-

最初運行時,您會得到:-

在此處輸入圖像描述

單擊一行,您將獲得:-

在此處輸入圖像描述

如果然后單擊您獲得的所有行:-

在此處輸入圖像描述

等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM