简体   繁体   English

如何使用 ViewBinding 从父布局访问视图?

[英]How to access a view from parent layout with ViewBinding?

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.我想要的是从片段内部访问 FAB。

fragment_user_anime_list(parent) fragment_user_anime_list(父)

<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) fragment_my_anime_list(子浏览器页面)

<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.这会引发 Null 指针异常。 view cannot be null查看不能是 null

How do I get a reference to the fab using viewBinding?如何使用 viewBinding 获得对 fab 的引用?

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.你得到 parentfragment 并直接引用它的视图。

val fab = requireParentFragment().random_fab

and then you can check if it's null and do whatever you want然后你可以检查它是否是 null 并做任何你想做的事情

fab?.let{
   //Do something
}

If anyone knows how to do it using viewBinding let me know.如果有人知道如何使用 viewBinding 让我知道。

How do I get a reference to the fab using viewBinding?如何使用 viewBinding 获得对 fab 的引用?

Now you want to access the FAB from one of ViewPager pages/fragments through data binding.现在您想通过数据绑定从ViewPager页面/片段之一访问FAB

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.通常应在其生命周期所有者(即其活动/片段)内访问视图,因此父片段(承载 FAB 和 ViewPager)的视图应由该片段而不是页面片段触及。

You did a milestone by using requireParentFragment() .您使用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.但不是直接从页面引用FAB ,您可以在父片段中创建一个方法,然后从页面访问此方法。 And do the changes on FAB on this method.并在此方法上对 FAB 进行更改。

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.通过这种方法,您可以在页面和parentFragment之间传递数据,而无需从另一个 Fragment 触摸一个 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.并从页面调用requireParentFragment().changeMyFab() ,您可以传递一些数据作为方法参数来更改 FAB 行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM