0
votes

I am trying to create a RecyclerView in a fragment but I am getting a null error on the RecyclerView. I was able to create the fragment successfully using the new Navigation architecture component with a bottom navigation bar. I am running Android Studio canary 3.2 Beta 1.

Note sure where I have gone wrong as I am not getting any red lines in Android Studio.

Debug Error

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.projects.arise.mytestapp, PID: 28285 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.projects.arise.mytestapp/com.projects.arise.mytestapp.MainActivity}: java.lang.IllegalStateException: rview_keys must not be null at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) Caused by: java.lang.IllegalStateException: rview_keys must not be null at com.projects.arise.mytestapp.MainActivity.onCreate(MainActivity.kt:55) at android.app.Activity.performCreate(Activity.java:6975) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)  at android.app.ActivityThread.-wrap11(Unknown Source:0)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)  at android.os.Handler.dispatchMessage(Handler.java:105)  at android.os.Looper.loop(Looper.java:164)  at android.app.ActivityThread.main(ActivityThread.java:6541)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val host: NavHostFragment = supportFragmentManager
                .findFragmentById(R.id.nav_host_fragment) as NavHostFragment? ?: return

        val navController = host.navController
        setupBottomNavMenu(navController)
    }

    override fun onSupportNavigateUp(): Boolean {
        return Navigation.findNavController(this, R.id.nav_host_fragment).navigateUp()
    }

    private fun setupBottomNavMenu(navController: NavController) {
        findViewById<BottomNavigationView>(R.id.navigation)?.let { bottomNavView ->
            NavigationUI.setupWithNavController(bottomNavView, navController)
        }
    }
}

FragmentKeys.kt

class FragmentKeys : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        setHasOptionsMenu(true)
        return inflater.inflate(R.layout.fragment_keys_layout, container, false)
    }

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

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

        //val rview_keys: RecyclerView = findViewById(R.id.rview_keys)
        rview_keys.layoutManager = LinearLayoutManager(context)
        rview_keys.adapter = AdapterKeys(KeysListObjects.keys)
    }
}

I commented out the one line above because I was getting an "unresolved reference" error on "findViewById". This line didn't seem to be necessary as it was not in other people's code. For example: Kotlin Android Fragment recyclerView and context issue

AdapterKeys.kt

class AdapterKeys(val keys: List<KeysList>) : RecyclerView.Adapter<AdapterKeys.KeysViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): KeysViewHolder {
        val view = LayoutInflater.from(parent?.context).inflate(R.layout.list_item_keys, parent, false)
        return KeysViewHolder(view)
    }

    override fun getItemCount() : Int {
        return keys.size
    } //override fun getItemCount() = keys.size

    override fun onBindViewHolder(holder: KeysViewHolder, position: Int) {
        val keysList = keys[position]
        holder.setData(keysList, position)
    }

    inner class KeysViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun setData(keysList: KeysList?, position: Int) {
            itemView.tview_Keys.text = keysList!!.keysText
        }
    }
}

ModelKeys.kt

object KeysListObjects {
    val keys = listOf<KeysList>(
            KeysList("Testing1"),
            KeysList("Testing2"),
            KeysList("Testing3")
    )
}
2
Why are you trying to do that in onActivityCreated and not in onViewCreated??EpicPandaForce
@EpicPandaForce I did that based on a previous SO question (linked in my original post). You are correct: in onViewCreated is where it should sit - see my post below. Thank you!Dennis 815

2 Answers

1
votes

you are getting the error because you commented this

//val rview_keys: RecyclerView = findViewById(R.id.rview_keys)

there is no declaration of rview_keys as a variable. So it is considering rview_keys as a view because in your activity you have a view with id rview_keys.

Following lines from error just confirm it.

java.lang.IllegalStateException: rview_keys must not be null at com.projects.arise.mytestapp.MainActivity.onCreate(MainActivity.kt:55) at

Check code at line number 55 of MainActivity.

The reason these people don't have that line is that they are using it as a view. And you can't use it as a view in onActivityCreated().

1
votes

I had to do two things to get this to work:

  1. Move the two rview_keys lines of code from onActivityCreated to onViewCreated (which I believe is earlier in the fragment lifecycle). Thanks to above posters for their feedback here! So now my fragment class looks like this:

FragmentKeys.kt

class FragmentKeys : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        setHasOptionsMenu(true)
        return inflater.inflate(R.layout.fragment_keys_layout, container, false)
    }

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

        rview_keys.layoutManager = LinearLayoutManager(context)
        rview_keys.adapter = AdapterKeys(KeysListObjects.keys)
    }
}
  1. I was still getting build errors so I tried changing one of the Kotlin dependencies in my build.gradle file (jdk7) back to what it was before even (jre7) though I was getting a deprecation warning.

The new dependency I was being asked to use - which wasn't working:

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

The old dependency I switched back to - which is working (for now):

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"