0

I am trying to load initial data onto a fragment in my application. In the following lines of code (located at the very end of onCreate, I attempt retrieve the fragment and load data onto it:

// Display the current list of matches to the user
var eventsFragment: EventsFragment =
    supportFragmentManager.findFragmentByTag("eventsFragment") as EventsFragment
eventsFragment.displaySchedule(currList)

However, I receive the following error:

Caused by: kotlin.TypeCastException: null cannot be cast to non-null type com.example.alarmfornbamatches.ui.main.EventsFragment

My guess is that the fragment hasn't loaded at the end of onCreate. So how do I execute the displaySchedule function once the fragment is fully loaded and available to be referenced for UI updates?

Adam Lee
  • 436
  • 1
  • 14
  • 49
  • Regular casts may result into a ClassCastException if the object is not of the target type. Another option is to use safe casts that return null if the attempt was not successful: `var eventsFragment: EventsFragment? = supportFragmentManager.findFragmentByTag("eventsFragment") as? EventsFragment eventsFragment?.displaySchedule(currList)` – Ric17101 Jan 13 '21 at 03:58

3 Answers3

0

You can solve the TypeCastException by using this:

// Display the current list of matches to the user
var eventsFragment: EventsFragment? = supportFragmentManager.findFragmentByTag("eventsFragment") as EventsFragment
eventsFragment?.displaySchedule(currList)
Karan Dhillon
  • 1,186
  • 1
  • 6
  • 14
0

You are looking for a fragment that you haven't created, in a place you haven't put it yet. You must first create the fragment and add it to the supportFragmentManager using transactions. If you want do pass data to the fragment you should do so by add this to your fragment (if your list is not string, then it must be serializable and use putSerializable instead.

companion object{
        fun newInstance(list: ArrayList<String>) = EventsFragment().apply{
            arguments = Bundle().apply {
                putStringArrayList(KEY, list)
            }
        }
    }

and then pull the data out of the arguments bundle in the onCreate method in your fragment.

Now in the onCreate in your activity you will create the fragment and add it like so

eventsFragment = EventsFragment.newInstance(list)
supportFragmentManager.beginTransaction().add(R.id.frameLayoutId, eventsFragment, fragmentTag).commit()

only now, if necessary can you use the code you have to get the fragment again, and you should always do it expecting ti to possibly come back as null:

eventsFragment = supportFragmentManager.findFragmentByTag(fragmentTag) as? EventsFragment ?: EventsFragment.newInstance(list)
0

The problem with your code is you are trying to find a fragment which is not there that's why its null. Not sure where you made the Fragment transaction.

To fix this There can be two cases:

  1. If you already have the data in your Activity its better you pull it inside Fragment by using getActivity() in #onViewCreated() or by a Shared ViewModel.

  2. If you are loading data from a source(Network/IO) then you can use a Shared ViewModel or Get fragment from back stack and call its method or you can use conventional callback stuff.

I can add some sample code but i am not sure which option is best fit for you since its not clear from question that u are using MVVM or not.

ADM
  • 20,406
  • 11
  • 52
  • 83