Жизнь может быть намного проще при использовании CursorAdapter, например SimpleCursorAdapter, при использовании ListViews.
Они предназначены для обработки курсоров, и нет необходимости в промежуточных массивах и извлечении их / их из курсоров, они передают идентификатор в прослушиватели onItemClick (4-й параметр), и это все, что необходимо для передачистрока базы данных между действиями.
Единственное неудобство заключается в том, что идентификатор ДОЛЖЕН быть столбцом с именем _id (или переименован с использованием AS, например SELECT *, id AS _id).- это определяется как константа с именем _ID в BaseColumns (используется в примере ниже).
Пример
Ниже приведено базовое приложение, основанное на вашем коде (некоторые отклонения комментируются)
DatabaseHandler.java
открытый класс DatabaseHandler расширяет SQLiteOpenHelper {
public static final String DBNAME = "campsite.db";
public static final int DBVERSION = 1;
public static final String TABLE_CAMPSITES = "campsite";
public static final String COL_ID = BaseColumns._ID; //<<<<<<<<<< Important for Adapter
public static final String COL_NAME = "name";
public static final String COL_CITY = "city";
public static final String COL_FEATURE = "feature";
public static final String COL_FAVORITE = "favourite";
public static final String COL_RATING = "rating";
public static final String COL_LATITUDE = "latitude";
public static final String COL_LONGITUDE = "longitude";
public DatabaseHandler(@Nullable Context context) {
super(context, DBNAME, null, DBVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CAMPSITES_TABLE = "CREATE TABLE " + TABLE_CAMPSITES + "("
+ COL_ID + " INTEGER PRIMARY KEY," + COL_NAME + " TEXT,"
+ COL_CITY + " TEXT," + COL_FEATURE + " TEXT," + COL_FAVORITE + " TEXT," + COL_RATING + " INTEGER," + COL_LATITUDE + " REAL," + COL_LONGITUDE + " REAL" + ")";
db.execSQL(CREATE_CAMPSITES_TABLE);
}
public Cursor getCampsitesAsCursor() {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(
TABLE_CAMPSITES, /* Table i.e. FROM part */
/* Columns */
new String[]{
COL_ID,
COL_NAME,
COL_CITY,
COL_FEATURE
},
null,null,null,null,null
);
}
public Cursor getCampSiteById(long id) {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(TABLE_CAMPSITES,null,COL_ID + "=?",new String[]{String.valueOf(id)},null,null,null);
}
public long addCampsiteRow(String name, String city, String feature, String favourite, int rating, double latitude, double longitude) {
ContentValues cv = new ContentValues();
cv.put(COL_NAME,name);
cv.put(COL_CITY,city);
cv.put(COL_FEATURE, feature);
cv.put(COL_FAVORITE,favourite);
cv.put(COL_RATING,rating);
cv.put(COL_LATITUDE,latitude);
cv.put(COL_LONGITUDE,longitude);
SQLiteDatabase db = this.getWritableDatabase();
return db.insert(TABLE_CAMPSITES,name,cv);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
browse_row_layout.xml (обратите внимание, что ваши, вероятно, могут быть использованы без каких-либо изменений)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/campsiteName"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/campsiteCity"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/campsiteFeature"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
Browse.java
public class Browse extends AppCompatActivity {
public static final String INTENTKEY_CAMPSITEID = "ik_campsiteID";
DatabaseHandler DBHandler;
ListView lvCampsites;
Cursor campsiteList;
SimpleCursorAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_browse);
lvCampsites = this.findViewById(R.id.lvCampsites);
DBHandler = new DatabaseHandler(this);
addSometestingData();
manageListView();
}
private void manageListView() {
campsiteList = DBHandler.getCampsitesAsCursor();
if (adapter == null) {
adapter = new SimpleCursorAdapter(
this,
R.layout.browse_row_layout,campsiteList,
new String[]{
DatabaseHandler.COL_NAME,
DatabaseHandler.COL_CITY,
DatabaseHandler.COL_FEATURE},
new int[]{
R.id.campsiteName,
R.id.campsiteCity,
R.id.campsiteFeature},
0
);
lvCampsites.setAdapter(adapter);
lvCampsites.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(view.getContext(),CampSiteInfo.class);
intent.putExtra(INTENTKEY_CAMPSITEID,id);
startActivity(intent);
}
});
} else {
adapter.swapCursor(campsiteList);
}
}
private void addSometestingData() {
if(DatabaseUtils.queryNumEntries(DBHandler.getWritableDatabase(),DatabaseHandler.TABLE_CAMPSITES) < 1) {
DBHandler.addCampsiteRow(
"Brownsea Island",
"Bournemouth",
"wet wet wet",
"might be",
10,1234567.567,890678.564
);
DBHandler.addCampsiteRow(
"Youbury",
"Oxford",
"Trees, tress and more trees",
"NO",
-100,66463636.8877, 42316867.3542
);
// etc
}
}
//<<<<<<<<<< ADDED >>>>>>>>>>
@Override
protected void onDestroy() {
campsiteList.close(); //<<<<<<<<<< closes the cursor when done with it
super.onDestroy();
}
//<<<<<<<<<< ADDED >>>>>>>>>>
@Override
protected void onResume() {
super.onResume();
manageListView(); //<<<<<<<<<< refreshes the listview if need be
}
}
Обратите внимание, что при создании экземпляра адаптера 4-й параметрстроковый массив столбцов из , из которого извлекаются отображаемые данные, и что 5-й параметр является массивом идентификаторов int в макете для каждой строки, соответствующей 4-му параметру.
Таким образом, SimpleCursorAdapter является достаточно гибким (более или более простым, чем SimpleAdapter) в отношении того, что может быть отображено.
CampSiteInfo.java
Это бКогда он показывает основы получения данных для переданного id , он регистрирует только имя.
public class CampSiteInfo extends AppCompatActivity {
DatabaseHandler DBHandler;
Cursor csr;
long campSiteId;
int campSiteRating;
String campSiteName = "", campSiteCity = "", campSiteFeature = "", campSiteFavourite = "";
double campSiteLatitude = 0.0, campSiteLongitude = 0.0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camp_site_info);
campSiteId = this.getIntent().getLongExtra(Browse.INTENTKEY_CAMPSITEID,-1);
DBHandler = new DatabaseHandler(this);
csr = DBHandler.getCampSiteById(campSiteId);
if (csr.moveToFirst()) {
campSiteName = csr.getString(csr.getColumnIndex(DatabaseHandler.COL_NAME));
campSiteCity = csr.getString(csr.getColumnIndex(DatabaseHandler.COL_CITY));
campSiteFeature = csr.getString(csr.getColumnIndex(DatabaseHandler.COL_FEATURE));
campSiteFavourite = csr.getString(csr.getColumnIndex(DatabaseHandler.COL_FAVORITE));
campSiteRating = csr.getInt(csr.getColumnIndex(DatabaseHandler.COL_RATING));
campSiteLatitude = csr.getDouble(csr.getColumnIndex(DatabaseHandler.COL_LATITUDE));
campSiteLongitude = csr.getDouble(csr.getColumnIndex(DatabaseHandler.COL_LONGITUDE));
}
Log.d("CAMPSITEINFO","CampsiteInfo activity started with campsite Name as " + campSiteName );
// .... code
}
@Override
protected void onDestroy() {
if (!csr.isClosed()) {
csr.close();
}
super.onDestroy();
}
}
Результат
При запуске 2 строкиотображается: -
При щелчке строки (остров Браунси) запускается CampSiteInfo (просто пустой экран): -
и журнал содержит: -
2019-09-27 12:53:42.332 24769-24769/aso.asocamper D/CAMPSITEINFO: CampsiteInfo activity started with campsite Name as Brownsea Island
т.е. был передан правильный идентификатор, а имя, которое не было передано через намерение, имеетбыл найден.