Alternativt svar
Det følgende er koden til et ret grundlæggende, men fungerende eksempel. Det går dog lidt længere ved at inkorporere en ListView og tillade sletning ved at Langklikke på et element i ListView .
Dette bruger dog ikke fragmenter.
Der er 3 kodestykker, MainActivity (MainActivity.java
), SQLiteOpenHelper-underklassen CrimeDBHelper (CrimeDBHelper.java
) og layoutet for MainActivity, activity_main.xml
:-
activity_main.xml
Dette er ret ligetil. Bemærk, at den indeholder en ListView til sidst.
<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
De fleste ligner hinanden, undtagen den ekstra metode getCrimeList()
, returnerer dette en markør, der indeholder alle data fra forbrydelsestabellen (bruges til at udfylde 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();
}
}
}
Den første ting at bemærke er linjen long lastcrimeid;
, dette er deklareret på klasseniveau, så det er meget tilgængeligt overalt (det problem du havde med long databaseID
).
Du vil måske også bemærke SimpleCursorAdapter sca;
dette vil blive brugt til ListView
(dybest set placerer det dataene fra markøren i ListView ).
Du bør være bekendt med meget af følgende kode. Sammenfattende:-
- super.onCreate kaldes.
- Aktiviteten er indstillet til at bruge layoutet activity_main.xml.
- Efterhånden som layoutet er blevet indlæst, opnås de id'er, der er knyttet til visningerne.
-
Der opnås en markør, der henter de aktuelle forbrydelser fra databasen (kan være ingen, dette er ikke et problem).
-
knaplytteren til tilføjelse af en forbrydelse tilføjes. Bemærk, at dette bruger det returnerede _id af den tilføjede række to gange (faktisk 3 gange, da den ændrer sletteknappernes tekst i overensstemmelse hermed ).
lastcrimeid
indstilles af returneringen af addCrime()
metode.-
mDltCrime.setTag(lastcrimeid);
indstiller tagget for sletteknappen til_id
af den tilføjede række. -
Bemærk også, at der findes to yderligere linjer, nemlig
crimelist = dbhlpr.getCrimeList();
ogsca.swapCursor(crimelist);
.- Den første erstatter markøren med det, der nu er i databasen (dvs. inkluderer rækken, der er blevet tilføjet), den anden fortæller ListView at bruge den nye markør, hvilket får ListView til at vise, hvad der nu er i databasen ( dette bruges igen, når en række slettes).
-
knaplytteren til sletknappen tilføjes derefter. Dette kan fungere på to måder.
lastcrimeid
kan bruges eller alternativt kan knappens tag bruges, da begge holder _id af rækken, der skal slettes. Koden har førstnævnte kommenteret ud, så den sidste metode bruges (dvs. værdien i knappens tag hentes).- Bemærk, at sidstnævnte metode har den ulempe, at værdien kan være null, hvilket ville forårsage en nul pointer-undtagelse, deraf
if (view.getTag != null)
.
- Bemærk, at sidstnævnte metode har den ulempe, at værdien kan være null, hvilket ville forårsage en nul pointer-undtagelse, deraf
-
Som ovenfor for at opdatere ListView .
-
Dernæst er SimpleCursorAdapteren sat op, det tager 5 parametre:-
- layoutet, der skal bruges (android.R.layout.simple_list_item_1) er et lagerlayout.
- de data, der skal bruges i form af en markør. BEMÆRK! en kolonne med navnet _id SKAL eksistere (generelt en god idé altid at bruge
_id INTEGER PRIMARY KEY
af denne grund. ) Bemærk, at vi får en markørcrimelist
viagetCrimeList
metode. - Kolonnen(e) i markøren, hvorfra dataene skal hentes.
- Den(e) visning(er) i layoutet, hvor de hentede data vil blive placeret.
- En værdi, som jeg ikke kan huske formålet med. Men 0 er fint at bruge. Hvis denne 5. parameter ikke kodes, vil det sandsynligvis resultere i en forældet besked.
- (Bemærk, at jeg normalt bruger Custom CursorAdapters, da de er meget mere fleksible, så bruger sjældent Simples).
-
Derefter får ListView besked om at bruge adapteren i henhold til
mCrimeList.setAdapter(sca);
. -
Derefter en
onItemLongClickListener
føjes til ListView, som vil slette den forbrydelse, der blev klikket længe på (langt l er _id værdi, deraf en grund til, at en CursorAdapter har brug for _id og derfor hvorfordbhlpr.deleteCrime(l);
).- Igen ListView er opdateret.
-
Til sidst, da markøren bruges, mens aktiviteten forbliver i brug
onDestory
metode bruges til at lukke markøren (markørerne skal altid lukkes, når du er færdig med).
Sådan ser det ud (ikke smukt, men funktionelt), med tre forbrydelser tilføjet (Slet-knappen ville fjerne Århundredes forbrydelse forbrydelse). Langt-klik på en listet forbrydelse vil slette denne forbrydelse. Hvis du klikker på tilføje, tilføjes endnu en post for Århundredets kriminalitet, medmindre dataene blev ændret.