Omówiliśmy już podstawy biblioteki Navigation. W tym artykule przyjrzymy się innym funkcją, które oferuje.
Dodawanie przejść
Możesz dodać niestandardowe animacje do akcji. W tym celu otwórz swój wykres i dodaj następujące atrybuty do akcji:
app:enterAnim="@anim/nav_default_enter_anim" app:exitAnim="@anim/nav_default_exit_anim" app:popEnterAnim="@anim/nav_default_pop_enter_anim" app:popExitAnim="@anim/nav_default_pop_exit_anim"
Każdy z tagów definiuje przejście dla jednego z przypadków:
- enterAnim — animacja, która ma zostać użyta, gdy otwieramy miejsca docelowe.
- exitAnim — animacja, która ma być używana, gdy opuszczamy miejsca docelowe.
- popEnterAnim — animacja, która ma być używana, gdy miejsce docelowe jest przenoszone na górną część stosu.
- popExitAnim — animacja, która ma być używana, gdy miejsce docelowe jest przenoszone na dalszą pozycję w stosie.
Każda animacja, której chcesz użyć, musi być zdefiniowana we własnym pliku zasobów animacji, w katalogu „res/anim”. Jeśli Twój projekt nie zawiera jeszcze tego katalogu, musisz go utworzyć. A jak może wyglądać przykładowa animacja? Ano tak:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="0%" android:toYDelta="-100%" android:duration="1500"> </translate> </set>
Przejścia można również zdefiniować programowo za pomocą instancji NavOptions.Builder:
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_list_news, container, false); ... NavOptions navOptions = new NavOptions.Builder() .setEnterAnim(R.anim.nav_default_enter_anim) .setExitAnim(R.anim.nav_default_exit_anim) .setPopEnterAnim(R.anim.nav_default_pop_enter_anim) .setPopExitAnim(R.anim.nav_default_pop_exit_anim) .build(); list.setOnItemClickListener((adapterView, view1, position, id) -> { Bundle args = new Bundle(); args.putInt("idNews", position); // Navigation.findNavController(view).navigate(R.id.goToDetails, args); Navigation.findNavController(view1).navigate(R.id.goToDetails, null, navOptions); }); return view; }
Uzupełnij wiedze o: Task i Back Stack w Androidzie
Zagnieżdżone wykresy
Wraz z rozwojem aplikacji o nowe możliwości, a co za tym idzie, powstają nowe aktywności, fragmenty. W pewnym momencie jeden wykres nie wystarcza. Może zdarzyć się sytuacja, w której chcesz pogrupować pewne części. Na przykład masz aplikację, w której masz funkcje darmowe i płatne. Chcesz pogrupować wykres na część darmową i premium. Do tego właśnie przydadzą się zagnieżdżone wykresy. Aby to uczynić, Twój wykres może przybrać taką formę:
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" app:startDestination="@id/listNews"> <fragment android:id="@+id/listNews" android:name="net.myenv.architecturecomponents.Navigation.ListNews" android:label="News" tools:layout="@layout/fragment_list_news"> <action android:id="@+id/goToDetails" app:destination="@id/details" /> <action android:id="@+id/premium_articles" app:destination="@id/details" /> </fragment> <fragment android:id="@+id/details" android:name="net.myenv.architecturecomponents.Navigation.Details" android:label="Details" /> <navigation android:id="@+id/content_premium" app:startDestination="@id/premium_articles" <fragment android:id="@+id/readLeter" android:label="Read leter" android:name="net.myenv.architecturecomponents.Navigation.ReadLeter" tools:layout="@layout/fragment_read_leter"/> <fragment android:id="@+id/premium_articles" android:label="Premium Articles" android:name="net.myenv.architecturecomponents.Navigation.PremiumArticles" tools:layout="@layout/fragment_premium_articles"/> </navigation> </navigation>
Oczywiście możemy część premium przenieść do osobnego pliku i wtedy w głównym wykresie dodać znacznik include.
<include app:graph="@navigation/premium_graph" />
Warunkowa nawigacja
Może zdarzyć się tak, że potrzebujesz przekierować użytkownika do pewnego ekranu w zależności od spełnienia jakiegoś warunku. Kontynuując nasz przykład z poprzednich artykułów — posiadamy aplikację z artykułami. Jeżeli użytkownik posiada zapisane artykuły, to przekieruj go do odpowiedniego ekranu. W przeciwnym wypadku przekieruj użytkownika do wyszukiwarki artykułów. Nasz kod może wyglądać wtedy tak:
if (hasFavorites()) destination = R.id.action_Favorites; else destination = R.id.action_Search; Navigation.findNavController(this, destination).navigateUp();
Nie zapomnij dodać odpowiednich akcji do wykresu we fragmencie ListNews (zobacz poprzedni wpis).
Opcjonalnie możemy dodać trzeci argument do funkcji navigate(). Określa on opcję nawigacji. W naszym przypadku czyści tylny ston, aby uniemożliwić użytkownikowi powrót do fragmentu ListNews.
NavOptions.Builder().setPopUpTo(R.id.listNews,true).build();
W tym przypadku mamy tylko jedno miejsce docelowe i musimy je także wyczyścić. Zatem ustawimy parametr inclusive na true.
Bardziej zaawansowany przykład możesz znaleźć tutaj.
Głębokie linkowanie
O linkowaniu już pisałem na blogu. Możesz zapoznać się z tym artykułem pod tym adresem. Zapoznałeś się z nim? Ok to ruszamy dalej.
Głębokie linki to adresy URL, które prowadzą do określonego ekranu lub zawartości w Twojej aplikacji. Aby korzystać z tej możliwości w bibliotece Navigation, musimy dodać odpowiedni wpis do naszego wykresu. Załóżmy, że chcemy bezpośredni link do fragmentu ReadLeter. Kod może wyglądać następująco:
<fragment android:id="@+id/readLeter" android:label="Read leter" android:name="net.myenv.architecturecomponents.Navigation.ReadLeter" tools:layout="@layout/fragment_read_leter"> <deepLink android:id="@+id/deepLink" app:uri="https://www.myenv.net/readLeter" /> </fragment>
Aby włączyć niejawne głębokie linkowanie, musisz dodać wpis do manifestu aplikacji.
<activity name=".MainActivity" ...> ... <nav-graph android:value="@navigation/basic_navigation" /> ... </activity>