I have a layout that contains a view pager and a fab. The view pager has fragments as pages. What I want is to access the FAB from inside a fragment.
fragment_user_anime_list(parent)
<layout 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">
<data>
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.destructo.sushi.ui.user.animeList.MyAnimeListFragment">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
style="@style/ToolBarWithNavigation"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/PopupMenu"
app:title="@string/my_anime_list"
app:titleTextAppearance="@style/TextAppearance.Sushi.H1" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/my_anime_list_tablayout"
style="@style/TabLayoutStyle"
android:layout_width="fill_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:tabIndicator="@drawable/custom_tab_layout_indicator"
app:tabMode="scrollable" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/my_anime_list_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_gravity="center"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/random_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_normal"
android:layout_marginBottom="@dimen/margin_normal"
android:layout_gravity="bottom|right"
android:src="@drawable/ic_question_line"
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
fragment_my_anime_list(child viewpager page)
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/userAnimeRecycler"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@+id/user_anime_list_pagination_progressbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/user_anime_list_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/userAnimeRecycler" />
<ProgressBar
android:id="@+id/user_anime_list_pagination_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
in the child fragment
private lateinit var binding: FragmentUserAnimeListBinding
private lateinit var randomAnimeFab: FloatingActionButton
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentUserAnimeListBinding
.inflate(inflater, container, false).apply {
lifecycleOwner = viewLifecycleOwner
}
randomAnimeFab = binding.root.random_fab
return binding.root
}
This throws Null pointer exception. view cannot be null
How do I get a reference to the fab using viewBinding?
I found a solution without using view binding. Don't know if it's the best one. You get the parentfragment and reference it's views directly.
val fab = requireParentFragment().random_fab
and then you can check if it's null and do whatever you want
fab?.let{
//Do something
}
If anyone knows how to do it using viewBinding let me know.
How do I get a reference to the fab using viewBinding?
Now you want to access the FAB
from one of ViewPager
pages/fragments through data binding.
Normally views should be accessed within its lifecycle owner (ie its activity/fragment), so views of the parent fragment (which hosts the FAB & the ViewPager), should be touched by this fragment, not by a page fragment.
You did a milestone by using requireParentFragment()
.
val fab = requireParentFragment().random_fab
But instead of referencing the FAB
directly from the page, you can create a method in the parent fragment instead and access this method from the page. And do the changes on FAB on this method.
And through this method, you can pass data between a page and the parentFragment
without having to touch views of a fragment from another fragment.
So you could have a method in the parent fragment:
fun changeMyFab() {
binding.random_fab ...
}
And call requireParentFragment().changeMyFab()
from the page, and you can pass some data as method parameters to change the FAB behavior.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.