Criação da barra de navegação inferior no Kotlin usando Anko

Iniciando um novo projeto, decidi tentar abandonar completamente os arquivos XML, com base nos layouts formados, e criar telas usando a biblioteca Anko. Tendo pouca experiência em desenvolvimento para Android (cerca de 2 anos) e ainda menos experiência em escrever código no Kotlin (pouco mais de seis meses), imediatamente enfrentei o problema de incluir a barra de navegação inferior criada por BottomNavigationView no aplicativo Componente de Arquitetura de Navegação.


Antes de tudo, voltei-me à Internet para encontrar uma solução possível. Mas todos os artigos que encontrei com diferentes graus de clareza informaram sobre como trabalhar com componentes de navegação e nenhum (daqueles cujos artigos eu estudei) fez no Anko. Tendo resolvido a tarefa, ofereço à comunidade minha opção de criar uma barra de navegação inferior.


Todo o código pode ser visto aqui.
Eu pulo o estágio de criação de um novo projeto no Android Studio, apenas observe as seguintes dependências para trabalhar com o Anko e o Navigation Architecture Component no build.gradle no nível do módulo:


implementation "org.jetbrains.anko:anko:$anko_version" implementation "org.jetbrains.anko:anko-constraint-layout:$anko_version" implementation "com.android.support.constraint:constraint-layout:2.0.0-alpha3" implementation 'android.arch.navigation:navigation-fragment:1.0.0-beta02' implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-beta02' implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-beta02' implementation 'com.google.android.material:material:1.0.0' 

O próximo passo é criar a estrutura do aplicativo futuro. Para desenhar a atividade principal, em vez do arquivo xml, crie a classe MainActivityUI herdada da interface AnkoComponent:


 class MainActivityUI: AnkoComponent<MainActivity> { override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) { constraintLayout { } } } 

Na classe MainActivity, setContentView (R.layout.activity_main) é substituído por MainActivityUI (). SetContentView (this).


Em seguida, criamos fragmentos de pacote nos quais nossos fragmentos e interface do usuário estarão para colocar as classes responsáveis ​​por renderizar telas dos fragmentos correspondentes. Esta é a estrutura do projeto:


 fragments ui HomeUI UsersUI DetailsUI MoreUI HomeFragment UsersFragment DetailsFragment MoreFragment 

Agora, lidaremos diretamente com a navegação e a criação da barra de navegação inferior.
Uma descrição detalhada da inclusão de novos componentes de navegação e uma descrição do trabalho no Editor de Navegação podem ser encontradas na página de documentação aqui . Para criar um arquivo (gráfico) para navegação entre as telas do aplicativo, você precisa adicionar outra pasta à pasta res, a saber navegação, e adicionar o arquivo navigation_graph.xml a ela. Para este projeto, será assim:


 <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/navigation_graph" app:startDestination="@id/homeFragment"> <fragment android:id="@+id/homeFragment" android:name="com.arsinde.ankobottomnavbar.fragments.HomeFragment" android:label="HomeFragment"> <action android:id="@+id/action_homeFragment_to_detailsFragment" app:destination="@id/detailsFragment"/> </fragment> <fragment android:id="@+id/detailsFragment" android:name="com.arsinde.ankobottomnavbar.fragments.DetailsFragment" android:label="DetailsFragment"> <action android:id="@+id/action_detailsFragment_to_usersFragment" app:destination="@id/usersFragment"/> </fragment> <fragment android:id="@+id/usersFragment" android:name="com.arsinde.ankobottomnavbar.fragments.UsersFragment" android:label="UsersFragment"> <action android:id="@+id/action_usersFragment_to_moreFragment" app:destination="@id/moreFragment"/> </fragment> <fragment android:id="@+id/moreFragment" android:name="com.arsinde.ankobottomnavbar.fragments.MoreFragment" android:label="MoreFragment"/> </navigation> 

Para exibir a própria barra, você precisa criar outra pasta de recursos, o menu. Ele contém o arquivo responsável pela parte visível da barra. É assim que parece neste projeto:


 <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@id/homeFragment" android:icon="@drawable/ic_home" android:title="@string/menu_title_home"/> <item android:id="@id/usersFragment" android:icon="@drawable/ic_users" android:title="@string/menu_title_users"/> <item android:id="@id/detailsFragment" android:icon="@drawable/ic_info" android:title="@string/menu_title_details"/> <item android:id="@id/moreFragment" android:icon="@drawable/ic_more" android:title="@string/menu_title_more"/> </menu> 

É hora de juntar tudo e ver como funciona.


Adicione um contêiner para fragmentos no MainActivityUI e também defina um contêiner para a barra de navegação.


 constraintLayout { val fragmentContainer = frameLayout { id = R.id.fragment_container }.lparams { width = matchParent height = matchConstraint } val bottomNavigation = bottomNavigation { id = R.id.bottom_nav_view inflateMenu(R.menu.bottom_navigation_menu) } applyConstraintSet { fragmentContainer { connect( START to START of PARENT_ID, END to END of PARENT_ID, TOP to TOP of PARENT_ID, BOTTOM to TOP of R.id.bottom_nav_view ) } bottomNavigation { connect( START to START of PARENT_ID, END to END of PARENT_ID, TOP to BOTTOM of R.id.fragment_container, BOTTOM to BOTTOM of PARENT_ID ) } } } 

Deve-se notar especialmente que bottomNavigation neste exemplo é uma função de extinção, que tem o seguinte formato:


 inline fun ViewManager.bottomNavigation(init: BottomNavigationView.() -> Unit = {}) = ankoView({ BottomNavigationView(it) }, theme = 0, init = init) 

Agora em MainActivity, você precisa definir o objeto NavHostFragment (consulte o dock):


 private val host by lazy { NavHostFragment.create(R.navigation.navigation_graph) } 

E no método onCreate (), defina:


 supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, host) .setPrimaryNavigationFragment(host) .commit() 

O toque final - adicione à onStart () MainActivity um objeto da classe NavController, que permite a transição entre fragmentos, escolhendo um ou outro objeto da barra de navegação:


 override fun onStart() { super.onStart() val navController = host.findNavController() findViewById<BottomNavigationView>(R.id.bottom_nav_view)?.setupWithNavController(navController) navController.addOnDestinationChangedListener{_, destination, _ -> val dest: String = try { resources.getResourceName(destination.id) } catch (e: Resources.NotFoundException) { Integer.toString(destination.id) } Log.d("NavigationActivity", "Navigated to $dest") } } 

Inicie o aplicativo e veja mais ...


Captura de tela

Source: https://habr.com/ru/post/pt441618/


All Articles