Search code examples
androidkotlinandroid-fragmentsandroid-activityandroid-fragmentactivity

Kotlin fragment : activity returns null outside onActivityCreated


I'm trying to use startActionMode inside a fragment.

startActionMode works fine in the onActivityCreated method. But outside onActivityCreated method, activity returns null and hence activity?.startActionMode(mActionModeCallback) doesn't work.

package com.akshat.music
import android.app.Activity
import android.content.ContentUris
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.*
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_songs.*
import java.io.File


class SongsFragment : Fragment(), SongListAdapter.OnItemClickListener{

private val allSongs = ArrayList<Songs>()
var activityRef: FragmentActivity? = null


override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    activityRef = activity;
    if (activityRef == null)
        Log.d("MIKE", " $activityRef is empty");
    else
        Log.d("MIKE", " $activityRef is not empty");
    recyclerView.apply {
        layoutManager = LinearLayoutManager(activity)
        adapter = SongListAdapter(allSongs, SongsFragment().apply { this@SongsFragment })
    }
    activity?.startActionMode(mActionModeCallback) // works

}

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

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return inflater!!.inflate(R.layout.fragment_songs, container, false);
}

override fun onItemClicked(song: Songs, position: Int) {
    if (activityRef == null)
        Log.d("MIKE", " $activityRef is empty");
    else
        Log.d("MIKE", " $activityRef is not empty");
    activity?.startActionMode(mActionModeCallback)  // doesn't work
    activityRef?.startActionMode(mActionModeCallback) // activityRef is null
}

private val mActionModeCallback: ActionMode.Callback =
    object : ActionMode.Callback {
        override fun onCreateActionMode(
            actionMode: ActionMode,
            menu: Menu
        ): Boolean {
            val menuInflater = actionMode.menuInflater
            menuInflater.inflate(R.menu.contextual_action_bar, menu)
            return true
        }

        override fun onPrepareActionMode(
            actionMode: ActionMode,
            menu: Menu
        ): Boolean {
            return false
        }

        override fun onActionItemClicked(
            actionMode: ActionMode,
            menuItem: MenuItem
        ): Boolean {
            return false
        }

        override fun onDestroyActionMode(actionMode: ActionMode) {
            var actionMode: ActionMode? = actionMode
            actionMode = null
        }
    }

private fun getAudioDirectories() {
    /////////////
    }
}
}

How can I get reference to activity outside onActivityCreated method? Thanks


Solution

  • You should be able to get a reference to the activity from anywhere inside a fragment. there are some cases where activity can be null e.g inside onDetach() or inside OnCreateView(), so activity doesn't always require a value.

    try to use the requireContext() like Stachu has mentioned:

        (requireContext() as Activity).startActionMode(mActionModeCallback)