首页 > 解决方案 > Fragment Button 由 Activity 的 findViewById 找到,而不是 Fragment 的膨胀 view.findViewById

问题描述

我看到这种奇怪的行为,找不到类似的东西。

所以我有一个父级Activity,里面是一个Fragment,我通过include元素将它包含在父级中,然后在父级中onCreate,创建Fragment并用这个布局替换它include(告诉我这是否是正确的方法?我正在使用FrameLayout但后来切换到include并定义对它id)。

活动

<androidx.constraintlayout.widget.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.sourcey.materiallogindemo.CustomerDetailActivity"
    tools:ignore="MergeRootFrame">

    <com.google.android.material.appbar.AppBarLayout>

        <com.google.android.material.appbar.MaterialToolbar />

    </com.google.android.material.appbar.AppBarLayout>

    <include
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/app_bar"
        app:layout_constraintBottom_toTopOf="@id/layout_bottom_bar"
        layout="@layout/fragment_customer_detail" />

    <androidx.coordinatorlayout.widget.CoordinatorLayout>

        <com.google.android.material.bottomappbar.BottomAppBar>

        </com.google.android.material.bottomappbar.BottomAppBar>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

分段

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context="com.sourcey.materiallogindemo.CustomerDetailFragment"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

<!-- THIS IS THE CULPRIT -->
    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn_update_position"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <com.google.android.material.button.MaterialButton />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/sku_list"
        app:layoutManager="LinearLayoutManager"
        tools:context="com.sourcey.materiallogindemo.CustomerDetailFragment"
        tools:listitem="@layout/fragment_s_k_u_item" />

</androidx.constraintlayout.widget.ConstraintLayout>

Fragmentinflate正确的,但是当我在里面这样做时onCreateView

rootView.btn_update_position.setOnClickListener {
    // ... log something
}

然后按Button,它什么也没做?尽管大多数发现都导致了我应该然后设置inflate的建议。viewonClickListener

我也试过做这些

rootView.findViewById<MaterialButton>(R.id.btn_update_position).setOnClickListener {
    // ... log something
}

val button = rootView.findViewById<MaterialButton>(R.id.btn_update_position)
button.setOnClickListener {
    // ... log something
}

但它们都不起作用。

我还尝试了上述方法,onViewCreated看看我是否没有得到参考,但没有抛出错误,也没有反应。

唯一有效的就是这个

activity?.findViewById<MaterialButton>(R.id.btn_update_position)
    ?.setOnClickListener {
         // ... log something
}

我试图理解为什么会发生这种情况?这可能是使用include的问题Fragment吗?

注意我不是 android 的专业人士,只是在其中做业余爱好,所以对它不太了解。

编辑如您所见,我有一个RecyclerViewinFragment布局,我正在扩展布局,然后设置它的适配器项,这似乎与按钮相反。

rootView.sku_list.adapter = Adapter()

标签: androidandroid-fragmentskotlinandroid-activityinclude

解决方案


我对你想在这里做什么感到有点困惑

首先,<include>不创建新视图,它只是将 xml 包含到父 xml 文件中,所以基本上它仍然在活动中,你需要活动来 findViewById

其次,关于你的问题 FrameLayout 和<include>.

就像我上面说的,它只是将<include>xml 文件添加到父文件中,主要用途是重复使用布局(你可以在任何地方包含它)。

使用 FrameLayout,来自官方文档:“FrameLayout 旨在阻止屏幕上的一个区域以显示单个项目”。例如:你希望你的布局有一个所有屏幕的页眉和页脚,只有中间部分发生变化,所以在中间放置一个框架布局,然后为每个屏幕加载不同的视图,因为这种灵活性框架布局通常用于显示片段(你可以谷歌如何使用框架布局了解更多细节)


推荐阅读