Struktura przejścia Androida pozwala animować każdy ruch z interfejsem, podając układ początkowy i końcowy. Możesz wybrać rodzaj animacji, np. zanikanie lub pomniejszenia, a także rozmiaru widoku. Proces przejścia określa jak animować układ od układu początkowego do końcowego.
Proces przejścia obejmuje te funkcje:
- Animacje na poziomie grupy: stosować efekty animacji do wszystkich widoków w hierarchii widoków.
- Wbudowane animacje: korzysta ze wstępnie zdefiniowanych animacji w celu uzyskania typowych efektów, takich jak rozjaśnienie czy ruch.
- Obsługa pliku zasobów: wczytuj hierarchie widoków i wbudowane animacje z plików zasobów układu.
- Wywołania zwrotne cyklu życia: otrzymywanie wywołań zwrotnych, które zapewniają kontrolę nad animacją i hierarchią; proces zmiany.
Przykładowy kod animowany między zmianami układu: Podstawowe przejście.
Podstawowy proces animacji między 2 układami wygląda tak:
- Utwórz obiekt
Scene
dla układ początkowy i końcowy. Początkowa scena jest jednak często określane automatycznie na podstawie bieżącego układu. - Tworzenie
Transition
aby zdefiniować odpowiedni typ animacji. - Zadzwoń do nas
TransitionManager.go()
a system uruchamia animację, aby zamienić układy.
Diagram na ilustracji 1 pokazuje zależności między układami. sceny, przejścia i końcową animację.
Tworzenie sceny
Sceny przechowują stan hierarchii widoków, w tym wszystkie jej widoki i ich wartości właściwości. Platforma przejść może uruchamiać animacje między i scenę końcową.
Możesz tworzyć sceny z poziomu układu lub z grupy widoków w kodzie. Jednak scena początkowa przejścia jest często określana automatycznie na podstawie obecny interfejs użytkownika.
Scena może też określać własne działania, które są wykonywane po wprowadzeniu jej zmiany. Ta funkcja jest przydatna do wyczyszczenia ustawień widoku po przejście do określonej sceny.
Tworzenie sceny z zasobu układu
Możesz utworzyć instancję Scene
bezpośrednio z zasobu szablonu
. Ta metoda jest przydatna, gdy hierarchia widoków w pliku jest w większości statyczna.
Powstała scena przedstawia stan hierarchii widoków w momencie,
utworzono instancję Scene
. Jeśli zmienisz hierarchię widoków,
odtworzyć scenę. Platforma tworzy scenę z całego widoku
w danej hierarchii. Nie można utworzyć sceny z części pliku układu.
Aby utworzyć instancję Scene
z pliku zasobów układu, pobierz
główny element sceny z układu jako
ViewGroup
Następnie wywołaj funkcję
Scene.getSceneForLayout()
z katalogiem głównym sceny i identyfikatorem zasobu pliku układu, który
zawiera hierarchię widoku sceny.
Definiowanie układów scen
Fragmenty kodu znajdujące się w pozostałej części tej sekcji pokazują, jak utworzyć dwa
różnych scen z tym samym elementem głównym sceny. Fragmenty kodu pokazują też
że możesz wczytać wiele niepowiązanych obiektów Scene
, nie sugerując, że
są ze sobą powiązane.
Przykład składa się z tych definicji układu:
- Główny układ aktywności z etykietą tekstową i elementem podrzędnym
FrameLayout
ConstraintLayout
dla pierwszą scenę z dwoma polami tekstowymi.ConstraintLayout
dla drugiej sceny z tymi samymi 2 polami tekstowymi w w innej kolejności.
Przykład jest zaprojektowany tak, aby cała animacja odbywała się w elemencie podrzędnym. układ głównego układu aktywności. Etykieta tekstowa w układzie głównym. nie zmienia się.
Główny układ aktywności jest zdefiniowany tak:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/master_layout"> <TextView android:id="@+id/title" ... android:text="Title"/> <FrameLayout android:id="@+id/scene_root"> <include layout="@layout/a_scene" /> </FrameLayout> </LinearLayout>
Ta definicja układu zawiera pole tekstowe i element podrzędny FrameLayout
dla elementu
element główny sceny. Układ pierwszej sceny znajduje się w głównym pliku układu.
Dzięki temu aplikacja może wyświetlać ją jako część początkowego interfejsu użytkownika, a także ją wczytywać.
go w scenie, ponieważ platforma może załadować tylko cały plik układu
scena.
Układ pierwszej sceny jest zdefiniowany tak:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scene_container" android:layout_width="match_parent" android:layout_height="match_parent" ></androidx.constraintlayout.widget.ConstraintLayout>
Układ drugiej sceny zawiera te same 2 pola tekstowe – w tej samej kolejności, ale w innej kolejności. Jest on zdefiniowany w ten sposób:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scene_container" android:layout_width="match_parent" android:layout_height="match_parent" ></androidx.constraintlayout.widget.ConstraintLayout>
Generuj sceny na podstawie układów
Po utworzeniu definicji dla dwóch układów ograniczeń możesz uzyskać dla każdej z nich. Umożliwia to przełączanie się między dwoma interfejsami. konfiguracji. Aby uzyskać scenę, musisz podać jej źródło i układ identyfikatora zasobu.
Ten fragment kodu pokazuje, jak uzyskać odniesienie do źródła sceny
utwórz 2 obiekty Scene
z plików układu:
Kotlin
val sceneRoot: ViewGroup = findViewById(R.id.scene_root) val aScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this) val anotherScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this)
Java
Scene aScene; Scene anotherScene; // Create the scene root for the scenes in this app. sceneRoot = (ViewGroup) findViewById(R.id.scene_root); // Create the scenes. aScene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this); anotherScene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this);
W aplikacji są teraz 2 obiekty Scene
oparte na widoku
hierarchie. Obie sceny używają rdzenia sceny zdefiniowanego przez tag
FrameLayout
element w res/layout/activity_main.xml
.
Tworzenie sceny w kodzie
Możesz też utworzyć w kodzie wystąpienie Scene
na podstawie
ViewGroup
obiekt. Użyj tej metody do modyfikowania hierarchii widoków
bezpośrednio w kodzie lub gdy generujesz je dynamicznie.
Aby utworzyć scenę na podstawie hierarchii widoków w kodzie, użyj funkcji
Scene(sceneRoot, viewHierarchy)
za pomocą konstruktora. Wywołanie tego konstruktora jest równoważne wywołaniu funkcji
Scene.getSceneForLayout()
, gdy plik układu został już uzupełniony.
Fragment kodu poniżej pokazuje, jak utworzyć Scene
z poziomu głównego elementu sceny i hierarchii widoku sceny w
Twój kod:
Kotlin
val sceneRoot = someLayoutElement as ViewGroup val viewHierarchy = someOtherLayoutElement as ViewGroup val scene: Scene = Scene(sceneRoot, viewHierarchy)
Java
Scene mScene; // Obtain the scene root element. sceneRoot = (ViewGroup) someLayoutElement; // Obtain the view hierarchy to add as a child of // the scene root when this scene is entered. viewHierarchy = (ViewGroup) someOtherLayoutElement; // Create a scene. mScene = new Scene(sceneRoot, mViewHierarchy);
Tworzenie działań dotyczących sceny
Platforma umożliwia zdefiniowanie niestandardowych działań związanych ze scenami, które system uruchamia, gdy przejście do następnego punktu widokowego lub wyjście z niego. W wielu przypadkach określenie działań na scenie niestandardowych jest jest niepotrzebne, bo struktura animuje przejście między scenami automatycznie.
Czynności wykonywane na ekranie przydają się w takich przypadkach:
- Aby animować widoki, które nie należą do tej samej hierarchii Możesz animować widoki dla: między scenami początkowymi i końcowymi za pomocą działań wyjścia i wejścia.
- Aby animować widoki, których struktura przejść nie może animować się automatycznie,
takich jak
ListView
. Więcej informacje znajdziesz w sekcji o ograniczeniach.
Aby podać niestandardowe działania związane ze scenami, określ je jako
Runnable
obiektów i przekazać je do funkcji
Scene.setExitAction()
lub Scene.setEnterAction()
funkcji. Platforma wywołuje funkcję setExitAction()
na początku
scenę przed uruchomieniem animacji przejścia i elementu setEnterAction()
na scenie końcowej po uruchomieniu animacji przejścia.
Zastosuj przejście
Schemat przejścia reprezentuje styl animacji między scenami i
Transition
obiekt. Możesz utworzyć instancję Transition
za pomocą wbudowanych
podklasy, takie jak
AutoTransition
i
Fade
lub
zdefiniować własne przejście.
Następnie możesz uruchomić
animacja między scenami, przechodząc przez koniec Scene
oraz Transition
na
TransitionManager.go()
Cykl przejścia jest podobny do cyklu życia aktywności i przedstawia jest to stan przejścia między elementem początkowym, a zarazem monitorowanym przez platformę po zakończeniu animacji. W ważnych stanach cyklu życia platforma wywołuje które można wdrożyć w celu dostosowania interfejsu na różnych etapach przejścia.
Tworzenie przejścia
W poprzedniej sekcji pokazujemy, jak tworzyć sceny
odzwierciedlające stan
różne hierarchie widoków. Po zdefiniowaniu sceny początkowej i końcowej
chcesz się przełączyć, utwórz obiekt Transition
z definicją animacji.
Platforma umożliwia określenie wbudowanego przejścia w pliku zasobów
i powiększania go w kodzie lub utworzyć
wystąpienie wbudowanego przejścia.
bezpośrednio w kodzie.
Kategoria | Oznacz | Efekt |
---|---|---|
AutoTransition |
<autoTransition/> |
Przejście domyślne. Zanikanie, przesuwanie, zmienianie rozmiaru i zanikanie w widoku w tej kolejności. |
ChangeBounds |
<changeBounds/> |
Przenosi widoki i zmienia ich rozmiar. |
ChangeClipBounds |
<changeClipBounds/> |
Rejestruje View.getClipBounds() przed sceną i po niej
i animuje te zmiany podczas przejścia. |
ChangeImageTransform |
<changeImageTransform/> |
Rejestruje macierz elementu ImageView przed sceną i po niej
i animuje go podczas przejścia. |
ChangeScroll |
<changeScroll/> |
Przechwytuje właściwości przewijania elementów docelowych przed sceną i po niej i animuje wszystkie zmiany. |
ChangeTransform |
<changeTransform/> |
Rejestruje skalę i obrót widoków przed zmianą sceny i po niej i animuje te zmiany podczas przejścia. |
Explode |
<explode/> |
Śledzi zmiany widoczności widoków docelowych na początku i na końcu i przesuwa widok poza krawędź sceny. |
Fade |
<fade/> |
fade_in zmniejsza liczbę wyświetleń.fade_out przyciemnia liczbę wyświetleń.fade_in_out (domyślnie) wykonuje czynność fade_out , po której następuje
fade_in .
|
Slide |
<slide/> |
Śledzi zmiany widoczności widoków docelowych na początku i na końcu sceny i przesuwają widoki od jednego z krawędzi sceny. |
Tworzenie instancji przejścia z pliku zasobów
Ta technika pozwala modyfikować definicję przejścia bez zmiany kodu Twojej aktywności. Technika ta przydaje się również do rozdzielania złożonych definicje przejścia z kodu aplikacji, jak pokazano w sekcji o określaniu kilku przejść.
Aby określić wbudowane przejście w pliku zasobów, wykonaj te czynności:
- Dodaj do projektu katalog
res/transition/
. - Utwórz nowy plik zasobów XML w tym katalogu.
- Dodaj węzeł XML dla jednego z wbudowanych przejść.
Na przykład ten plik zasobów określa przejście Fade
:
<fade xmlns:android="http://schemas.android.com/apk/res/android" />
Ten fragment kodu pokazuje, jak powiększyć instancję Transition
wewnątrz
o swojej aktywności z pliku zasobów:
Kotlin
var fadeTransition: Transition = TransitionInflater.from(this) .inflateTransition(R.transition.fade_transition)
Java
Transition fadeTransition = TransitionInflater.from(this). inflateTransition(R.transition.fade_transition);
Tworzenie w kodzie instancji przejściowej
Ta technika jest przydatna do dynamicznego tworzenia obiektów przejść, jeśli modyfikować interfejs w kodzie i tworzyć proste, wbudowane przejście z instancjami z niewielką liczbą parametrów lub bez nich.
Aby utworzyć instancję wbudowanego przejścia, wywołaj jedną z publicznych
konstruktory w podklasach klasy Transition
. Na przykład parametr
ten fragment kodu tworzy wystąpienie przejścia Fade
:
Kotlin
var fadeTransition: Transition = Fade()
Java
Transition fadeTransition = new Fade();
Zastosuj przejście
Zwykle stosuje się przejście, aby przełączać się między różnymi hierarchiami widoków w w odpowiedzi na zdarzenie, np. działania użytkownika. Przyjrzyjmy się na przykład wyszukiwarce: gdy użytkownik wpisuje wyszukiwane hasło i klika przycisk wyszukiwania, do sceny reprezentującej układ wyników z przejściem, które powoduje zniknięcie przycisku wyszukiwania i zanikanie w wynikach wyszukiwania.
Aby zmienić scenę podczas stosowania przejścia w odpowiedzi na zdarzenie w
swoją aktywność, wywołaj funkcję klasy TransitionManager.go()
z zakończeniem
scena i wystąpienie przejścia, które ma być wykorzystywane w animacji, jak widać na ekranie.
ten fragment:
Kotlin
TransitionManager.go(endingScene, fadeTransition)
Java
TransitionManager.go(endingScene, fadeTransition);
Platforma zmienia hierarchię widoku w głównej części sceny za pomocą widoku. hierarchii od sceny końcowej podczas odtwarzania animacji wskazywanej przez tag z instancji przejścia. Początkowa scena to końcowa scena z ostatniego przejścia. Jeśli nie ma poprzedniego przejścia, określa się scena początkowa. automatycznie od obecnego stanu interfejsu.
Jeśli nie określisz instancji przejścia, menedżer przenoszenia może zastosować
automatyczne przeniesienie, które w większości sytuacji daje sens w sposób rozsądny. Dla:
więcej informacji znajdziesz w dokumentacji interfejsu API
TransitionManager
zajęcia.
Wybierz konkretne widoki docelowe
Struktura stosuje przejścia do wszystkich widoków w scenie początkowej i końcowej
domyślnie. W niektórych przypadkach warto zastosować animację tylko do podzbioru
wyświetleń danej sceny. Platforma umożliwia wybór konkretnych widoków, które chcesz
ani animacji. Na przykład platforma nie obsługuje animowania zmian w
ListView
obiektów, więc nie próbuj animować ich podczas przejścia.
Każdy widok, w którym jest animowany przejście, jest nazywany celem. Do wyboru masz tylko wybrać elementy docelowe należące do hierarchii widoku powiązanej ze sceną.
Aby usunąć co najmniej jeden widok z listy celów, wywołaj funkcję
removeTarget()
przed rozpoczęciem przejścia. Aby dodać tylko określone widoki do
listę celów, wywołaj funkcję
addTarget()
. Więcej informacji znajdziesz w dokumentacji interfejsu API w sekcji
Transition
.
Określ wiele przejść
Aby uzyskać jak największy wpływ animacji, dopasuj ją do typu zmian, między scenami. Na przykład jeśli usuniesz niektóre widoki i dodasz między scenami, rozjaśnienie lub zaniknięcie animacji zapewnia może oznaczać, że niektóre widoki nie są już dostępne. Jeśli przenosisz widoki do w różnych punktach na ekranie, lepiej animować ruch, użytkownicy zauważają nową lokalizację wyświetleń.
Nie musisz wybierać tylko jednej animacji, ponieważ pozwala łączyć efekty animacji w zestawie przejść, który zawiera grupę pojedyncze wbudowane lub niestandardowe przejścia.
Aby zdefiniować zestaw przejść ze zbioru przejść w formacie XML, utwórz
pliku zasobów w katalogu res/transitions/
i wymień przejścia pod
element TransitionSet
. Na przykład ten fragment kodu pokazuje, jak
określ zestaw przejść, który będzie taki sam jak AutoTransition
zajęcia:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="sequential"> <fade android:fadingMode="fade_out" /> <changeBounds /> <fade android:fadingMode="fade_in" /> </transitionSet>
Aby zwiększyć zakres przejścia
TransitionSet
obiekt w
dla swojego kodu, wywołaj funkcję
TransitionInflater.from()
w Twojej aktywności. Klasa TransitionSet
rozciąga się od
Transition
, możesz więc używać jej wraz z menedżerem przenoszenia, tak jak w przypadku każdej innej usługi.
inną instancję Transition
.
Zastosuj przejście bez scen
Zmiana hierarchii widoków to nie jedyny sposób na zmodyfikowanie interfejsu użytkownika. Ty również wprowadzić zmiany, dodając, modyfikując lub usuwając widoki podrzędne w bieżącej hierarchii.
Możesz np. wdrożyć interakcję związaną z wyszukiwaniem z użyciem parametru
jeden układ. Zacznij od układu zawierającego pole do wpisywania wyszukiwania i wyszukiwanie
. Aby zmienić interfejs użytkownika tak, aby wyświetlały się wyniki, usuń przycisk wyszukiwania
gdy użytkownik go kliknie, wywołując
ViewGroup.removeView()
i dodaj wyniki wyszukiwania, wywołując
ViewGroup.addView()
.
Możesz użyć tego podejścia, jeśli alternatywą jest 2 hierarchie, które są prawie identyczne. Zamiast tworzyć i utrzymywać dwa osobne pliki układu dla niewielkiej różnicy w interfejsie możesz mieć jeden plik układu zawierające hierarchię widoków, którą modyfikujesz w kodzie.
Jeśli wprowadzisz zmiany w bieżącej hierarchii widoków w taki sposób, musisz utworzyć scenę. Zamiast tego możesz utworzyć i zastosować przejście między dwóch stanów w hierarchii widoku korzystającego z opóźnionego przejścia. Ta funkcja platforma przejść zaczyna się od bieżącego stanu hierarchii widoków, rekordy zmian wprowadzanych w widokach oraz zastosowanie przejścia, które animuje zmienia się, gdy system ponownie wyświetla interfejs użytkownika.
Aby utworzyć opóźnione przejście w obrębie hierarchii pojedynczego widoku, postępuj zgodnie z tymi kroki:
- Gdy wystąpi zdarzenie, które aktywuje przejście, wywołaj funkcję
TransitionManager.beginDelayedTransition()
dając widok nadrzędny wszystkich widoków którą chcesz zmienić, oraz przejście, które chcesz zastosować. Platforma przechowuje bieżącą stan widoków podrzędnych i ich wartości właściwości. - Wprowadź zmiany w widokach podrzędnych odpowiednio do swojego przypadku użycia. Struktura rejestruje zmiany wprowadzone w widokach podrzędnych i ich właściwościach.
- Gdy system ponownie przerysuje interfejs zgodnie ze zmianami, platforma animuje zmiany między stanem pierwotnym a nowym.
Przykład poniżej pokazuje, jak animować dodanie widoku tekstu do widoku w hierarchii przy użyciu opóźnionego przejścia. Pierwszy fragment pokazuje układ plik definicji:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:id="@+id/inputText" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> ... </androidx.constraintlayout.widget.ConstraintLayout>
Następny fragment kodu pokazuje kod animujący dodanie widoku tekstu:
Kotlin
setContentView(R.layout.activity_main) val labelText = TextView(this).apply { text = "Label" id = R.id.text } val rootView: ViewGroup = findViewById(R.id.mainLayout) val mFade: Fade = Fade(Fade.IN) TransitionManager.beginDelayedTransition(rootView, mFade) rootView.addView(labelText)
Java
private TextView labelText; private Fade mFade; private ViewGroup rootView; ... // Load the layout. setContentView(R.layout.activity_main); ... // Create a new TextView and set some View properties. labelText = new TextView(this); labelText.setText("Label"); labelText.setId(R.id.text); // Get the root view and create a transition. rootView = (ViewGroup) findViewById(R.id.mainLayout); mFade = new Fade(Fade.IN); // Start recording changes to the view hierarchy. TransitionManager.beginDelayedTransition(rootView, mFade); // Add the new TextView to the view hierarchy. rootView.addView(labelText); // When the system redraws the screen to show this update, // the framework animates the addition as a fade in.
Zdefiniuj wywołania zwrotne cyklu życia przejścia
Cykl przejścia jest podobny do cyklu życia aktywności. Reprezentuje on
stany przejściowe, które platforma monitoruje w okresie między wywołaniem
do funkcji TransitionManager.go()
i wykonania funkcji
animację. W ważnych stanach cyklu życia platforma wywołuje wywołania zwrotne
zdefiniowane przez TransitionListener
za pomocą prostego interfejsu online.
Wywołania zwrotne cyklu życia przejścia przydają się na przykład do kopiowania widoku
od początkowej hierarchii widoków do końcowej
podczas zmiany sceny. Nie możesz po prostu skopiować wartości z widoku początkowego do
w końcowej hierarchii widoków, bo końcowa hierarchia widoków nie jest
jest zwiększana do momentu ukończenia przejścia. Zamiast tego musisz zapisać wartość
w zmiennej, a następnie skopiuj ją do końcowej hierarchii widoku, gdy platforma
Użytkownik zakończył przenoszenie danych. Aby otrzymać powiadomienie o zakończeniu przenoszenia,
zastosuj
TransitionListener.onTransitionEnd()
w Twojej aktywności.
Więcej informacji znajdziesz w dokumentacji interfejsu API w sekcji
TransitionListener
zajęcia.
Ograniczenia
W tej sekcji znajdziesz kilka znanych ograniczeń platformy przejść:
- Animacje zastosowane do
Opcja
SurfaceView
może się nie pojawiać .SurfaceView
instancja jest aktualizowana z wątku niezwiązanego z interfejsem, więc mogą nie być zsynchronizowane z animacjami w innych widokach. - Niektóre typy przejść mogą nie dawać pożądanego efektu animacji.
po zastosowaniu do elementu
TextureView
. - Klasy, które obejmują
AdapterView
, na przykładListView
, zarządzać widokami dziecka w sposób niezgodny z z struktury przejścia. Jeśli spróbujesz animować widok na podstawie elementuAdapterView
, ekran urządzenia może przestać odpowiadać. - Jeśli próbujesz zmienić rozmiar elementu
TextView
za pomocą animacji, tekst przesuwa się w nowe miejsce, zanim obiekt zostanie całkowicie rozmiar został zmieniony. Aby uniknąć tego problemu, nie animuj zmiany rozmiaru widoków, które zawierają tekstu.