使用 JetPack Navigation 启动带有 recyclerview 的片段
Starting a fragment with a recyclerview using JetPack Navigation
我有一个应用 MainActivity
但所有工作都在片段中。
我使用 JetPack
导航将片段布局设为 HomePage
。它奏效了。但是当我添加回收器视图时它崩溃了。
错误是这样的:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.saheralsous.android, PID: 12418
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.saheralsous.android/com.saheralsous.android.MainActivity}: android.view.InflateException: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.view.InflateException: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Error inflating class fragment
Caused by: java.lang.NullPointerException: null cannot be cast to non-null type androidx.recyclerview.widget.RecyclerView
at com.saheralsous.android.PhotoGalleryFragment.onCreateView(PhotoGalleryFragment.kt:45)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:699)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:195)
at com.saheralsous.android.MainActivity.onCreate(MainActivity.kt:9)
at android.app.Activity.performCreate(Activity.java:8000)
E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我没有在主要部分添加或更改任何内容 activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
仅在 activity_main 我添加了导航组件的片段
<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"
tools:context=".MainActivity">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
我以这种方式初始化片段中的回收视图:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
/**
* PagingDataAdapter
*/
RecyclerViewPhotoAdapter = RecyclerViewPhotoAdapter()
/**
* Recycler View
*/
PhotoRecyclerView =
view?.findViewById(R.id.recyclerview_main) as RecyclerView
PhotoRecyclerView.layoutManager = LinearLayoutManager(context)
//linking adapter with recyclerview
PhotoRecyclerView.adapter = RecyclerViewPhotoAdapter
/**
* Adapter, Repository and viewmodel
*/
pagingAdapter = PhotoPaging(
(requireActivity().application as MyApplication).networkApi
)
repository = GalleryFlowRepositoryImpl(pagingAdapter)
viewModel = ViewModelProvider(this, ViewModelProviderFactory(
PhotoGalleryViewModel::class
){
PhotoGalleryViewModel(repository)
}).get(PhotoGalleryViewModel::class.java)
//observing data
observers()
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_photo_gallery, container, false)
}
fragment_photo_gallery布局就是这样
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PhotoGalleryFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</FrameLayout>
我发现你的代码有问题。
您在使用 RecyclerView 之前没有填充视图。
PhotoRecyclerView =
view?.findViewById(R.id.recyclerview_main) 作为 RecyclerView
在那里,视图应该是空的。因为你没有膨胀视图。
所以要解决你的问题,有两种方法。
首先,在 onCreateView 方法中,您应该在使用前膨胀视图。
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var view = inflater.inflate(R.layout.fragment_photo_gallery, container, false)
/**
* PagingDataAdapter
*/
RecyclerViewPhotoAdapter = RecyclerViewPhotoAdapter()
/**
* Recycler View
*/
PhotoRecyclerView =
view?.findViewById(R.id.recyclerview_main) as RecyclerView
PhotoRecyclerView.layoutManager = LinearLayoutManager(context)
//linking adapter with recyclerview
PhotoRecyclerView.adapter = RecyclerViewPhotoAdapter
/**
* Adapter, Repository and viewmodel
*/
pagingAdapter = PhotoPaging(
(requireActivity().application as MyApplication).networkApi
)
repository = GalleryFlowRepositoryImpl(pagingAdapter)
viewModel = ViewModelProvider(this, ViewModelProviderFactory(
PhotoGalleryViewModel::class
){
PhotoGalleryViewModel(repository)
}).get(PhotoGalleryViewModel::class.java)
//observing data
observers()
// Inflate the layout for this fragment
return view
}
或者其次,您可以在 onViewCreated 方法中使用您的代码。
在您的 onCreateView
中,您在展开布局之前访问视图。
行:
PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as RecyclerView
您尝试在视图中检索 recyclerview_main
,因为此时布局未膨胀。
然后你强制将其转换为 RecyclerView
(as RecyclerView
而不是 as? RecyclerView
用于可选转换)导致 NullPointerExcepion
.
我建议将您的代码移动到 onViewCreated
方法中。
好的,这不是什么大问题你需要在使用前充气view
首先,将其添加到 onCreateView
的顶部
val view = inflater.inflate(R.layout.fragment_photo_gallery, container, false)
然后return最后查看
return view
希望我的回答对您有所帮助
我有一个应用 MainActivity
但所有工作都在片段中。
我使用 JetPack
导航将片段布局设为 HomePage
。它奏效了。但是当我添加回收器视图时它崩溃了。
错误是这样的:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.saheralsous.android, PID: 12418
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.saheralsous.android/com.saheralsous.android.MainActivity}: android.view.InflateException: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.view.InflateException: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #20 in com.saheralsous.android:layout/activity_main: Error inflating class fragment
Caused by: java.lang.NullPointerException: null cannot be cast to non-null type androidx.recyclerview.widget.RecyclerView
at com.saheralsous.android.PhotoGalleryFragment.onCreateView(PhotoGalleryFragment.kt:45)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:699)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:195)
at com.saheralsous.android.MainActivity.onCreate(MainActivity.kt:9)
at android.app.Activity.performCreate(Activity.java:8000)
E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我没有在主要部分添加或更改任何内容 activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
仅在 activity_main 我添加了导航组件的片段
<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"
tools:context=".MainActivity">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
我以这种方式初始化片段中的回收视图:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
/**
* PagingDataAdapter
*/
RecyclerViewPhotoAdapter = RecyclerViewPhotoAdapter()
/**
* Recycler View
*/
PhotoRecyclerView =
view?.findViewById(R.id.recyclerview_main) as RecyclerView
PhotoRecyclerView.layoutManager = LinearLayoutManager(context)
//linking adapter with recyclerview
PhotoRecyclerView.adapter = RecyclerViewPhotoAdapter
/**
* Adapter, Repository and viewmodel
*/
pagingAdapter = PhotoPaging(
(requireActivity().application as MyApplication).networkApi
)
repository = GalleryFlowRepositoryImpl(pagingAdapter)
viewModel = ViewModelProvider(this, ViewModelProviderFactory(
PhotoGalleryViewModel::class
){
PhotoGalleryViewModel(repository)
}).get(PhotoGalleryViewModel::class.java)
//observing data
observers()
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_photo_gallery, container, false)
}
fragment_photo_gallery布局就是这样
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PhotoGalleryFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</FrameLayout>
我发现你的代码有问题。 您在使用 RecyclerView 之前没有填充视图。
PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) 作为 RecyclerView
在那里,视图应该是空的。因为你没有膨胀视图。 所以要解决你的问题,有两种方法。
首先,在 onCreateView 方法中,您应该在使用前膨胀视图。
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var view = inflater.inflate(R.layout.fragment_photo_gallery, container, false)
/**
* PagingDataAdapter
*/
RecyclerViewPhotoAdapter = RecyclerViewPhotoAdapter()
/**
* Recycler View
*/
PhotoRecyclerView =
view?.findViewById(R.id.recyclerview_main) as RecyclerView
PhotoRecyclerView.layoutManager = LinearLayoutManager(context)
//linking adapter with recyclerview
PhotoRecyclerView.adapter = RecyclerViewPhotoAdapter
/**
* Adapter, Repository and viewmodel
*/
pagingAdapter = PhotoPaging(
(requireActivity().application as MyApplication).networkApi
)
repository = GalleryFlowRepositoryImpl(pagingAdapter)
viewModel = ViewModelProvider(this, ViewModelProviderFactory(
PhotoGalleryViewModel::class
){
PhotoGalleryViewModel(repository)
}).get(PhotoGalleryViewModel::class.java)
//observing data
observers()
// Inflate the layout for this fragment
return view
}
或者其次,您可以在 onViewCreated 方法中使用您的代码。
在您的 onCreateView
中,您在展开布局之前访问视图。
行:
PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as RecyclerView
您尝试在视图中检索 recyclerview_main
,因为此时布局未膨胀。
然后你强制将其转换为 RecyclerView
(as RecyclerView
而不是 as? RecyclerView
用于可选转换)导致 NullPointerExcepion
.
我建议将您的代码移动到 onViewCreated
方法中。
好的,这不是什么大问题你需要在使用前充气view
首先,将其添加到 onCreateView
val view = inflater.inflate(R.layout.fragment_photo_gallery, container, false)
然后return最后查看
return view
希望我的回答对您有所帮助