Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin Android Extensions giving Layout Null Pointer

Tags:

There is a fairly simple scenario that is giving me quite a bit of trouble. I'm making a very simple Activity with an embedded fragment. This fragment is simply a Gridview that displays some images. The issue comes when referring to the Gridview using Kotlin extensions to refer directly to an XML id. What is the issue here? Does kotlinx not work on static fragments?

Error:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.android_me/com.example.android.android_me.ui.MainActivity}: java.lang.IllegalStateException: gridview_all_parts must not be null  Caused by: java.lang.IllegalStateException: gridview_all_parts must not be null                                                                                  at com.example.android.android_me.ui.MasterListFragment.onActivityCreated(MasterListFragment.kt:22) 

Fragment with offensive line of code

import kotlinx.android.synthetic.main.fragment_master_list.*      class MasterListFragment: Fragment() {          override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {             val layoutView = inflater?.inflate(R.layout.fragment_master_list, container, false)             return layoutView         }          override fun onActivityCreated(savedInstanceState: Bundle?) {             //If this is removed, code runs             gridview_all_parts.adapter = MasterListAdapter(activity, AndroidImageAssets.getAll())             super.onActivityCreated(savedInstanceState)         }     } 

Fragment Layout:

<?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android="http://schemas.android.com/apk/res/android"     android:id="@+id/gridview_all_parts"     android:layout_width="match_parent" android:layout_height="match_parent"/> 

Parent Activity Layout

<?xml version="1.0" encoding="utf-8"?> <!--have tried both class:= and android:name:=--> <fragment xmlns:android="http://schemas.android.com/apk/res/android"     class="com.example.android.android_me.ui.MasterListFragment"     android:id="@+id/fragment_masterlist"     android:layout_width="match_parent"     android:layout_height="match_parent"     /> 

Parent Activity

class MainActivity: AppCompatActivity(){      override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)     } } 
like image 390
Josh Ribeiro Avatar asked Feb 16 '18 15:02

Josh Ribeiro


People also ask

Why is Kotlin extensions deprecated?

They are not supported with Java. There are still projects that are written in Java and may not be fully migrated to Kotlin yet, and hence Kotlin Synthetics may not be a consistent way of getting the ViewIds in your project. Because of these issues, Kotlin Synthetics is now being deprecated.

Can we throw null pointer exception in Kotlin?

The library is properly annotated. If the @Nullable and @NotNull annotations are being used properly, both Java and Android ones, Kotlin will be able to work seamlessly with them and figure out when a variable is null and when not.

What does Kotlin Android extensions do?

Kotlin Android Extensions are another Kotlin plugin that is included in the regular one, and that will allow recovering views from Activities, Fragments, and Views in an amazing seamless way.


1 Answers

To use the extensions in Fragment, you need to use with your layoutView. This should work: layoutView.gridview_all_parts.adapter = MasterListAdapter(activity, AndroidImageAssets.getAll())

You can make your layoutView global in this case.

UPDATED EXPLANATION Its something to do with view inflating. Like in butterknife, we need to bind the inflated view in case of fragment/recyclerView, similarly in case of kotlin, we need that inflate view for accessing the views in the xml.

Quoting from official documentation,

Importing synthetic properties It is convenient to import all widget properties for a specific layout in one go:

import kotlinx.android.synthetic.main.<layout>.*

Thus if the layout filename is activity_main.xml, we'd import

kotlinx.android.synthetic.main.activity_main.*.

If we want to call the synthetic properties on View, we should also import

kotlinx.android.synthetic.main.activity_main.view.*.

Once we do that, we can then invoke the corresponding extensions, which are properties named after the views in the XML file.

like image 55
karandeep singh Avatar answered Oct 18 '22 10:10

karandeep singh