NullPointerException when trying to access views in a Kotlin fragment
Kotlin synthetic properties are not magic and work in a very simple way. When you access btn_K
, it calls for getView().findViewById(R.id.btn_K)
.
The problem is that you are accessing it too soon. getView()
returns null
in onCreateView
. Try doing it in the onViewCreated
method:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
btn_K.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world"); }
}
How to detect cause of Null Pointer Exception on Android Extensions inside fragments
Android extensions plugin is deprecated and the official proposal is to use ViewBinding
instead which provided compile time access to the views of an xml layout without the need to do viewFindById
on each view you have.
This page here will provide you with the steps to set up your code to use view binding, make sure to check the code snippet on a fragment to clear the reference you have on the views
kotlin fragment error NullPointerException
Done. this my complete fix code with separate onCreateView and onViewCreate. thanks all
class FragBaru : Fragment() {
private lateinit var rv: RecyclerView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.mainex, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
rv = view.findViewById(R.id.recycler_view)
val groupAdapter = GroupAdapter<ViewHolder>().apply {
spanCount = 2
}
rv.apply {
layoutManager = GridLayoutManager(rootView.context, groupAdapter.spanCount).apply {
spanSizeLookup = groupAdapter.spanSizeLookup
}
adapter = groupAdapter
}
var headerTab: ArrayList<mTop>
headerTab = arguments?.getSerializable("headertab") as ArrayList<mTop>
for (h in 0 until headerTab.size) {
val header = headerTab.get(h).kategori
ExpandableGroup(ExpandableHeaderItem(header), true).apply {
for (c in 0 until headerTab[h].sub.size) {
val gambar = (headerTab[h].sub).get(c).gambar
val nama_menu = (headerTab[h].sub).get(c).nama_menu
add(Section(FancyItem(gambar, nama_menu)))
}
groupAdapter.add(this)
}
}
}
companion object {
fun newInstance(headertab: ArrayList<mTop>): FragBaru {
val f = FragBaru()
val args = Bundle()
args.putSerializable("headertab", headertab)
f.setArguments(args)
return f
}
}
}
Kotlin Fragment NullPointerException
You are doing asynchronous I/O directly in a fragment. Then you are trying to update the UI of the fragment when that work completes.
The problem is that sometimes your fragment will be destroyed before that work completes (e.g., the user pressed the BACK button). In that case, context
will be null
and context!!
will be... bad.
The tactical fix is to only update the UI if you have a context:
activity?.let {
userAdapter = UsersAdapter(it, mUsers as ArrayList<Users>, false)
recyclerView.adapter = userAdapter
}
The better fix, by a fair margin, is to get this I/O out of the fragment entirely. If the user triggers a configuration change (rotates the screen, toggles dark mode, etc.), your new fragment will not be getting the I/O results from the original fragment. It would be better to move this I/O into a ViewModel
that your fragment uses, where you make those results available via a LiveData
or similar mechanism. Your fragment would observe the LiveData
and apply the results. This not only fixes the crash, but it also handles configuration changes better.
Android View Binding in Thread error NullPointerException
You may find this easier if you ditch the !!
getter and just use nullable types with local non-null variables as-needed. If you have a lot of places to use the binding inside the loop you could grab a non-null value of it at the start of the loop.
private fun updateHomeUI() {
Thread {
// this could also be while(true) since the calls just
// inside will break out when it goes null
while (_binding != null) { // Stop the loop after onDestroyView sets this to null
val binding = _binding ?: break
val a = activity as? MainActivity ?: break
// Lots of UI update like this:
a.runOnUiThread { binding.tvName.text = str }
...
Thread.sleep(1000)
}
}.start()
}
I'm not sure how your existing bind.tvName != null
loop condition would ever return false without first failing the !!
check. The views in the binding class are non-null by default (unless they don't exist in all layout permutations), so that would either be true, or would fail in the bind
getter when _binding
is null.
Kotlin Null Pointer Exception when trying to open Activity
Activity
or Fragment
may be destroyed before request is finished executing. You can check if activity
is not null:
val a = activity
if (a != null) {
recyclerAdapter = HomeRecyclerAdapter(a, displayList)
recyclerHome.adapter = recyclerAdapter
recyclerHome.layoutManager = layoutManager
}
Related Topics
Android - Cannot Capture Backspace/Delete Press in Soft. Keyboard
Out of Memory Error Imageview Issue
Popupwindow - Dismiss When Clicked Outside
Android - Save/Restore Fragment State
Activenetworkinfo.Type Is Deprecated in API Level 28
How to Store Images Using Sharedpreference in Android
Proguard Hell - Can't Find Referenced Class
Compile with Proguard Gives Simexception: "Local Variable Type Mismatch"
Get Free Space on Internal Memory
How to Set Font Custom Font to Spinner Text Programmatically
How to Display Icons in a Popupmenu
Android - Controlling a Task with Timer and Timertask
Detecting Sms Incoming and Outgoing
Date Formatting Based on User Locale on Android
Android - Timepicker Minutes to 15
How to Style the Drawerarrowtoggle from Android Appcompat V7 21 Library
How to Verify That an Android APK Is Signed with a Release Certificate