Alternativt svar
Följande är koden för ett ganska grundläggande, men fungerande exempel. Det går dock lite längre genom att införliva en ListView och tillåta radering genom att långklicka på ett objekt i ListView .
Detta använder dock inte fragment.
Det finns tre stycken kod, MainActivity (MainActivity.java
), SQLiteOpenHelper-underklassen CrimeDBHelper (CrimeDBHelper.java
) och layouten för MainActivity, activity_main.xml
:-
activity_main.xml
Det här är ganska okomplicerat. Observera att den innehåller en ListView på slutet.
<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 flesta är liknande, förutom den extra metoden getCrimeList()
, returnerar detta en markör som innehåller all data från brottstabellen (används för att fylla i listvyn).
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();
}
}
}
Det första att notera är raden long lastcrimeid;
, detta deklareras på klassnivå så det är mycket tillgängligt genomgående (problemet du hade med long databaseID
).
Du kanske också märker SimpleCursorAdapter sca;
detta kommer att användas för ListView
(i princip placerar den data från markören i listvyn ).
Du bör vara bekant med mycket av följande kod. Sammanfattningsvis:-
- super.onCreate kallas.
- Aktiviteten är inställd på att använda layouten activity_main.xml.
- När layouten har laddats in erhålls id:erna som är kopplade till vyerna.
-
En markör erhålls som hämtar de aktuella brotten från databasen (kan vara inga, detta är inget problem).
-
knappavlyssnaren för att lägga till ett brott läggs till. Observera att detta använder det returnerade _id av den tillagda raden två gånger (faktiskt 3 gånger eftersom den ändrar texten på raderingsknapparna i enlighet därmed ).
lastcrimeid
ställs in av returen avaddCrime()
metod.-
mDltCrime.setTag(lastcrimeid);
ställer in taggen för raderingsknappen till_id
för den tillagda raden. -
Observera också att det finns två ytterligare rader, nämligen
crimelist = dbhlpr.getCrimeList();
ochsca.swapCursor(crimelist);
.- Den första ersätter markören med det som nu finns i databasen (dvs. inkluderar raden som har lagts till), den andra talar om för ListView att använda den nya markören, vilket gör att ListView visar vad som nu finns i databasen ( detta används igen när en rad raderas).
-
knappavlyssnaren för raderingsknappen läggs sedan till. Detta kan fungera på två sätt.
lastcrimeid
kan användas eller alternativt kan knappens tagg användas eftersom båda håller _id av raden som ska raderas. Koden har den förra kommenterat, så den senare metoden används (dvs värdet i knappens tagg hämtas).- Observera att den senare metoden har nackdelen att värdet kan vara null, vilket skulle orsaka ett undantag för nollpekare, därav
if (view.getTag != null)
.
- Observera att den senare metoden har nackdelen att värdet kan vara null, vilket skulle orsaka ett undantag för nollpekare, därav
-
Som ovan för att uppdatera ListView .
-
Därefter ställs SimpleCursorAdapter in, den tar 5 parametrar:-
- layouten som ska användas (android.R.layout.simple_list_item_1) är en lagerlayout.
- datan som ska användas i form av en markör. NOTERA! en kolumn med namnet _id MÅSTE finnas (vanligtvis en bra idé att alltid använda
_id INTEGER PRIMARY KEY
av denna anledning. ) Observera att vi får en markörcrimelist
viagetCrimeList
metod. - Kolumnen/kolumnerna i markören som data ska hämtas från.
- Vyen/vyerna i layouten där den hämtade informationen kommer att placeras.
- Ett värde som jag inte kommer ihåg syftet med. Men 0 är bra att använda. Att inte koda denna femte parameter kommer sannolikt att resultera i ett föråldrat meddelande.
- (Obs att jag normalt använder anpassade marköradapters eftersom de är mycket mer flexibla, så använder sällan Simples).
-
Sedan uppmanas ListView att använda adaptern enligt
mCrimeList.setAdapter(sca);
. -
Sedan en
onItemLongClickListener
läggs till i ListView, vilket kommer att ta bort brottet som långklickades på (långt l är _id värde, därav en anledning till att en CursorAdapter behöver _id och därav varfördbhlpr.deleteCrime(l);
).- Återigen ListView är uppdaterad.
-
Slutligen, eftersom markören används medan aktiviteten fortfarande används
onDestory
metod används för att stänga markören (markörer ska alltid stängas när du är klar med).
Så här ser det ut (inte vackert men funktionellt), med tre brott tillagda (Ta bort-knappen skulle ta bort Århundradets brott brottslighet). Långklickning på något listat brott kommer att ta bort det brottet. Om du klickar på Lägg till läggs ytterligare en post till Crime of the Century till om inte uppgifterna ändras.