android - 从片段访问 content_main.xml 的视图?
问题描述
在我的应用程序中,我使用NavController
Fragments。在某些片段中,我需要访问MainActivity
布局视图。我这样做是这样的:
val fab: FloatingActionButton = requireActivity().findViewById(R.id.fab)
这按预期正常工作。但是,一个视图不想被调用并且findViewById()
返回 null。
布局结构是这样的。在activity_main.xml
<androidx.drawerlayout.widget.DrawerLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
....>
<FrameLayout
android:id="@+id/frame"
.... />
<include
android:id="@+id/include"
layout="@layout/app_bar_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav"
.... />
</androidx.drawerlayout.widget.DrawerLayout>
已经包括了app_bar_main.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
....>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
....>
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing"
....>
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
.... />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<include
android:id="@+id/content"
layout="@layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
.... />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
包括content_main.xml
<androidx.core.widget.NestedScrollView
android:id="@+id/nested"
....>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/host"
.... />
</androidx.core.widget.NestedScrollView>
问题是,我需要访问NestedScrollView
,虽然可以访问所有其他视图,但无法访问此视图content_main.xml
并返回 null:
java.lang.NullPointerException: requireActivity().findViewById(R.id.nested) must not be null
编辑:
class HomeFragment : Fragment() {
private lateinit var drawer: DrawerLayout
private lateinit var nested: NestedScrollView
private lateinit var fab: FloatingActionBar
private lateinit var bng: FragmentHomeBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
setHasOptionsMenu(true)
bng = FragmentHomeBinding.inflate(layoutInflater, container, false)
return bng.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
drawer = requireActivity().findViewById(R.id.drawer)
fab = requireActivity().findViewById(R.id.fab)
nested = requireActivity().findViewById(R.id.nested) // This line throws exception
.........
}
}
如您所见,我viewBinding
用来处理 Fragment 的Views
s。我不认为这可能是问题。
解决方案
因此,如果有人应该寻找解决方案,这里有一个对我有用的解决方案。首先,我发现我需要重新排序我的XML
布局,以便将 thecontent_main.xml
和 the的内容app_bar_layout.xml
直接放入activity_main.xml
如下所示:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer"
...>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator"
...>
<com.google.android.material.appbar.AppBarLayout
... >
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing"
... >
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
... />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/nested"
... >
<androidx.fragment.app.FragmentContainerView
android:id="@+id/host"
... />
</androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
... />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav"
... />
</androidx.drawerlayout.widget.DrawerLayout>
这可能不是最佳方式,但如果没有这一步,View
s oncontent_main.xml
就无法访问,这在正常工作之前确实是胡说八道。实际上,不知道,但似乎谷歌改变了它的库中的一些东西或者任何应该的东西。
下一步,View
如果你想activity_main.xml
从某个地方访问Fragment
,你必须将它们公开:
MainActivity.kt
class MainActivity : AppCompatActivity() {
...
lateinit var fab: FloatingActionButton
lateinit var nested: NestedScrollView
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
nested = findViewById(R.id.nested)
fab = findViewById(R.id.fab)
...
}
}
现在,它们可以Fragment
像这样使用:
MyFragment.kt
class MyFragment : Fragment() {
...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_my, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
var fab: FloatingActionButton
var nested: NestedScrollView
(activity as MainActivity).apply {
fab = this.fab
nested = this.nested
}
...
}
}
这就是所有的家伙!通过这种方式,我可以实现我的目标。
如上所述,这可能不是最佳方式,但它对我有用。
希望这可以帮助某人解决此类问题。
欢迎和赞赏任何改进或建议。
推荐阅读
- javascript - jQuery 代码仅适用于浏览器的编辑器,但不适用于脚本标签
- swiftui - 宽度为 0 的 swiftUI 按钮仍然处于活动状态
- javascript - Discord Bot 不加入语音频道 (JS)
- java - org.springframework.expression.spel.SpelEvaluationException:EL1008E:在对象上找不到属性或字段“latestTotalCases”
- javascript - 将多个 div 元素映射到数组中
- angular - NullInjectorError:商店没有提供者!AUTH GUARD Angular 9
- python-3.x - tkinter 可以分别处理鼠标滚轮前进和后退事件吗?
- python-3.x - 为什么 Boto3 会给出 s3 创建错误?
- javascript - 如何在页面加载中弹出对话框
- python - 从Openpyxl导出后,需要在excel的每个单元格中按回车将单元格格式转换为日期