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>