-1

I have an app that has MainActivity but all the work is in the fragment. I made the fragment layout the HomePage using JetPack navigation. and it worked. but when i added the recycler view it crashed.

the error was this:

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)

I didn't add or change anything in the main 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)
    }
}

only in the activity_main i added the fragment for Navigation compnonent

<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>

i initialize the recyclerview in the fragment this way:

 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 layout is simply this

<?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>
Persi
  • 27
  • 4
Saher Al-Sous
  • 517
  • 4
  • 15
  • `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)` This tells you where to start looking for the problem. – Code-Apprentice Jun 21 '21 at 15:25
  • the only issue i have in this line is the null check--> PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as RecyclerView <--- but it fixed this way... or using the !!.. but neither solve the issue – Saher Al-Sous Jun 21 '21 at 15:26
  • What is line 45 of `PhotoGalleryFragment.kt`? – Code-Apprentice Jun 21 '21 at 15:27
  • the one i copied for you --> PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as RecyclerView – Saher Al-Sous Jun 21 '21 at 15:28
  • i solved it.... – Saher Al-Sous Jun 21 '21 at 15:33

3 Answers3

2

In your onCreateView you access the view before inflating the layout.

At line: PhotoRecyclerView = view?.findViewById(R.id.recyclerview_main) as RecyclerView

you try to retrieve the recyclerview_main in the view wich is null because at this point the layout is not inflated.

Then you force cast it into a RecyclerView (as RecyclerView instead of as? RecyclerView for optional cast) wich lead to a NullPointerExcepion.

I would recommand moving your code into onViewCreated method.

Azartys
  • 543
  • 6
  • 14
2

ok it's not a big problem you need to inflate before you use view

first, add this on the top of your onCreateView

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

then return view at the end

return view

hope my answer helped you

1

I found problem in your code. You didn't inflate view before use RecyclerView.

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

In there, view should be null. because you didn't inflate view. So to resolve your problem, there are two methods.

First, in onCreateView method you should inflate view before using.

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
}

Or Second, you can use your code in onViewCreated method.

Daniel.Wang
  • 2,242
  • 2
  • 9
  • 27