2011-12-30 13 views
7

Mam aplikację, która pobiera komunikaty zapisane jako pliki xml na serwerze i ładuje tytuł i autora każdego ogłoszenia do elementu ListView. To, co muszę przechowywać z każdym przedmiotem, to identyfikator każdego ogłoszenia, ale nie muszę go wyświetlać. Pomyślałem o przechowywaniu identyfikatora w mapie mieszania, której używam do wypełnienia listy, a następnie znajdowania powiązanego identyfikatora z tytułem klikniętym, ale myślę, że byłoby to niebezpieczne, ponieważ dwie ogłoszenia mogły mieć ten sam tytuł (oraz autora i datę) . Zastanawiałem się również nad dodaniem niewidocznego TextView do każdego elementu do przechowywania ID, ale to powodowało problemy z układem. Na koniec przeszukałem i znalazłem setTag() i getTag(), które moim zdaniem byłyby idealne do tego, co chcę robić, ale nie jestem pewien, jak używać ich z SimpleAdapter (jestem stosunkowo nowy w tym ...). Jeśli pomysł TextView to co muszę zrobić (chociaż wątpię), tutaj jest układ używam dla każdej pozycji:Dołączanie danych ID do elementów listview

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@android:id/text1" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="6dip" 
     android:textAppearance="?android:attr/textAppearanceMedium"/> 
    <LinearLayout 
     android:orientation="horizontal" 
     android:id="@+id/items" 
     android:weightSum="100" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 
     <TextView 
      android:id="@android:id/text2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="6dip" 
      android:textAppearance="?android:attr/textAppearanceSmall" 
      android:layout_weight="85"/> 
     <LinearLayout 
      android:orientation="vertical" 
      android:id="@+id/itemCB" 
      android:layout_weight="15" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:gravity="center"> 
      <CheckBox 
       android:id="@+id/cbSelected" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" /> 
     </LinearLayout> 
    </LinearLayout> 
</LinearLayout> 

i używam następujący adapter do wypełnienia listy:

for(int i = 0; i < ann.length; i++) 
{ 
    map = new HashMap<String, String>(); 
    map.put("line1", ann[i].getTitle()); 
    map.put("line2", "Posted by: " + ann[i].getAuthor() + "\n" + ann[i].date.toLongString()); 
    list.add(map); 
} 
String[] from = { "line1", "line2"}; 

int[] to = { android.R.id.text1, android.R.id.text2}; 

SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.twoline_checkbox_id_listitem, from, to); 
setListAdapter(adapter); 

Dziękuję za pomoc!

+0

myślę tu jest najlepszym rozwiązaniem dla Ciebie: http://stackoverflow.com/a/3051729/7379190 – AleX

+0

myślę [to] (http : //stackoverflow.com/a/3051729/7379190) jest najlepszą odpowiedzią na twoje pytanie. – AleX

Odpowiedz

3

Teoretycznie można zastosować dowolne podejście i prawdopodobnie będzie działać bez problemów. Na dłuższą metę jednak powiedziałbym, że lepiej będzie z prostym obiektem obiektu i niestandardowym adapterem. Bardziej szczegółowo, od jego wyglądu, wybrałbym ArrayAdapter, a ty już wydajesz się używać jakiegoś prostego obiektu obiektu dla tablicy ann.

Istnieje mnóstwo przykładów, które mogą pokazać, jak rozszerzyć ArrayAdapter. Jednak najważniejszą częścią jest metoda getView(), co w niej jest najbardziej podstawowa forma może wyglądać nieco jak poniżej:

public View getView(int position, View convertView, ViewGroup parent) { 
    View row; 
    if (null == convertView) { 
     row = mInflater.inflate(R.layout.list_item, null); 
    } else { 
     row = convertView; 
    } 

    MyObject item = (MyObject) getItem(position); 

    TextView tv = (TextView) row.findViewById(android.R.id.xxx); 
    tv.setText(item.getTitle); 

    // same for other fields/views; e.g. author, date etc 

    return row; 
} 

Zamiast tworzenia SimpleAdapter, teraz utworzyć instancję swojej CustomAdapter, przekaż swoją tablicę (lub lista) obiektów jednostki i ustawić jako całość adapterem do swojej listy:

MyObject[] objects = ... 
setListAdapter(new ArrayAdapter<string>(this, R.layout.list_item, objects)); 

Skoro teraz do czynienia z obiektami bezpośrednio, zamiast pierwszego tworząc kilka reprezentacji ciągów z różnych dziedzin, można również łatwo uzyskać dostęp do "identyfikatora" każdego elementu. Co więcej, możesz dodać wiele różnych pól bez obawy o to, jak będzie wyglądać na liście, ponieważ reprezentacja wizualna jest określona przez to, co ustawiłeś (i nie ustawiasz) w metodzie adaptera getView().

+0

Tak, bałem się, że będę musiał zagłębić się w tworzenie własnych niestandardowych adapterów. To chyba coś, czego i tak muszę się nauczyć, dzięki za pomoc! Aha, a tablica 'ann' jest tablicą obiektów ogłoszeniowych utworzonych za pomocą prostego parsera XML, po prostu fyi. :) – lancex

+0

Rozumiem, że może to być trochę przeszkodą do podjęcia się po raz pierwszy, ale kiedy już to zrozumiesz, jestem przekonany, że zgodzisz się, że było to warte wysiłku. Bez zmartwień, jeśli utkniesz w połowie drogi, zawsze są ludzie, którzy mogą pomóc. :) –

4

Po prostu chcę wyjaśnić w nieco bardziej szczegółowej odpowiedzi MH.
w twojej myArrayAdapter klasa w getView funkcji można przypisać identyfikator do View (co faktycznie oznacza „rząd”) tak:

public View getView(int position, View convertView, ViewGroup parent){ 

    View v = convertView; 

    if (v == null) { 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(mItemLayout, null); 
    } 

    String[] dataForOneRow = this.allRowsData.get(position); 

    // Tag is expected to be an Object (Integer is an object) 
    // our data are in String array - that's why we need to convert it into Integer 
    // I assume here, your ID number is first item (No.0) in the array of data 
    v.setTag(new Integer(Integer.valueOf(dataForOneRow[0]))); 

    /* 
    ...here you will set your data to display in your TextViews... 
    */ 

    return v; 
} 

A potem trzeba znać identyfikator rzędu kiedy (na przykład) użytkownik kliknął wiersz i rozpocznie się niektóre szczegółowe działanie.

Mam ListView w Fragment i to jest kawałek kodu z mojego głównego Activity, od deklaracji Fragment, umieszczone w funkcji onCreateView:

// here we assign "onClick listener" when user clicks a row 
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 

    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     Intent myRowClickIntent = new Intent(getActivity(), myDetailActivity.class); 
     // we can send some data to the new Activity through "extras" 
     // remember - our Tag is an object (Integer object) but putExtra() awaits some integer or string or some other type 
     // so here we are saying that it should be understood/treated as an Integer 
     myRowClickIntent.putExtra("item_id", (Integer)view.getTag()); 
     startActivity(myRowClickIntent); 
    } 
}); 

I wreszcie tu jest fragment kodu z onCreate metoda mojego DetailActivity:

Bundle myExtras; 
int myItemId; 

myExtras = getIntent().getExtras(); 
if (myExtras != null) { 
    myItemId = myExtras.getInteger("item_id"); 
} 

mam nadzieję, że ktoś pomoże ... :)
Jestem również nowy na Androida.
Big thank you do stackoverflow na taką pomoc w nauce rozwój Androida :)

Powiązane problemy