Алтернативен отговор
Следва кодът за доста основен, но работещ пример. Това обаче отива малко по-далеч, като включва ListView и позволява изтриване чрез продължително щракване върху елемент в ListView .
Това обаче не използва фрагменти.
Има 3 части от кода, MainActivity (MainActivity.java
), Подкласът SQLiteOpenHelper CrimeDBHelper (CrimeDBHelper.java
) и оформлението за MainActivity, activity_main.xml
:-
activity_main.xml
Това е доста ясно. Имайте предвид, че включва ListView в края.
<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
Повечето са подобни, с изключение на допълнителния метод getCrimeList()
, това връща курсор, който съдържа всички данни от таблицата за престъпления (използва се за попълване на 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();
}
}
}
Първото нещо, което трябва да се отбележи, е реда long lastcrimeid;
, това е декларирано на ниво клас, така че е много достъпно навсякъде (проблемът, който имате с long databaseID
).
Може също да забележите SimpleCursorAdapter sca;
това ще се използва за ListView
(по принцип той поставя данните от курсора в ListView ).
Трябва да сте запознати с голяма част от следния код. В обобщение:-
- извиква се super.onCreate.
- Дейността е настроена да използва оформлението на activity_main.xml.
- След като оформлението е заредено, се получават идентификаторите, свързани с изгледите.
-
Получава се курсор за получаване на текущите престъпления от базата данни (може да не е такъв, това не е проблем).
-
добавен е слушател на бутони за добавяне на престъпление. Имайте предвид, че това използва върнатия _id от добавения ред два пъти (всъщност 3 пъти, тъй като съответно променя текста на бутоните за изтриване ).
lastcrimeid
се задава от връщането наaddCrime()
метод.-
mDltCrime.setTag(lastcrimeid);
задава етикета на бутона за изтриване на_id
от добавения ред. -
Също така имайте предвид, че съществуват два допълнителни реда, а именно
crimelist = dbhlpr.getCrimeList();
иsca.swapCursor(crimelist);
.- Първият замества курсора с това, което сега е в базата данни (т.е. включва реда, който е добавен), вторият казва на ListView да използва новия курсор, така че кара ListView да показва какво е сега в базата данни ( това се използва отново при изтриване на ред).
-
след това се добавя слушател на бутони за бутона за изтриване. Това може да работи по два начина.
lastcrimeid
може да се използва или алтернативно може да се използва нивото на бутона, тъй като и двете задържат _id от реда, който трябва да бъде изтрит. Първият код е коментиран, така че се използва вторият метод (т.е. стойността в маркера на бутона се извлича).- Обърнете внимание, че последният метод има недостатъка, че стойността може да бъде нулева, което би причинило изключение с нулев указател, следователно
if (view.getTag != null)
.
- Обърнете внимание, че последният метод има недостатъка, че стойността може да бъде нулева, което би причинило изключение с нулев указател, следователно
-
Както по-горе за опресняване на ListView .
-
След това SimpleCursorAdapter е настроен, той отнема 5 параметъра:-
- оформлението, което ще се използва (android.R.layout.simple_list_item_1), е стандартно оформление.
- данните, които да се използват под формата на курсор. ЗАБЕЛЕЖКА! колона с име _id ТРЯБВА да съществува (като цяло е добра идея винаги да се използва
_id INTEGER PRIMARY KEY
поради тази причина. ) Забележете, че получаваме курсорcrimelist
чрезgetCrimeList
метод. - Колоната(ите) в курсора, от която трябва да бъдат извлечени данните.
- Изгледът(ите) в оформлението, където ще бъдат поставени извлечените данни.
- Стойност, чиято цел не мога да си спомня. Въпреки това 0 е добре да се използва. Некодирането на този 5-ти параметър вероятно ще доведе до оттеглено съобщение.
- (Забележете, че обикновено използвам персонализирани адаптери за курсор, тъй като те са много по-гъвкави, така че рядко използвам Simples).
-
След това на ListView се казва да използва адаптера съгласно
mCrimeList.setAdapter(sca);
. -
След това
onItemLongClickListener
се добавя към ListView, което ще изтрие престъплението, върху което е щракнато дълго (дългото l е _id стойност, следователно причина, поради която CursorAdapter се нуждае от _id и следователно защоdbhlpr.deleteCrime(l);
).- Отново ListView се обновява.
-
И накрая, тъй като курсорът се използва, докато дейността остава в употреба
onDestory
методът се използва за затваряне на курсора (курсорите винаги трябва да бъдат затворени, когато приключите с).
Ето как изглежда (не красиво, но функционално), с добавени три престъпления (бутонът за изтриване ще премахне Престъплението на века престъпление). Дългото щракване върху всяко изброено престъпление ще изтрие това престъпление. Щракването върху добавяне ще добави още един запис за Престъплението на века, освен ако данните не бъдат променени.