NullPointerException on calling method from Fragment

68 Views Asked by At

I'm encountering a NullPointerException when trying to use VideoSupportFragment in my Activity. I've added the fragment directly to the Activity, but it throws this error.

FATAL EXCEPTION: main                                                                    
Process: com.example.firstdemotv, PID: 32115

java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.leanback.widget.VerticalGridView androidx.leanback.app.RowsSupportFragment.getVerticalGridView()' on a null object reference
    at androidx.leanback.app.PlaybackSupportFragment.setupChildFragmentLayout(PlaybackSupportFragment.java:780)
    at androidx.leanback.app.PlaybackSupportFragment.onStart(PlaybackSupportFragment.java:955)
    at androidx.fragment.app.Fragment.performStart(Fragment.java:3021)
    at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:589)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:300)
    at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)                                                                                                

I've tried all the suggested solutions, but the only thing that fixes the issue is changing the fragment type from VideoSupportFragment to Fragment. This makes the fragment work correctly, but it also means I can't utilize the specific features of VideoSupportFragment anymore.

I have upgraded my leanback library version to 1.2.0-alpha04 from 1.0.0

my Listfragment which type is RowsSupportFragment()

class ListFragment : RowsSupportFragment() {

private var itemSelectedListener: ((DataModel.Result.Detail) -> Unit)? = null
private var itemClickListener: ((DataModel.Result.Detail) -> Unit)? = null

private val listRowPresenter = object : ListRowPresenter(FocusHighlight.ZOOM_FACTOR_MEDIUM) {
    override fun isUsingDefaultListSelectEffect(): Boolean {
        return false
    }
}.apply {
    shadowEnabled = false
}

private var rootAdapter: ArrayObjectAdapter = ArrayObjectAdapter(listRowPresenter)


override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    adapter = rootAdapter

    onItemViewSelectedListener = ItemViewSelectedListener()
    onItemViewClickedListener = ItemViewClickListener()
}

fun bindData(dataList: DataModel) {

    dataList.result.forEachIndexed { index, result ->
        val arrayObjectAdapter = ArrayObjectAdapter(ItemPresentor())

        result.details.forEach {
            arrayObjectAdapter.add(it)
        }

        val headerItem = HeaderItem(result.title)
        val listRow = ListRow(headerItem, arrayObjectAdapter)
        rootAdapter.add(listRow)

    }

}

fun bindCastData(list: List<CastResponse.Cast>) {
    val arrayObjectAdapter = ArrayObjectAdapter(CastItemPresenter())

    list.forEach { content ->
        arrayObjectAdapter.add(content)
    }

    val headerItem = HeaderItem("Cast & Crew")
    val listRow = ListRow(headerItem, arrayObjectAdapter)
    rootAdapter.add(listRow)}}

i'm calling my listFragment in two different screens one in DetialActivity : FragmentActivity()

class DetailActivity : FragmentActivity() {

private lateinit var binding: ActivityDetailBinding
lateinit var viewmodel: DetailViewmodel
val castFragment = ListFragment()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    binding = DataBindingUtil.setContentView(this, R.layout.activity_detail)

    addFragment(castFragment)

    val movieId = intent.getIntExtra("id", 0)

    val repository = (application as MyApplication).tmdbRepo

    viewmodel = ViewModelProvider(
        owner = this,
        factory = DetailViewmodelFactory(repository, movieId)
    )[DetailViewmodel::class.java]

    viewmodel.movieDetails.observe(this) {

        when (it) {
            is Response.Loading -> {

            }

            is Response.Success -> {
                setData(it.data)
            }

            is Response.Error -> {

            }

            else -> {}
        }

    }

    viewmodel.castDetails.observe(this) {

        when (it) {
            is Response.Loading -> {

            }

            is Response.Success -> {
                if (!it.data?.cast.isNullOrEmpty()) {
                    castFragment.bindCastData(it.data?.cast!!)
                }
            }

            is Response.Error -> {

            }

            else -> {}
        }
    }

    binding.addToMylist.setOnKeyListener { view, keyCode, keyEvent ->
        when (keyCode) {
            KeyEvent.KEYCODE_DPAD_DOWN -> {
                if (keyEvent.action == KeyEvent.ACTION_DOWN) {
                    castFragment.requestFocus()
                }
            }
        }

        false
    }

    binding.play.setOnClickListener {
        val intent = Intent(this@DetailActivity, PlaybackActivity::class.java)
        startActivity(intent)
    }
}

and in HomeFragment : Fragment()

class HomeFragment : Fragment() {

private lateinit var binding: FragmentHomeBinding
val listFragment = ListFragment()

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    binding = FragmentHomeBinding.inflate(inflater, container, false)
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val transaction = requireActivity().supportFragmentManager.beginTransaction()
    transaction.add(binding.listFragments.id, listFragment)
    transaction.commit()

    val gson = Gson()
    val i: InputStream = requireContext().assets.open("movies.json")
    val br = BufferedReader(InputStreamReader(i))
    val dataList: DataModel = gson.fromJson(br, DataModel::class.java)

    listFragment.bindData(dataList)
    listFragment.setOnContentSelectedListener {
        updateBanner(it)
    }
    listFragment.setOnItemClickListener {
        val intent = Intent(requireActivity(), DetailActivity::class.java)
        intent.putExtra("id", it.id)
        startActivity(intent)
        requireActivity().finish()
    }

}
0

There are 0 best solutions below