IllegalStateException: RecyclerView is null inside of Fragment within NavigationDrawer activity
Solution 1
You have not initialized the RecyclerView in MainFragment.kt
file. You have to initialize it before the below line:
mainMenu.layoutManager = LinearLayoutManager(this.context)
You can initialize the RecyclerView by the below line:
var mainMenu = findViewById(R.id.mainMenu) as RecyclerView
You have to change it as per your need.
Solution 2
For anyone that follow the brilliant clue of @Avijit Karmakar, getting in count another discussion, (RecyclerView error: No adapter attached; skipping layout) I had to include :
class WikiFragment : Fragment() {
val paginas: ArrayList<String> = ArrayList()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
var listItems : View = inflater.inflate(R.layout.fragment_wiki, container, false)
var rv_frag_wiki = listItems.findViewById<View>(R.id.rv_frag_wiki) as RecyclerView
rv_frag_wiki.layoutManager = LinearLayoutManager(this.context)
rv_frag_wiki.adapter = PaginasAdapter(paginas, this.context)
return listItems
Solution 3
Since you are using kotlin you can have advantage of synthetics where you don't need to do var rv_frag_wiki = listItems.findViewById<View>(R.id.rv_frag_wiki) as RecyclerView
Rather import synthetics via plugin Step 1 :
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
Step 2 :
Import sythetic in MainFragment
import kotlinx.android.synthetic.main.content_menu.*
//
Step 3 :
Finally in MainFragment
Shift this code of recyclerView here
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
rvList.layoutManager = LinearLayoutManager(context,
LinearLayoutManager.VERTICAL, false)
rvList.adapter = academyAdapter
}
Solution 4
If you are using fragments: 1. Use a global variable that will hold your layout reference
internal var root: View? = null // create a global variable which will hold your layout override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
root = inflater.inflate(R.layout.your_layout_file_name, container, false) // initialize it here
return root
}
To use any view of your layout which is inside your layout you can use it with (root.) like:
root!!.recyclerView.layoutManager = LinearLayoutManager(context,LinearLayoutManager.VERTICAL, false)
Comments
-
hdx13_beatcode almost 2 years
I tried to make a RecyclerView that will go inside one of the two pages of my fragments. These pages are put inside a NavigationDrawer activity. The goal is to create something like the Play Store app homepage.
But I found an error in this snippet of code on runtime. It says:
java.lang.IllegalStateException: mainMenu must not be null at com.example.MyApp.app.fragment.MainFragment.onCreate(MainFragment.kt:49)
Ive been looking at some SO threads, and they said that the layouts are not properly loaded. Which caused some elements not linked as it should. Another said in the comments that the problem is with the context not initialized properly. Which is not the case for me (rather it's the RecyclerView).
Here are the links, hope they could be useful as a reference.
After multiple-checks on my codes, I swear I've put the right layouts in. EDIT: I imported the
kotlinx.android.synthetic.main.^
package where I put this sign: ^${layout}. Here's some of my files (forgive me if this thread becomes too long):-
MainActivity.kt : AppCompatActivity()
^activity_main.*override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // preparing the app bars setSupportActionBar(toolBar) // getting ready for the pages val pagerAdapter = MainPagerAdapter( supportFragmentManager, resources.getString(R.string.tab_main), resources.getString(R.string.tab_chat) ) pager.adapter = pagerAdapter // activating tabs tabLayout.setupWithViewPager(pager) val toggle = ActionBarDrawerToggle( this, mainDrawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) mainDrawer.addDrawerListener(toggle) navView.setNavigationItemSelectedListener(this) toggle.syncState() }
-
MainPagerAdapter.kt (fm: FragmentManager, private val page1: String, private val page2: String): FragmentPagerAdapter(fm)
override fun getItem(position: Int): Fragment? { return when (position) { 0 -> MainFragment() 1 -> ChatFragment() else -> null } } override fun getCount() = 2 override fun getPageTitle(position: Int): CharSequence? { return when (position) { 0 -> page1 1 -> page2 else -> null } }
-
MainFragment.kt : Fragment()
^content_main.*override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) : View? = inflater.inflate(R.layout.content_main, container) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // this is the error mainMenu.layoutManager = LinearLayoutManager(this.context) mainMenu.adapter = MyAdapter(itemList) { toast("${it.name} selected") } }
-
MyAdapter.kt: RecyclerView.Adapter<MyAdapter.MyHolder>()
^item_custom.view.*(courtesy of Antonio Leiva)override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = GoodsHolder(parent.inflate(R.layout.item_custom)) override fun getItemCount() = itemList.size override fun onBindViewHolder(holder: MyHolder, position: Int) = holder.bind(itemList[position], listener) class MyHolder(v: View): RecyclerView.ViewHolder(v){ private val item: Item? = null private val view = v fun bind(item: Item, listener: (Item) -> Unit) = with (itemView) { imgPic.setImageResource(item.pictureId) txtName.text = item.name txtPrice.text = item.price.toString() setOnClickListener { listener(item) } } }
-
content_main.xml
<android.support.constraint.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" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.example.MyApp.app.activity.MainActivity" > <!-- the RecyclerView that caused the runtime error --> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/mainMenu"/> </android.support.constraint.ConstraintLayout>
-
item_custom.xml (These code are inside a LinearLayout inside a CardView)
<ImageView android:id="@+id/imgPic" android:layout_width="match_parent" android:layout_height="128dp" app:srcCompat="@drawable/ic_menu_gallery" /> <TextView android:id="@+id/txtName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Get it while it's hot!" android:layout_margin="@dimen/margin_small" android:layout_marginTop="@dimen/margin_medium" android:maxLines="2" android:ellipsize="end" android:textStyle="bold" /> <TextView android:id="@+id/txtPrice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="$3.000.000" android:layout_marginLeft="@dimen/margin_small" android:layout_marginStart="@dimen/margin_small" android:layout_marginRight="@dimen/margin_small" android:layout_marginEnd="@dimen/margin_small" android:layout_marginBottom="@dimen/margin_medium"/>
ChatFragment.kt: Fragment() (only contains onCreateView inflating content_main_chat.xml)
content_main_chat.xml (only contains a TextView)
-
-
hdx13_beatcode over 6 yearsI might need to point out that I use
kotlinx.android.synthetic.main.content_main.*
to be able to access themainMenu
. Is it possible that the Kotlin Android Extension failed to initialize my views? -
hdx13_beatcode over 6 yearsOkay, so I initialized the RecyclerView under
OnCreateView()
instead, and then "initialize" (or smart cast) the RecyclerView by consideringif(inflatedView is RecyclerView)
. I just need to grab the context from thatinflatedView
. And finally it works as expected. -
Aaron Frary over 5 yearsYou should be able to use
findViewById<RecyclerView>
and skip the cast. -
sourlemonaid over 5 years@hdx13_beatcode hey, can you explain what you mean? I am having the same issue right now
-
cflorenciav over 3 yearsThis is the correct answer, also the trick is use it inside onViewCreated