Chcę rozwinąć / zwinąć elementy mojego widoku recyclingerView, aby wyświetlić więcej informacji. Chcę osiągnąć ten sam efekt, co SlideExpandableListView .
Zasadniczo w moim ViewHolder mam widok, który nie jest widoczny i chcę zrobić płynną animację rozwijania / zwijania, zamiast ustawiać widoczność na VISIBLE / GONE. Potrzebuję tylko elementu do rozwinięcia naraz i fajnie byłoby mieć jakieś podniesienie, aby pokazać, że element jest wybrany.
Jest to ten sam efekt, co nowa lista historii ostatnich połączeń Androida. Opcje „ODDZWOŃ” i „SZCZEGÓŁY” są widoczne tylko wtedy, gdy element jest zaznaczony.
Odpowiedzi:
Nie używaj żadnej biblioteki do tego efektu, zamiast tego użyj zalecanego sposobu robienia tego zgodnie z Google I / O. W metodzie onBindViewHolder w Twoim ecclerView wykonaj następujące czynności:
Aby uzyskać fajne efekty, które chciałeś, użyj tych jako atrybutów list_item:
gdzie comment_background to:
a comment_selection to:
źródło
TransitionManager.beginDelayedTransition(recyclerView);
jeśli nie mogę znaleźć odniesienia do widoku recyklera.recyclerView
jako parametr w konstruktorze adapteraDo tego potrzebne były tylko proste, a nie skomplikowane linie
w swojej metodzie onBindViewHolder dodaj poniższy kod
Dla tych, którzy chcą rozwinąć tylko jeden element, a inne zwinąć. Użyj tego
najpierw zadeklaruj zmienną globalną z previousExpandedPosition = -1
następnie
Gotowe!!!. Prosty i pokorny .. :)
źródło
OnClickListener
onCreateViewHolder
onBindViewHolder
RecyclerView
pracować, to znaczy, jaki jest sens wLayoutManager
przeciwnym razie, jeśli nie zarządza układami! To rozwiązanie jest lepsze niż rozwiązanie z największą liczbą głosów, ponieważ ma mniej kodu, pozwala naRecyclerView
obsługę i działa lepiej!Nie mówię, że to najlepsze podejście, ale wydaje mi się, że działa.
Pełny kod można znaleźć pod adresem: Przykładowy kod pod adresem : https://github.com/dbleicher/recyclerview-grid-quickreturn
Po pierwsze, dodaj rozszerzony obszar do układu komórki / elementu i ustaw otaczający układ komórek animateLayoutChanges = "true". Zapewni to animację rozwijania / zwijania:
Następnie spraw, aby klasa RV Adapter implementowała View.OnClickListener, tak aby można było działać na klikanym elemencie. Dodaj pole int, aby zachować pozycję jednego rozwiniętego widoku i zainicjuj go do wartości ujemnej:
Na koniec zaimplementuj metody ViewHolder, onBindViewHolder () i zastąp metodę onClick (). Rozszerzysz widok w onBindViewHolder, jeśli jego pozycja jest równa „extendedPosition”, a jeśli nie, to ukryjesz. Ustawiasz wartość extendedPosition w odbiorniku onClick:
Powinno to rozwinąć tylko jeden element naraz, używając domyślnej animacji systemu do zmiany układu. Przynajmniej dla mnie to działa. Mam nadzieję, że to pomoże.
źródło
expandAlarm
Funkcja wAlarmClockFragment.java
plikach wykonuje część rozszerzającą.onClick()
powinienem zastąpić? Nie maonClick
w adapterze.Istnieje bardzo prosta w użyciu biblioteka z obsługą gradle: https://github.com/cachapa/ExpandableLayout .
Bezpośrednio z dokumentów biblioteki:
Po oznaczyć rozszerzalne widoki, po prostu zadzwoń do żadnej z tych metod na pojemniku:
expand()
,collapse()
lubtoggle()
źródło
Wiem, że minęło dużo czasu od opublikowania pierwotnego pytania. Ale myślę, że w przypadku powolnych, takich jak ja, pomocne byłoby wyjaśnienie odpowiedzi @ Heisenberga.
Zadeklaruj dwie zmienne w klasie adaptera jako
Następnie w onBindViewHolder, jak podano w oryginalnej odpowiedzi.
I na koniec, aby uzyskać obiekt recyclinglerView w przesłonięciu adaptera
Mam nadzieję że to pomoże.
źródło
Po prostu nie ma potrzeby korzystania z bibliotek innych firm. Trochę uszczypnąć w metodzie wykazano w Google I / O 2016 i Heisenberga na ten temat, załatwia sprawę.
Ponieważ
notifyDataSetChanged()
przerysowuje w całościRecyclerView
,notifyDataItemChanged()
jest lepszą opcją (nie najlepszą), ponieważ mamy pozycję i doViewHolder
dyspozycji, anotifyDataItemChanged()
tylko przerysowuje konkretViewHolder
na danej pozycji .Problem polega jednak na tym, że przedwczesne zniknięcie
ViewHolder
po kliknięciu i jego pojawienie się nie jest wyeliminowane, nawet jeślinotifyDataItemChanged()
jest używane.Poniższy kod nie odwołuje się do
notifyDataSetChanged()
aninotifyDataItemChanged()
i jest testowany na interfejsie API 23 i działa jak urok, gdy jest używany w RecyclerView, gdzie każdy element ViewHolder maCardView
jako element główny:prev_position
jest globalną liczbą całkowitą zainicjowaną na -1.details
to pełny widok, który jest wyświetlany po rozwinięciu i zasłonięciu po zwinięciu.Jak powiedziano, głównym elementem
ViewHolder
jest atrybut aCardView
withforeground
istateListAnimator
zdefiniowane dokładnie tak, jak powiedział Heisenberg na ten temat.AKTUALIZACJA: Powyższa demonstracja zwinie wcześniej rozwinięty element, jeśli jeden z nich zostanie rozwinięty. Aby zmodyfikować to zachowanie i zachować rozwinięty element w takim stanie, w jakim jest nawet po rozwinięciu innego elementu, potrzebujesz następującego kodu.
AKTUALIZACJA: Podczas rozwijania ostatnich elementów na liście, może nie być ona w pełni widoczna, ponieważ rozwinięta część znajduje się poniżej ekranu. Aby uzyskać pełną pozycję na ekranie, użyj następującego kodu.
WAŻNE: Aby powyższe demonstracje działały, należy zachować w swoim kodzie wystąpienie RecyclerView i jego LayoutManager (później dla elastyczności)
źródło
notifyItemChanged
ponieważ mamImageView
załadowany obraz z adresu URL.notifyItemChanged
przeładuj mój obraz sprawia, że wygląda dziwnieTransitionManager.beginDelayedTransition(recycler);
, świetne znalezisko. Ale odkryłem, że używając tej metody, jeśli kliknę spamowo kilka wierszy po kolei, w końcu wywołuje to wewnętrzną awarięThe specified child already has a parent. You must call removeView() on the child's parent first
. Wyobrażam sobie, że jest to spowodowane recyklingiem widoku na granicach widoku recyklera, ale nie mogę tego powiedzieć na pewno. Czy ktoś miał ten sam problem?Po zastosowaniu zalecanego sposobu implementacji elementów rozwijanych / zwijanych znajdujących się w elementach rozwijania / zwijania w RecyclerView,
RecyclerView
na które odpowiedziała HeisenBerg , zauważyłem zauważalne artefakty za każdym razem, gdy odświeżany jest przez wywołanieRecyclerView
TransitionManager.beginDelayedTransition(ViewGroup)
a następnienotifyDatasetChanged()
.Jego oryginalna odpowiedź:
Zmodyfikowano:
int
które śledzi rozwinięty elementViewHolder
używany podczas zwijania elementuZwróć uwagę, że metoda
TransitionManager.beginDelayedTransition(ViewGroup)
inotifyDataSetChanged()
są zastępowane przeznotifyItemChanged(int)
celowanie w określony przedmiot i kilka drobnych poprawek.Po modyfikacji poprzednie niechciane efekty powinny zniknąć. Jednak może to nie być idealne rozwiązanie. Zrobił tylko to, co chciałem, eliminując bóle oczu.
::EDYTOWAĆ::
Dla wyjaśnienia, oba
mExpandedPosition
imExpandedHolder
są globalne.źródło
notifyItemChanged()
. Możesz ręcznie animować i zmieniać wysokość elementu oraz dodawać do niego widoki.Wykonaj następujące czynności po ustawieniu odbiornika onClick na klasę ViewHolder:
Myślę, że to powinno pomóc, tak właśnie wdrożyłem i robi to samo, co Google w widoku ostatnich połączeń.
źródło
Dziwię się, że nie ma jeszcze zwięzłej odpowiedzi, chociaż taka animacja rozwijania / zwijania jest bardzo łatwa do osiągnięcia za pomocą zaledwie 2 linii kodu:
razem z
Więc dla mnie wyjaśnienia w linku poniżej były naprawdę przydatne: https://medium.com/@nikola.jakshic/how-to-expand-collapse-items-in-recyclerview-49a648a403a6
źródło
źródło
Użyj dwóch typów widoku w pliku
RVAdapter
. Jeden dla rozwiniętego układu, a drugi dla zwiniętego. I magia dzieje się z ustawieniemandroid:animateLayoutChanges="true"
dlaRecyclerView
Checkout efektu osiągniętego przy użyciu tego w tym filmie przy 0:42źródło