Android Studio: добавление onItemClickListener в строки ListView для запуска нового действия и отображения этой строки - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть собственный ListView, который отображает все строки в моей базе данных SQLite.Я пытаюсь сделать так, чтобы при щелчке строки запускалась новая операция, и она отображала данные из этой конкретной строки таблицы SQLite, чтобы я мог получить все данные столбца из одной строки.

Функция DBHandler: putкаждый лагерь в ArrayList и возвращает список:

    public ArrayList<HashMap<String, String>> getCampsites() {
        SQLiteDatabase db = this.getWritableDatabase();
        ArrayList<HashMap<String, String>> campsiteList = new ArrayList<>();
        String query = "SELECT name, city, feature FROM "+ TABLE_CAMPSITES;
        Cursor cursor = db.rawQuery(query,null);
        while (cursor.moveToNext()){
            HashMap<String,String> campsite = new HashMap<>();
            campsite.put("name",cursor.getString(cursor.getColumnIndex(COL_NAME)));
            campsite.put("city",cursor.getString(cursor.getColumnIndex(COL_CITY)));
            campsite.put("feature",cursor.getString(cursor.getColumnIndex(COL_FEATURE)));
            campsiteList.add(campsite);
        }
        cursor.close();
        return  campsiteList;
    }

Деятельность Browse.java, где я показываю каждый лагерь в виде списка:

    public class Browse extends AppCompatActivity {

    ListView lvCampsites;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_browse);

        lvCampsites= findViewById(R.id.lvCampsites);

        DatabaseHandler db = new DatabaseHandler(this);
        ArrayList<HashMap<String, String>> campsiteList = db.getCampsites();
        ListAdapter adapter = new SimpleAdapter(Browse.this, campsiteList, R.layout.browse_row_layout,new String[]{"name","city","feature"}, new int[]{R.id.name, R.id.city, R.id.feature});
        lvCampsites.setAdapter(adapter);

        lvCampsites.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent(Browse.this, CampsiteInfo.class);
                startActivity(intent);
            }
        });



    }






}

Итак, у меня есть настройка setOnItemClickListener, и она идетв действие CampsiteInfo при щелчке строки.

Что я хочу сделать, это иметь возможность отображать имя, город и функцию И иметь возможность отображать данные из дополнительных столбцов этой конкретной строки.

Итак, у меня есть еще пара столбцов, которые я хочу отобразить в действии CampsiteInfo, основываясь на строке, по которой щелкнули.

Просто для получения дополнительной информации я отображаю столбцы имени, города и объектов вlistview, но я также хочу отобразить эти столбцы + избранные и рейтинговые столбцы (в следующем упражнении).Моя таблица выглядит следующим образом:

     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);

Итак, как я могу перенести данные из одного действия в другое и получить дополнительные данные из строки SQLite в действии CampsiteInfo?Надеюсь, у меня есть смысл, спасибо!

Ответы [ 3 ]

0 голосов
/ 27 сентября 2019

Сделайте это так.

@Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                HashMap<String, String> data= (HashMap<String, String>) (parent.getAdapter()).getItem(position);
                String name= data.get("name");
                String city= data.get("city");
                String feature= data.get("feature");

                Intent intent = new Intent(getApplicationContext(), ActivityEdit.class);
                intent.putExtra("name", name);
                intent.putExtra("city", city);
                intent.putExtra("feature", feature);
                startActivity(intent );

            }

и запишите его в свой ActivityEdit вот так.

        Intent intent = getIntent();
        String name= intent.getStringExtra("name");
        String city= intent.getStringExtra("city");
        String feature= intent.getStringExtra("feature");
0 голосов
/ 27 сентября 2019

Жизнь может быть намного проще при использовании 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 строкиотображается: -

enter image description here

При щелчке строки (остров Браунси) запускается CampSiteInfo (просто пустой экран): -

enter image description here

и журнал содержит: -

2019-09-27 12:53:42.332 24769-24769/aso.asocamper D/CAMPSITEINFO: CampsiteInfo activity started with campsite Name as Brownsea Island

т.е. был передан правильный идентификатор, а имя, которое не было передано через намерение, имеетбыл найден.

0 голосов
/ 27 сентября 2019

Есть ли причина для использования ArrayList<HashMap<String, String>>?Почему бы не список объектов Campsite, в которых есть все данных?

В любом случае, вы пытаетесь выполнить передачу данных из одного действия в другое.Вы можете либо загрузить существующее действие со всей информацией в getCampsites () - даже если вы не отображаете все это, либо повторно запросить базу данных во втором действии, чтобы заполнить оставшиеся данные.

Что касается перехода от одного действия к другому, вот ссылка на это: Передача Bundle на startActivity ()? .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...