2012-07-25 25 views
14

Mam ListFragment wspierany przez ArrayAdapter, który jest wypełniany przez Loader. Kiedy użytkownik kliknie na jeden z elementów, chcę przekazać odniesienie do wybranego elementu, a także pozostałe elementy listy do innego fragmentu. Moje pytanie brzmi: jak mam pobrać wszystkie elementy z adaptera? Oto możliwości, które widzę:Uzyskiwanie wszystkich elementów z ArrayAdapter

1. Należy odniesienie do podłoża List

Tworzenie adapter tak:

List<DomainObject> items = new ArrayList<DomainObject>(); 
listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine, items); 

a następnie po prostu przejść items lub jego kopię do następnej czynności.

Wadą tego, co widzę, jest to, że polegam na nieudokumentowanym fakcie, że ta sama lista, którą przekazuję do konstruktora, zawiera te elementy później.

2. iterację adaptera

Gdy element zostanie kliknięty, iterację adapterem i stworzyć listę. Wydaje się to niepotrzebną ilością pracy. Elementy są zawarte w adapterze List i ręcznie kopiuję każdy element na nową listę.

3. Trzymać osobną listę elementów podczas dodawania do adaptera

Przed dodaniem elementu do adaptera, należy dodać go do oddzielnej liście, że utrzymanie we fragmencie. Jest to również marnotrawstwem, ponieważ lista elementów jest kopiowana w pliku ArrayAdapter i fragmentu.

Odpowiedz

7

Rozwiązanie, które Poszedłem z tymczasem jest tylko, aby nie używać ArrayAdapter. W przypadkach, w których walczysz z tym API, wydaje się, że lepiej jest użyć mniej w pełni funkcjonalnego (i złożonego) BaseAdapter. Możesz przeczytać więcej na temat decyzji, aby wybrać z BaseAdapter zamiast ArrayAdapter w tym artykule: Android Adapter Good Practices.

+0

Podczas gdy ten artykuł jest w większości dobry, zignorowałbym całą sekcję dotyczącą bezpieczeństwa wątków. Jest całkowicie nie w porządku, dlaczego zakłada się, że są zamki (z powodu filtrowania, które występują w wątku tła) i że 'ArrayAdapter' już zawiesza się, jeśli' notifyDataSetChanged() 'jest wywoływany na czymkolwiek poza wątkiem interfejsu użytkownika. –

+0

@ scompt.com Myślę, że opublikowany przez Ciebie link jest nieprawidłowy, wyjaśniając ArrayAdapter. Wydaje się wyjaśniać tylko ArrayAdapter . Jestem trochę zdezorientowany ... – theMfromA

+0

Ze strony, którą połączyłeś ... "Może wyświetlać tylko tekst." => Nieprawidłowy. "Wymusza dostarczenie listy elementów CharSequence ..." => Wrong "Wymaga podania zasobu układu, który zawiera tylko TextView" => Wrong. Niemal wszystkie założenia są błędne ... Nie mam na myśli, że ArrayAdapter jest lepszy od BaseAdapter, ale podstawy są złe. – Loenix

-2

Myślę, że pierwsza metoda to najlepszy sposób na zrobienie tego.

Nie sądzę, dane byłyby oryginalne w przypadku innej czynności. ponieważ, przekazywałbyś elementy przez pakunek, więc obiekt jest najpierw zapisywany na pakiecie, a następnie w następnym działaniu, które odczytujemy z pakietu.

Jeśli jednak używasz jakiegoś innego sposobu przekazania listy, użyj list.clone(), aby utworzyć nowy obiekt, zamiast podać oryginalny.

27

Trochę spóźniam się na grę, ale mam podobny problem.

Jednym ze sposobów radzenia sobie z # 1 byłoby zachowanie odwołania do listy w podklasie ArrayAdapter, aby ponowne użycie było kontrolowane przez obiekt adaptera.

Coś jak:

public class DomainAdapter extends ArrayAdapter<DomainObject> { 

    private final List<DomainObject> items; 

    public DomainAdapter(Context context, List<DomainObject> items) { 
     super(context, R.layout.mine, items); 
     this.items = items; 
    } 

    public List<DomainObject> getItems() { 
     return items; 
    } 
} 
+9

Uwaga. Jeśli planujesz filtrowanie adaptera w pewnym momencie, ta metoda może się nie powieść. Wykonywanie filtru, wewnątrz ArrayAdapter, spowoduje utworzenie zupełnie nowej instancji listy. Co oznacza, że ​​twoje zdefiniowane zewnętrznie "przedmioty" nie będą już tą samą listą. Co oznacza, że ​​nie będzie zsynchronizowany, jeśli później zostaną wprowadzone modyfikacje. Możesz przeczytać więcej na ten temat tutaj: http://www.jaysoyer.com/2014/07/constructor-woes-androids-arrayadapter/ –

0

Szybki test mówi, że metoda 1 działa.Wydaje się, że jest najszybszy i najczystszy, ale ponieważ jest nieudokumentowany, możesz przetestować go na planowanych platformach i za każdym razem, gdy zaktualizują się w przypadku zmiany struktury ArrayAdapter.

używam skompilować wersję SDK 22 i 10. min SDK Version

0

Najlepszą metodą jest „zachować odniesienie do listy”, ale nie przechodząc „pozycje” zmienna/parametr do konstruktora:

List<DomainObject> items = new ArrayList<DomainObject>(); listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine);

W ten sposób tworzysz tylko tablicę ArrayList jako pustą tablicę i będziesz musiał samodzielnie zarządzać listą.

Powiązane problemy