Alternatywna odpowiedź
Poniżej znajduje się kod dość podstawowego, ale działającego przykładu. Jednak idzie trochę dalej, włączając ListView i umożliwienie usunięcia przez długie kliknięcie elementu w ListView .
Jednak nie używa to fragmentów.
Istnieją 3 fragmenty kodu, MainActivity (MainActivity.java
), podklasa SQLiteOpenHelper CrimeDBHelper (CrimeDBHelper.java
) i układ MainActivity, activity_main.xml
:-
activity_main.xml
To całkiem proste. Pamiętaj, że zawiera ListView na końcu.
<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
Większość jest podobna, z wyjątkiem dodatkowej metody getCrimeList()
, zwraca Cursor, który zawiera wszystkie dane z tabeli przestępstw (używanej do wypełniania 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();
}
}
}
Pierwszą rzeczą, na którą należy zwrócić uwagę, jest wiersz long lastcrimeid;
, jest to deklarowane na poziomie klasy, więc jest bardzo dostępne przez cały czas (problem z long databaseID
).
Możesz również zauważyć SimpleCursorAdapter sca;
będzie to używane dla ListView
(w zasadzie umieszcza dane z kursora w widoku ListView ).
Powinieneś znać większość poniższego kodu. Podsumowując:-
- Nazywa się
- super.onCreate.
- Aktywność jest ustawiona na używanie układu activity_main.xml.
- Po załadowaniu układu identyfikatory są powiązane z widokami.
-
Uzyskuje się Kursor, który pobiera aktualne przestępstwa z bazy danych (może być żaden, to nie jest problem).
-
dodawany jest detektor przycisku dodawania przestępstwa. Pamiętaj, że używa zwróconego _id dodanego wiersza dwa razy (właściwie 3 razy, ponieważ zmienia odpowiednio tekst przycisków usuwania ).
lastcrimeid
jest ustawiana przez zwrotaddCrime()
metoda.-
mDltCrime.setTag(lastcrimeid);
ustawia tag przycisku usuwania na_id
dodanego wiersza. -
Zauważ również, że istnieją dwie dodatkowe linie, mianowicie
crimelist = dbhlpr.getCrimeList();
isca.swapCursor(crimelist);
.- Pierwszy zastępuje kursor tym, co jest teraz w bazie danych (tj. zawiera dodany wiersz), drugi mówi ListView, aby użył nowego kursora, więc powoduje, że ListView pokazuje, co jest teraz w bazie danych ( jest to używane ponownie podczas usuwania wiersza).
-
następnie dodawany jest detektor przycisku dla przycisku usuwania. Może to działać na dwa sposoby.
lastcrimeid
może być używany lub alternatywnie tag przycisku może być używany jako oba elementy przytrzymujące _id wiersza do usunięcia. Pierwsza metoda została zakomentowana w kodzie, więc używana jest druga metoda (tj. pobierana jest wartość ze znacznika przycisku).- Zauważ, że ta ostatnia metoda ma tę wadę, że wartość może mieć wartość null, co spowodowałoby wyjątek wskaźnika o wartości null, stąd
if (view.getTag != null)
.
- Zauważ, że ta ostatnia metoda ma tę wadę, że wartość może mieć wartość null, co spowodowałoby wyjątek wskaźnika o wartości null, stąd
-
Jak powyżej dla odświeżenia ListView .
-
Następnie konfigurowany jest SimpleCursorAdapter, który przyjmuje 5 parametrów:-
- układ, który ma zostać użyty (android.R.layout.simple_list_item_1) jest układem giełdowym.
- dane do wykorzystania w postaci kursora. UWAGA! kolumna o nazwie _id MUSI istnieć (ogólnie dobrym pomysłem jest zawsze używać
_id INTEGER PRIMARY KEY
z tego powodu. ) Zauważ, że otrzymujemy kursorcrimelist
poprzezgetCrimeList
metoda. - Kolumny w kursorze, z których mają zostać pobrane dane.
- Widoki w układzie, w których zostaną umieszczone pobrane dane.
- Wartość, której celu nie pamiętam. Jednak 0 jest w porządku. Niezakodowanie tego piątego parametru prawdopodobnie spowoduje przestarzałą wiadomość.
- (Zauważ, że zwykle używam niestandardowych adapterów kursorów, ponieważ są one znacznie bardziej elastyczne, więc rzadko używam Simples).
-
Następnie ListView otrzymuje polecenie użycia adaptera zgodnie z
mCrimeList.setAdapter(sca);
. -
Następnie
onItemLongClickListener
zostanie dodany do ListView, który usunie przestępstwo, na które długo kliknięto (długie l to _id wartość, stąd powód, dla którego CursorAdapter potrzebuje _id i stąd dlaczegodbhlpr.deleteCrime(l);
).- Ponownie ListView jest odświeżony.
-
Wreszcie, gdy kursor jest używany, gdy aktywność pozostaje w użyciu
onDestory
Metoda służy do zamykania Kursora (Kursory powinny być zawsze zamykane po zakończeniu).
Tak to wygląda (nie ładnie, ale funkcjonalnie) z dodanymi trzema przestępstwami (przycisk usuwania usunie Zbrodnię stulecia przestępczość). Długie kliknięcie dowolnego przestępstwa z listy spowoduje jego usunięcie. Kliknięcie Dodaj spowoduje dodanie kolejnego wpisu do Crime of the Century, chyba że dane zostaną zmienione.