Migrando para ViewPager2
O ViewPager é basicamente um gerenciador de layout que permite à aplicação exibir páginas de dados (normalmente) semelhantes, onde o usuário pode alternar entre essas páginas utilizando o gesto de swipe (deslizando horizontalmente) para esquerda e para direita.
Recentemente o Google apresentou o ViewPager2, que é parte integrante do Jetpack e que possui algumas melhorias em relação ao seu antecessor:
- Permite o scroll vertical, bastando definir a propriedade
android:orientation
para "vertical"; - Dá suporte a idiomas RTL (Right-to-Left) por meio da propriedade
android:layoutDirection="rtl"
; - É possível modificar a listagem de fragments utilizado no adapter, similar ao que acontece na
RecyclerView
por meio da classeDiffUtil
e com isso, as animações serão feitas automaticamente;
Para utilizar o ViewPager2
a primeira coisa é adicionar a dependência no build.gradle.
dependencies {
implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation "com.google.android.material:material:1.1.0"
}
A dependência da biblioteca do Material Design é opcional, mas deve ser utilizada para exibir as abas do ViewPager2
por meio do componente TabLayout
.
Em seguida devemos definir o adapter.
class MyFragmentAdapter(fa: FragmentActivity)
: FragmentStateAdapter(fa) {
override fun getItemCount(): Int = 4
override fun createFragment(position: Int): Fragment =
SimpleFragment.newInstance("Position: $position")
}
A classe herda de FragmentStateAdapter
e recebe como parâmetro a activity que hospedará o ViewPager2
. Ainda é possível criar o adapter utilizando o construtor que recebe como parâmetro um Fragment
ou ainda um terceiro, que recebe o FragmentManager
e um Lifecycle
.
O método getItemCount
indica quantas páginas serão exibidas. E o método createFragment
, como próprio nome diz, é responsável por criar a instância do Fragment
que será exibido na página correspondente ao parâmetro position
.
O SimpleFragment
usado nesse exemplo é um fragment simples. Seu código está listado a seguir:
class SimpleFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = TextView(requireContext()).apply {
text = arguments?.getString("text") ?: ""
}
companion object {
fun newInstance(s: String) =
SimpleFragment().apply {
arguments = Bundle().apply {
putString("text", s)
}
}
}
}
Em seguida, adicione o ViewPager2
no arquivo de layout.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:tabIndicatorColor="@color/colorAccent"
app:tabTextColor="@android:color/white"
/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Aqui também foi adicionado o TabLayout
que exibirá as abas.
Por fim, na activity, basta utilizar o código a seguir:
pager.adapter = MyFragmentAdapter(this)
TabLayoutMediator(tabs, pager) { tab, position ->
tab.text = "Aba $position"
}.attach()
Primeiramente foi criada uma instância do MyFragmentAdapter
e atribuída ao ViewPager2
declarado no arquivo de layout. Em seguida, foi instanciado um TabLayoutMediator
que será responsável por definir o título das abas do TabLayout
.
Pronto! É isso que você precisa pra criar uma página com abas utilizando o ViewPager2
. O resultado deve ficar como a seguir:
Como mencionei anteriormente, é possível utilizar um RecyclerView.Adapter
para a ViewPager2
. Vejamos o exemplo a seguir.
class MyAdapter: RecyclerView.Adapter<MyAdapter.PageHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): PageHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.layout_page, parent, false)
return PageHolder(view)
}
override fun getItemCount(): Int = 4
override fun onBindViewHolder(
holder: PageHolder,
position: Int
) {
holder.txtTexto.text = "Position: $position"
}
class PageHolder(root: View): RecyclerView.ViewHolder(root) {
val txtTexto = root.txtText
}
}
Se você já conhece uma RecyclerView
deve perceber que ele é um adapter sem nada de especial. Mas com ele, podemos utilizar instâncias da classe View
ao invés de Fragments
no ViewPager2
.
Atribuir o adapter ao ViewPager2
é idêntico ao apresentado anteriormente.
pager.adapter = MyAdapter()
A recomendação é que esse novo componente seja utilizado, uma vez que novas implementações serão realizadas apenas no ViewPager2
. O ViewPager
não será mais mantido e provavelmente será descontinuado (deprecated).
A maioria do conteúdo desse post foi retirado deste vídeo do Android Dev Summit: https://www.youtube.com/watch?v=lAP6cz1HSzA
Qualquer dúvida, deixe seu comentário ;)
4br4ç05
nglauber