Alternative Antwort
Das Folgende ist der Code für ein ziemlich einfaches, aber funktionierendes Beispiel. Es geht jedoch noch etwas weiter, indem es eine ListView einbindet und das Löschen durch langes Klicken auf ein Element in der ListView zuzulassen .
Dies verwendet jedoch keine Fragmente.
Es gibt 3 Codeteile, die MainActivity (MainActivity.java
), die SQLiteOpenHelper-Unterklasse CrimeDBHelper (CrimeDBHelper.java
) und das Layout für die MainActivity, activity_main.xml
:-
activity_main.xml
Das ist ziemlich einfach. Beachten Sie, dass es eine ListView enthält am Ende.
<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
Das meiste ist ähnlich, außer der zusätzlichen Methode getCrimeList()
, gibt dies einen Cursor zurück, der alle Daten aus der Verbrechenstabelle enthält (die zum Füllen der ListView verwendet wird).
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();
}
}
}
Als Erstes ist die Zeile long lastcrimeid;
zu beachten , dies wird auf Klassenebene deklariert, ist also überall verfügbar (das Problem, das Sie mit long databaseID
hatten ).
Möglicherweise bemerken Sie auch SimpleCursorAdapter sca;
dies wird für die ListView
verwendet (Im Grunde platziert es die Daten vom Cursor in der ListView ).
Sie sollten mit einem Großteil des folgenden Codes vertraut sein. Zusammenfassend:-
- super.onCreate wird aufgerufen.
- Die Aktivität ist so eingestellt, dass sie das Layout activity_main.xml verwendet.
- Sobald das Layout geladen wurde, werden die mit den Ansichten verknüpften IDs abgerufen.
-
Ein Cursor erhält die aktuellen Verbrechen aus der Datenbank (kann keine sein, das ist kein Problem).
-
Der Schaltflächen-Listener zum Hinzufügen eines Verbrechens wird hinzugefügt. Beachten Sie, dass dies die zurückgegebene _id verwendet der hinzugefügten Zeile zweimal (eigentlich dreimal, da es den Text der Löschschaltfläche entsprechend ändert ).
lastcrimeid
wird durch die Rückgabe vonaddCrime()
gesetzt Methode.-
mDltCrime.setTag(lastcrimeid);
setzt das Tag der Löschschaltfläche auf die_id
der hinzugefügten Zeile. -
Beachten Sie auch, dass zwei zusätzliche Zeilen vorhanden sind, nämlich
crimelist = dbhlpr.getCrimeList();
undsca.swapCursor(crimelist);
.- Die erste ersetzt den Cursor durch das, was sich jetzt in der Datenbank befindet (d. h. schließt die hinzugefügte Zeile ein), die zweite weist die ListView an, den neuen Cursor zu verwenden, sodass die ListView anzeigt, was sich jetzt in der Datenbank befindet ( wird beim Löschen einer Zeile wieder verwendet).
-
Anschließend wird der Schaltflächen-Listener für die Löschschaltfläche hinzugefügt. Dies kann auf zwei Arten funktionieren. Die
lastcrimeid
kann verwendet werden, oder alternativ kann das Tag der Schaltfläche verwendet werden, da beide die _id enthalten der zu löschenden Zeile. Der Code hat ersteres auskommentiert, also wird letztere Methode verwendet (d. h. der Wert im Tag der Schaltfläche wird abgerufen).- Beachten Sie, dass letztere Methode den Nachteil hat, dass der Wert null sein kann, was eine Nullzeiger-Ausnahme verursachen würde, daher der
if (view.getTag != null)
.
- Beachten Sie, dass letztere Methode den Nachteil hat, dass der Wert null sein kann, was eine Nullzeiger-Ausnahme verursachen würde, daher der
-
Wie oben zum Aktualisieren der ListView .
-
Als nächstes wird der SimpleCursorAdapter eingerichtet, er braucht 5 Parameter:-
- das zu verwendende Layout (android.R.layout.simple_list_item_1) ist ein Bestandslayout.
- die zu verwendenden Daten in Form eines Cursors. HINWEIS! eine Spalte namens _id MUSS vorhanden sein (im Allgemeinen ist es eine gute Idee, immer
_id INTEGER PRIMARY KEY
zu verwenden aus diesem Grund. ) Beachten Sie, dass wir einen Cursorcrimelist
erhalten über diegetCrimeList
Methode. - Die Spalte(n) im Cursor, aus der die Daten abgerufen werden sollen.
- Die Ansicht(en) im Layout, wo die abgerufenen Daten platziert werden.
- Ein Wert, an dessen Zweck ich mich nicht erinnern kann. 0 ist jedoch gut zu verwenden. Das Nichtcodieren dieses fünften Parameters führt wahrscheinlich zu einer veralteten Meldung.
- (Beachte, dass ich normalerweise benutzerdefinierte CursorAdapter verwende, da sie viel flexibler sind, also verwende selten Simples).
-
Dann wird der ListView mitgeteilt, den Adapter gemäß
mCrimeList.setAdapter(sca);
zu verwenden . -
Dann ein
onItemLongClickListener
wird der ListView hinzugefügt, wodurch das Verbrechen gelöscht wird, auf das lange geklickt wurde (langes l ist die _id Wert, daher ein Grund, warum ein CursorAdapter _id benötigt und daher warumdbhlpr.deleteCrime(l);
).- Nochmals die ListView wird aktualisiert.
-
Schließlich, wenn der Cursor verwendet wird, während die Aktivität verwendet wird
onDestory
Methode wird verwendet, um den Cursor zu schließen (Cursors sollten immer geschlossen werden, wenn sie fertig sind).
So sieht es aus (nicht hübsch, aber funktional), mit drei hinzugefügten Verbrechen (Die Schaltfläche „Löschen“ würde das Verbrechen des Jahrhunderts entfernen Verbrechen). Durch langes Klicken auf ein aufgelistetes Verbrechen wird dieses Verbrechen gelöscht. Wenn Sie auf Hinzufügen klicken, wird ein weiterer Eintrag für Verbrechen des Jahrhunderts hinzugefügt, sofern die Daten nicht geändert wurden.