在我的应用程序中,我使用NavController
和片段。在一些片段中,我需要访问有关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
来处理片段的Views
,我不认为这可能是问题。
发布于 2021-01-05 11:03:39
这里有一个对我有用的解决方案。首先,我发现我需要重新排序我的XML
布局,以便像这样将content_main.xml
和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>
这可能不是一种最佳的方法,但如果没有这一步,就无法访问content_main.xml
上的content_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
}
...
}
}
就这样,我就能实现我的目标了。
https://stackoverflow.com/questions/65304976
复制相似问题