Soru SimpleCursorAdapter ile bağlı ListView'den seçili öğe al


Android geliştirmede yepyeni biriyim ... iPhone ve .Net geçmişlerinden geliyor. Buna çok benzer sorular gördüm, ama bunların hiçbiri SimpleCursorAdapter ile ilgilenmedi.

Bir SQLite sorgusundan veriyi ListView'ime bağlamak için bir İmleç kullanan temel bir ListActivity var:

ListAdapter adapter = new SimpleCursorAdapter(
        this, 
        android.R.layout.simple_list_item_1,  
        c,        
        new String[] {"name"},   
        new int[] {android.R.id.text1}); 

setListAdapter(adapter);

Daha sonra bir ürün tıklandığında:

public void onListItemClick(ListView l, View v, int position, long id) {

    super.onListItemClick(l, v, position,  id);

    //Difference between this:
    Cursor c = (cursor)l.getItemAtPosition(position);
    //and this??
    Cursor c = (Cursor)l.getAdapter().getItem(position);

    int categoryId = c.getInt(0);
}

Seçilen öğenin kimliğini almanın doğru yolu bu mu? Tuhaf görünüyor, çünkü veritabanı kapatıldıktan sonra imlecimi kullanabileceğimi düşünmüyordum (ki ben bağlandıktan sonra). Bu id dosyasındaki asıl öğeyi almanın bir yolunu göremediğimde kimliğin ne zaman geçtiğini anladım. Ayrıca, getItemAtPosition () neden bir imleci döndüreceğini anlamıyorum ... imleç tüm listeye bağlı; sadece bir satır değil. Son olarak, eğer bu doğruysa, imleci almanın iki yolu arasında bir fark var mı? Teşekkürler.


36
2018-05-27 19:29


Menşei




Cevaplar:


Yani birkaç puan: imleci getirdikten sonra, aramak istersiniz startManagingCursor. Bu, imlecin yaşam döngüsünü Etkinlik'in yaşam döngüsü ile bağlar (Etkinlik Etkinleştirildiğinde imleç kapanır / temizlenir).

startManagingCursor(c);
ListAdapter adapter = new SimpleCursorAdapter(
        this, 
        android.R.layout.simple_list_item_1,  
        c,        
        new String[] {"name"},   
        new int[] {android.R.id.text1}); 
setListAdapter(adapter);

Ayrıca, veritabanı kapalı, İmleç genellikle DB'ye canlı bir bağlantı tutar (bu nedenle ListView, İmlecin içeriğine gelecekteki erişimi gerektirebilecek bu tür şeyleri tarayabilir ve yapabilir.

Temel sorunuz için, bunu yapmanın en kolay yolu onListItemClick bu:

Cursor c = ((SimpleCursorAdapter)l.getAdapter()).getCursor();
c.moveToPosition(position);

Daha sonra kullanabilirsiniz c.getLong(0) kimliği almak için (genellikle geçerli olan ilk sütun olarak kimlik sütununu getirdiğiniz varsayılarak). Ancak, kimliğin imzanın bir parçası olarak geçtiğine dikkat edin (son argümana bakın. public void onListItemClick(ListView l, View v, int position, long id)) Yani gerçekten tekrar getirmeniz gerekmez (ancak döngüleri yakmak isterseniz kesinlikle yapabilirsiniz). Diğer sütunlara erişmek için aynı şeyi yapabilirsiniz, sadece sütun dizinini değiştirin.

Umarım yardımcı olur.


81
2018-05-27 19:43



Teşekkürler! StartManagingCursor'u arıyordum, ama neden şimdi anlayamadım! Birkaç soru ... Yani, SQLiteDatabase.close () yöntemini çağırdığımda bile, bu imlecin buna erişmesini engellemez mi? ListView bir getCursor () yöntemine sahip görünmüyor. Son olarak, yöntemime iletilen kimlik, veritabanımdaki kimlik otomatik olarak mı? Teşekkürler! - GendoIkari
Ah, eğer ararsan close o zaman ListView'iniz muhtemelen çalışmayı durduracaktır: genel olarak yaptığım şey, Application nesnesini veritabanı adaptörüm olarak yeniden kullanmamdır: onCreate ve yakın onTerminate ve sonra veritabanı bağlantı yaşam döngüsünü uygulamanın yaşam döngüsüne bağlamak için bunu kullanın. Olabildiğince getCursor, benim hatam: Cursor c = ((SimpleCursorAdapter)l.getAdapter()).getCursor();. Ve evet, kimlik veritabanından çıkan şey: oldukça uygun. - Femi
startManagingCursor APi11'de kullanımdan kaldırılmıştır. Cevabınızı CursorLoader kullanarak bahsetmek isteyebilirsiniz. - Noah
startManagingCursor yalnızca, HoneyComb veya ICS kullanan veya sürümlü içe aktarma deliliği ile uğraşmak isteyen Android kullanıcılarının %%0001'inden birini hedefliyorsanız kullanımdan kaldırılır. - Bjorn Tipling
@BjornTipling Aslında CursorLoaders uyumluluk paketi ile kullanabilirsiniz, böyle harika bir cevap güncelleme yanlıştır. - Gaurav Agarwal


Diğer yol:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View arg1, int position, long arg3) {

            Cursor cursor = (Cursor) parent.getAdapter().getItem(position);
            //TODO
            }
});

0
2017-09-15 17:08