sql >> データベース >  >> RDS >> SQLite

OnItemClickListenerを使用してListViewおよびデータベースからアイテムを削除する

    つまり、ListViewで使用可能なデータによって、削除する行を区別できる必要があります。値がカーソルから取得された場合、2番目の列(つまり、res.getString(1))そして価値はユニークになります 、これを取得して削除に使用できます。

    ただし、ListAdapterを使用すると、いくつかの問題が発生します。 おそらく十分ではないでしょう。より多くの機能を提供するArrayAdapterなどの他のアダプターがあり、重要なのは notifyDatasetChanged メソッド(関連付けられたListViewを更新します)。

    カーソルの反復ごとに新しいアダプタを作成するのは無駄です。したがって、アダプタはループの外側で1回だけ作成する必要があります。

    アイテムのクリックで削除すると、誤ってクリックする可能性が低くなり、アイテムのLongClickで削除すると、誤って削除される可能性がはるかに低くなることをお勧めします。

    変数をクラス変数に移動する場合、それらをfinalとして宣言する必要はありません。

    したがって、上記に基づいて、次のようになります:-

    アレイアダプタメソッド

    public class ZeigeFaecherListe extends AppCompatActivity {
    
        DatabaseHelper myDb;
        Cursor res;
        ListView listViewFaecher;
        ArrayAdapter<String> fachListAdapter;
        ArrayList<String> faecherListe;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.zeige_faecher);
    
            listViewFaecher = (ListView) this.findViewById(R.id.listview);
            myDb = new DatabaseHelper(this);
            addSomeData(); //<<<<<<<<<< ADDED for testing
    
            faecherListe = new ArrayList<>();
            res = myDb.zeigeFaecher();
            while (res.moveToNext()) {
                faecherListe.add(res.getString(1));
            }
    
            //<<<< NOTE outside of the loop as this only needs to be done once
            fachListAdapter = new ArrayAdapter<String>(
                    this,
                    android.R.layout.simple_list_item_1,
                    faecherListe
            );
            listViewFaecher.setAdapter(fachListAdapter);
    
            //<<<<< NOTE used LONG CLICK listener (less likely to accidentally delete)
            listViewFaecher.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    myDb.deleteRow((String)fachListAdapter.getItem(position));
                    faecherListe.remove(position);
                    fachListAdapter.notifyDataSetChanged(); 
                    return true; //<<<< Indicate that this longclick has been used
                }
            });
        }
    
        private void addSomeData() {
            for (int i=1; i <= 10; i++) {
                myDb.addRow("Row " + String.valueOf(i));
            }
        }
    }
    

    上記に加えて、 deletRow メソッドは:-

    public int deleteRow(String col2) {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.delete(TB001,COL_TB001_DATA + "=?",new String[]{col2});
    }
    
    • どこ
      • TB001 テーブルの名前に設定される定数文字列です。
      • COL_TB001_DATA 2番目の列の列名です。

    警告 上記の解決策は、2番目の列に一意のデータが含まれている場合にのみ正しく機能します。含まれていない場合、複数の行が削除されます。

    削除が機能するという仮定もあります:-

    を持っている方が良いかもしれません
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                if (myDb.deleteRow((String)fachListAdapter.getItem(position))<0) {
                    faecherListe.remove(position);
                }
                fachListAdapter.notifyDataSetChanged(); 
                return true; //<<<< Indicate that this longclick has been used
            }
    

    カーソルアダプタ方式

    ただし、中間配列の必要性をなくすことができるカーソルに適した他のアダプターがあります。 CursorAdapterを利用できます CursorAdapterの場合 列名_id が必要であり、この列は長いである必要があります また、行を不当に識別します。意図とその名前は、 rowidのエイリアスであるということです。 が使用されます(したがって、CONSTANT BaseColumns._IDも使用されます 存在します。

    rowidのエイリアス ?? INTEGER PRIMARY KEY どこ ??列名です。したがって、理想的には、_id INTEGER PRIMARY KEYを使用した列定義を含むテーブルを定義する必要があります。 例えばCREATE mytable (_id INTEGER PRIMARY KEY, myothercolumn TEXT) INTEGER PRIMARY KEYをフォローできます キーワードAUTOINCREMENTを使用しますが、SQLite Autoincrementのオーバーヘッドがあるため、通常はそうしません)

    テーブルにそのような列がない場合は、rowid AS _idを使用して、データをクエリするときにいつでもカーソルに列を作成できます。 例えばSQLがSELECT * FROM mytableと同等の場合 次に、SELECT *, rowid AS _id FROM mytableを使用できます。 。

    この例では、ストックの SimpleCursorAdapter 使用される場合、コードは次のようになります:-

    public class ZeigeFaecherListe extends AppCompatActivity {
    
        DatabaseHelper myDb;
        Cursor res;
        ListView listViewFaecher;
        SimpleCursorAdapter fachSimpleCursorAdapter;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.zeige_faecher);
    
            listViewFaecher = (ListView) this.findViewById(R.id.listview);
            myDb = new DatabaseHelper(this);
            addSomeData(); //<<<<<<<<<< ADDED for testing
    
            faecherListe = new ArrayList<>();
            res = myDb.zeigeFaecher();
            fachSimpleCursorAdapter = new SimpleCursorAdapter(this,
                    android.R.layout.simple_list_item_1, //<<<< The layout
                    res, //<<<< The Cursor
                    new String[]{"_data"}, //<<<< The column names from which to get the data
                    new int[]{android.R.id.text1} //<<<< The ids of the views in which the data is placed
                    );
            listViewFaecher.setAdapter(fachSimpleCursorAdapter);
            listViewFaecher.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    // id is the value of the respective _id column
                    //<<<< Normally you would have the delete method in the Databasehelper >>>>
                    myDb.getWritableDatabase().delete("mytable","_id=?",new String[]{String.valueOf(id)});
                    fachSimpleCursorAdapter.swapCursor(myDb.zeigeFaecher()); // Tell the adapter about the new cursor
                    return true;
                }
            });
        }
    }
    

    _idとして 列は常に一意になりますこのメソッドは、表示された値が一意でない場合、複数の行ではなく特定の行のみを削除します。



    1. PostgreSQLを使用している場合、役割が存在せず、データベースを作成できません

    2. PostgreSQL:JSON列から属性を削除します

    3. Ubuntu18.04にPostgreSQLをインストールします

    4. timeofday()がPostgreSQLでどのように機能するか