【问题标题】:Starting a fragment with a recyclerview using JetPack Navigation [duplicate]使用 JetPack Navigation 使用 recyclerview 启动片段 [重复]
【发布时间】:2021-06-21 15:23:49
【问题描述】:

我有一个具有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)

我没有在主要活动中添加或更改任何内容


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>

【问题讨论】:

  • 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) 这告诉你从哪里开始寻找问题。
  • 我在这一行中唯一的问题是空检查--> PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as RecyclerView
  • PhotoGalleryFragment.kt 的第 45 行是什么?
  • 我为你复制的那个 --> PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as RecyclerView
  • 我解决了....

标签: android android-layout android-fragments android-recyclerview android-jetpack-navigation


【解决方案1】:

在您的onCreateView 中,您可以在扩展布局之前访问视图。

在线: PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as RecyclerView

你尝试在视图中检索 recyclerview_main ,它为空,因为此时布局没有膨胀。

然后您将其强制转换为 RecyclerViewas RecyclerView 而不是 as? RecyclerView 用于可选转换)导致 NullPointerExcepion

我建议将您的代码移动到 onViewCreated 方法中。

【讨论】:

    【解决方案2】:

    好吧,在你使用view之前你需要充气不是一个大问题

    首先,将其添加到您的 onCreateView 顶部

    val view = inflater.inflate(R.layout.fragment_photo_gallery, container, false)

    然后在最后返回视图

    return view

    希望我的回答对你有帮助

    【讨论】:

      【解决方案3】:

      我在您的代码中发现了问题。 您在使用 RecyclerView 之前没有为视图充气。

      PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as 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 方法中使用您的代码。

      【讨论】:

      • 我是来写的……非常感谢……
      • 欢迎,很高兴为您提供帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      相关资源
      最近更新 更多