SQLite
 sql >> Database >  >> RDS >> SQLite

È possibile eliminare le voci del database aggiunte dagli elementi con il pulsante?

Risposta alternativa

Quello che segue è il codice per un esempio piuttosto semplice, ma funzionante. Tuttavia, va un po' oltre incorporando una ListView e consentendo l'eliminazione facendo clic lungo su un elemento in ListView .

Tuttavia, questo non utilizza frammenti.

Ci sono 3 pezzi di codice, MainActivity (MainActivity.java ), La sottoclasse SQLiteOpenHelper CrimeDBHelper (CrimeDBHelper.java ) e il layout per MainActivity, activity_main.xml :-

activity_main.xml

Questo è piuttosto semplice. Tieni presente che include una Vista elenco alla fine.

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="The Crime Thing"
    android:layout_gravity="center"
    android:textStyle="bold"/>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="Crime Title"
        />
    <EditText
        android:id="@+id/crimetitle"
        android:layout_width="0dp"
        android:layout_weight="3"
        android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="Crime Date"
        />
    <EditText
        android:id="@+id/crimedate"
        android:layout_width="0dp"
        android:layout_weight="3"
        android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="Suspect"
        />
    <EditText
        android:id="@+id/crimesuspect"
        android:layout_width="0dp"
        android:layout_weight="3"
        android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="Crime Solved?"
        />
    <CheckBox
        android:id="@+id/crimesolved"
        android:layout_width="0dp"
        android:layout_weight="3"
        android:layout_height="wrap_content" />
</LinearLayout>
<Button
    android:id="@+id/addcrime"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="ADD CRIME"/>
<Button
    android:id="@+id/dltcrime"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="DLT CRIME (ID=?)"/>
<ListView
    android:id="@+id/crimelist"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
</ListView>

CrimeDBHelper.java

La maggior parte è simile, ad eccezione del metodo aggiuntivo getCrimeList() , questo restituisce un Cursor che contiene tutti i dati della tabella dei reati (usata per popolare ListView).

public class CrimeDBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "crimesdb";
    public static final int DBVERSION = 1;
    public static final String CRIMESTABLE = "crimes";
    public static final String CRIMEID_COL = "_id";
    public static final String CRIMETITLE_COL = "crimetitle";
    public static final String CRIMEDATE_COL = "crimedate";
    public static final String CRIMESUSPECT_COL = "crimesuspect";
    public static final String CRIMESOLVED_COL = "crimesolved";


    public static final String TABLECRTSQL =
            "CREATE TABLE " + CRIMESTABLE + "(" +
                    CRIMEID_COL + " INTEGER PRIMARY KEY," +
                    CRIMETITLE_COL + " TEXT," +
                    CRIMEDATE_COL + " TEXT, " +
                    CRIMESUSPECT_COL + " TEXT, " +
                    CRIMESOLVED_COL + " INTEGER" +
                    ");";

    public CrimeDBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(TABLECRTSQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {
    }

    public long addCrime(String crimetitle, String crimedate, String crimesuspect, int crimesolved) {

        SQLiteDatabase db = getWritableDatabase();

        ContentValues cv = new ContentValues();
        cv.put(CRIMETITLE_COL,crimetitle);
        cv.put(CRIMEDATE_COL,crimedate);
        cv.put(CRIMESUSPECT_COL,crimesuspect);
        cv.put(CRIMESOLVED_COL,crimesolved);
        return db.insert(CRIMESTABLE,null,cv);
    }

    public int deleteCrime(long crimeid) {
        SQLiteDatabase db = getWritableDatabase();
        String whereclause = CRIMEID_COL + "=?";
        String[] whereargs = {Long.toString(crimeid)};
        return db.delete(CRIMESTABLE,whereclause,whereargs);
    }

    public Cursor getCrimeList() {
        SQLiteDatabase db = getWritableDatabase();
        return db.query(CRIMESTABLE,null,null,null,null,null,null,null);
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    EditText mCrimeTitle;
    EditText mCrimeDate;
    EditText mCrimeSuspect;
    CheckBox mCrimeSolved;

    Button mAddCrime;
    Button mDltCrime;
    ListView mCrimeList;

    CrimeDBHelper dbhlpr = new CrimeDBHelper(this);
    Cursor crimelist;
    SimpleCursorAdapter sca;

    long lastcrimeid;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mCrimeTitle = (EditText) findViewById(R.id.crimetitle);
        mCrimeDate = (EditText) findViewById(R.id.crimedate);
        mCrimeSuspect = (EditText) findViewById(R.id.crimesuspect);
        mCrimeSolved = (CheckBox) findViewById(R.id.crimesolved);
        mCrimeList = (ListView) findViewById(R.id.crimelist);
        mAddCrime = (Button) findViewById(R.id.addcrime);
        mDltCrime = (Button) findViewById(R.id.dltcrime);

        crimelist = dbhlpr.getCrimeList();

        // Setup Button to Add a crime
        mAddCrime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int solved = 0;
                if (mCrimeSolved.isChecked()) {
                    solved = 1;
                }
                lastcrimeid =  dbhlpr.addCrime(
                        mCrimeTitle.getText().toString(),
                        mCrimeDate.getText().toString(),
                        mCrimeSuspect.getText().toString(),
                        solved
                );
                mDltCrime.setText("DLT CRIME (ID=" + Long.toString(lastcrimeid) + ")");
                mDltCrime.setTag(lastcrimeid);
                crimelist = dbhlpr.getCrimeList();
                sca.swapCursor(crimelist);
            }
        });

        // Setup button to delete the latest Crime added
        mDltCrime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //dbhlpr.deleteCrime(lastcrimeid); can do it this way
                if (view.getTag() != null) {
                    dbhlpr.deleteCrime((long)view.getTag());
                    crimelist = dbhlpr.getCrimeList();
                    sca.swapCursor(crimelist);
                }
            }
        });

        sca = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_1,
                crimelist,
                new String[]{CrimeDBHelper.CRIMETITLE_COL},
                new int[]{android.R.id.text1},
                0
        );
        mCrimeList.setAdapter(sca);

        mCrimeList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                dbhlpr.deleteCrime(l);
                crimelist = dbhlpr.getCrimeList();
                sca.swapCursor(crimelist);
                return true;
            }
        });

    }

    protected void onDestroy() {
        super.onDestroy();
        if (crimelist != null) {
            crimelist.close();
        }

    }
}

La prima cosa da notare è la riga long lastcrimeid; , questo è dichiarato a livello di classe, quindi è molto disponibile in tutto (il problema che stavi riscontrando con long databaseID ).

Potresti anche notare SimpleCursorAdapter sca; questo verrà utilizzato per ListView (fondamentalmente posiziona i dati dal cursore nella ListView ).

Dovresti avere familiarità con gran parte del codice seguente. In sintesi:-

  • Viene chiamato super.onCreate.
  • L'attività è impostata per utilizzare il layout activity_main.xml.
  • Quando il layout è stato caricato, si ottengono gli ID associati alle viste.
  • Si ottiene un cursore ottenendo i crimini in corso dal database (potrebbe essere nessuno, questo non è un problema).

  • viene aggiunto il pulsante listener per l'aggiunta di un crimine. Tieni presente che questo utilizza il _id restituito della riga aggiunta due volte (in realtà 3 volte poiché cambia di conseguenza il testo dei pulsanti di eliminazione ).

    • lastcrimeid è impostato dal ritorno di addCrime() metodo.
    • mDltCrime.setTag(lastcrimeid); imposta il tag del pulsante di eliminazione su _id della riga aggiunta.

    • Si noti inoltre che esistono due righe aggiuntive, vale a dire crimelist = dbhlpr.getCrimeList(); e sca.swapCursor(crimelist); .

      • Il primo sostituisce il cursore con ciò che è ora nel database (cioè include la riga che è stata aggiunta), il secondo dice a ListView di usare il nuovo cursore, quindi fa in modo che ListView mostri ciò che è ora nel database ( questo viene utilizzato di nuovo quando si elimina una riga).
    • viene quindi aggiunto il listener di pulsanti per il pulsante di eliminazione. Questo può funzionare in due modi. Il lastcrimeid può essere utilizzato o in alternativa il tag del pulsante può essere utilizzato poiché entrambi tengono il _id della riga da eliminare. Il codice ha il primo commentato, quindi viene utilizzato il secondo metodo (ovvero viene recuperato il valore nel tag del pulsante).

      • Nota che quest'ultimo metodo ha lo svantaggio che il valore può essere nullo, il che causerebbe un'eccezione del puntatore nullo, da cui il if (view.getTag != null) .
    • Come sopra per aggiornare ListView .

    • Successivamente viene configurato SimpleCursorAdapter, richiede 5 parametri:-

      • il layout da utilizzare (android.R.layout.simple_list_item_1) è un layout stock.
      • i dati da utilizzare sotto forma di Cursore. NOTA! una colonna denominata _id DEVE esistere (generalmente una buona idea usare sempre _id INTEGER PRIMARY KEY per questo. ) Nota che otteniamo un cursore crimelist tramite getCrimeList metodo.
      • La/le colonna/e nel cursore da cui devono essere recuperati i dati.
      • Le viste nel layout in cui verranno inseriti i dati recuperati.
      • Un valore di cui non ricordo lo scopo. Comunque 0 va bene da usare. La mancata codifica di questo quinto parametro probabilmente risulterà in un messaggio obsoleto.
      • (Nota che di solito uso CursorAdapter personalizzati in quanto sono molto più flessibili, quindi uso raramente Simples).
  • Quindi a ListView viene detto di utilizzare l'adattatore come da mCrimeList.setAdapter(sca); .

  • Quindi un onItemLongClickListener viene aggiunto a ListView, che eliminerà il crimine su cui è stato fatto un clic prolungato (long l è il _id value, quindi un motivo per cui un CursorAdapter ha bisogno di _id e quindi perché dbhlpr.deleteCrime(l); ).

    • Di nuovo la Vista elenco viene aggiornato.
  • Infine, poiché il cursore viene utilizzato mentre l'attività rimane in uso onDestory viene utilizzato per chiudere il cursore (i cursori devono essere sempre chiusi al termine).

Ecco come appare (non carino ma funzionale), con l'aggiunta di tre crimini (il pulsante Elimina rimuoverebbe Il crimine del secolo reato). Fare clic a lungo su qualsiasi crimine elencato eliminerà quel crimine. Facendo clic su aggiungi si aggiungerebbe un'altra voce per Crime of the Century a meno che i dati non siano stati modificati.