Pull to refresh

Safe Args — верный помощник Navigation Component

Reading time3 min
Views9.2K

В этой статье вы узнаете, кто такой этот Safe Args, как он упрощает жизнь и что является продуктом его работы, в том числе и за кулисами.

Вы сейчас во второй части большого материала про Navigation Component в многомодульном проекте. Если вы впервые слышите про Navigation Component, то рекомендую сначала почитать, что вообще такое Navigation Component. Если уже знакомы с азами, то можно переходить к самому интересному:

Safe Args — это плагин, идущий отдельно от Navigation Component, но созданный специально для того, чтобы с библиотекой работалось легче. С ним нет необходимости указывать id destination-а и передавать параметры через Bundle — плагин генерирует для этого отдельные классы и имеет набор extension-ов для работы с ними. Давайте разбираться, как это всё работает.

Во-первых, вместе с плагином появился новый тег в xml: <argument>. Он применим и к action, и к destination — так можно передавать и принимать параметры в более удобном виде. Во-вторых, на основе экранов и переходов, указанных в графе, генерируются специальные классы, которые можно указывать в NavController-е вместо id action.

Show me the code!

<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"    
    android:id=”@+id/graphuserflow”    
    app:startDestination=”@id/fragmentUserList”>    
    <fragment        
        android:id=”@+id/fragmentUserList”        
        android:label=”FragmentUserList”        
        android:name=”com.example.usersList.UserListFragment”        
        tools:layout=”@layout/fragmentuserlist”>            
        <action            
            android:id=”@+id/actiontouserdetails”            
            pp:destination=”@id/fragmentUserList” >            
            <argument                
                android:name=”userId”                
                app:argType=”integer”                
                app:nullable=”false” />         
        </action>    
    </fragment>    
    <fragment        
        android:id=”@+id/fragmentUserDetails”        
        android:label=”FragmentUserDetails”        
        android:name=”com.example.usersList.UserDetails”        
        tools:layout=”@layout/fragmentuser_details”/>
</navigation>

Здесь мы взяли: достаточно простой граф, где есть фрагмент, вложенный граф и переход от одного к другому. Единственная особенность — пресловутый <argument>, с помощью которого мы передаем в users details фрагмент параметр userId. Пересоберём проект и посмотрим, что получилось.

class UserListFragmentDirections private constructor() {
    private data class ActionUserFromListToDetails(
    val userId: Int
    ) : NavDirections {
        override fun getActionId(): Int = R.id.actionToUserDetails
        
        override fun getArguments(): Bundle {
            val result = Bundle()
            result.putInt(“userId”, this.userId)
            return result
        }
    }
    companion object {
        fun actionToUserDetails(userId: Int): NavDirections =
        ActionToUserDetails(userId)
    }
}

В generated-папке модуля, где лежит граф, находим вот такой класс — обертку, которая включает в себя все переходы, указанные в графе с уже включенными туда параметрами. В нашем случае это переход на экран деталей пользователя и передача туда аргумента userId.

Теперь вызов перехода будет выглядеть так:

navController.navigate(
    UserListFragmentDirections.actionToUserDetails(userId)
)

А параметры в целевом destination-е можно получить через extension, который теперь у нас имеется.

private val args by navArgs<UserDetailsFragmentArgs>()
private val userId by lazy { args.userId }

Сам класс аргументов тоже генерируется в отдельный класс, который содержит методы упаковки и распаковки параметров в Bundle, но он уже не так интересен.

В итоге

Safe Args — приятное дополнение к Navigation Component, благодаря которому мы облегчили себе работу с id переходов и обработки получения/отправки их аргументов. Использовать его или нет — дело ваше, но дальнейшее повествование основано на использовании это плагина. Спойлер: он принесет немало проблем, но в конце все будут счастливы :)

А теперь к самому интересному. Взглянем, как можно организовать работу с Navigation Component в многомодульном проекте совместно с SafeArgs и iOS-like multistack-навигацию.

Tags:
Hubs:
+3
Comments0

Articles