20

I tried to this code which is mention below, but getting crash during run time. The error occurred is Android Run time:

FATAL EXCEPTION: main Process: com.root.specialbridge, PID: 17706 kotlin.KotlinNullPointerException at com.root.specialbridge.fragments.profile_fragment.WallFragments.initializeView(WallFragments.kt:49)

class WallFragments : Fragment(){

private var wallAdapter: WallAdapter? = null
private var wall_recycler: RecyclerView? = null
private val wallArrayList: ArrayList<Wall>? = null
private var mainlayout: LinearLayout? = null
private var no_result_found_layout: RelativeLayout? = null
private var userProfileWallInterface: UserProfileWallInterface? = null
internal var wallActivityBeanse: MutableList<WallActivityBeans> = ArrayList()

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater!!.inflate(R.layout.wall_fragments, container, false)
    userProfileWallInterface = UserProfileWallPresentation(activity, this)
    initializeView()
    wallAdapter = WallAdapter(activity, wallActivityBeanse)
    wall_recycler!!.adapter = wallAdapter

    return view
}
fun initializeView() {
    wall_recycler = view!!.findViewById(R.id.wall_recycler_id) as RecyclerView
    mainlayout = view!!.findViewById(R.id.mainlayout) as LinearLayout
    no_result_found_layout = view!!.findViewById(R.id.no_result_found_layout) as RelativeLayout
    wall_recycler!!.layoutManager = LinearLayoutManager(activity)
    wall_recycler!!.setHasFixedSize(true)
    if (AuthPreference(activity).isGetMemberProfile) {
        userProfileWallInterface!!.getMemberProfileWall(view!!)

    } else {
        userProfileWallInterface!!.getUserProfileWall(AuthPreference(activity).token, AuthPreference(activity).user.id, view!!)

    }
}   
companion object {
    val instance: WallFragments
        get() = WallFragments()  }}
Vishal Vaishnav
  • 3,346
  • 3
  • 26
  • 57
Ramesh
  • 1,772
  • 4
  • 12
  • 15
  • 1
    You should either call `initializeView()` in `onViewCreated()` or using the `view` that you inflated instead of `view!!`. Calling `getView()` will return null before `onCreateView` returns. Take a look at this [question](https://stackoverflow.com/questions/9488595/getview-returning-null-when-fragment-has-been-created-from-an-activity). – BakaWaii Sep 26 '17 at 06:38
  • @BakaWaii Can you give any example, It will more helpful Thanks – Ramesh Sep 26 '17 at 07:08
  • @Anchal Singh I tried with global variable but got the smart cast issues. Plz help me with example Thanks – Ramesh Sep 26 '17 at 07:11
  • @Vishal Vaishnav Do you have any answer – Ramesh Sep 26 '17 at 08:42

3 Answers3

35

Add

apply plugin: 'kotlin-android-extensions'

in the app level gradle file and

import

import kotlinx.android.synthetic.main.fragment_your_fragment_name.view.*

in the onCreateView of your fragment (e.g. if the id of your textview is textView)

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    val view = inflater!!.inflate(R.layout.fragment_splashfragment, container, false)
    view.textView.text = "hello"   //add your view before id else getting nullpointer exception
    return view
}

UPDATE:

declare viewOfLayout in your class instead of view.

class yourfragment:Fragment(){

    private lateinit var viewOfLayout: View
    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        viewOfLayout = inflater!!.inflate(R.layout.fragment_splashfragment, container, false)
        viewOfLayout.textView.text = "hello"   //add your view before id else will get nullpointer exception
        return viewOfLayout
    }

}
Keale
  • 3,924
  • 3
  • 29
  • 46
Kiran Benny Joseph
  • 6,755
  • 4
  • 38
  • 57
14

Introducing Kotlin Android Extensions.

You do not have to use findViewById anymore. Using this plugin you can use the UI component directly as a global field. Supported in Activities, fragments and views.

Example, To refer text view from the layout below,

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/hello"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, MyActivity"/>

</android.support.constraint.ConstraintLayout>

in activity you can simply write,

// Using R.layout.activity_main from the main source set
import kotlinx.android.synthetic.main.activity_main.*

class MyActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Instead of findViewById(R.id.hello) as TextView
        hello?.setText("Hello, world!")
    }
}

in fragments,

// Using R.layout.fragment_content from the main source set
import kotlinx.android.synthetic.main.fragment_content.*

class ContentFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
        inflater.inflate(R.layout.fragment_content, container, false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // Instead of view.findViewById(R.id.hello) as TextView
        hello?.setText("Hello, world!")
    }
}

and for views,

// Using R.layout.item_view_layout from the main source set
import kotlinx.android.synthetic.main.item_view_layout.*

class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    fun bindData(data: String) {
        // Instead of itemView.findViewById(R.id.hello) as TextView
        itemView.hello?.setText(data)
    }

}

And, you should not use !! everywhere, unless you want NullPointerException explicitly.

Instead use anyone from the following:

  1. Do null check with safe call - ?., Eg. nullableVariable?.method()
  2. Use non-null object using ?.let{ }, Eg. nullableVariable?.let { it.method() }
  3. Supplying a backup value for the nullable variable using elvis operator - ?:, Eg. nullableVariable ?: <backupValue>.

Read more about Null Safety in Kotlin.

krishh
  • 1,551
  • 15
  • 28
  • 1
    this is a nice and handy answer but completely irrelevant to what was asked in the question. The information on how to use kotlin android extensions in activity is widely spread and easy to find. It's not the case with fragments – Vendetta8247 Feb 08 '19 at 23:51
  • 1
    @Vendetta8247 it is the same case with Fragments. You can access views directly by using ids just as in Activities. Read my answer properly. – krishh Feb 14 '19 at 17:44
  • isn't this the grand designed extensions that was purported and all-hailed to replace the elegant and simple, and understandable and flexible `findViewById()` ? – daparic May 21 '20 at 19:43
11

Initialization of view in fragment :

wall_recycler=view.findViewById<RecyclerView>(R.id.wall_recycler_id)
mainlayout = view.findViewById<LinearLayout>(R.id.mainlayout)

The problem is that you are accessing it too soon. requireView() and view returns null in onCreateView.I have find all views in onViewCreated(). Try doing it in the onViewCreated method:

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

 wall_recycler=requireView().findViewById<RecyclerView>(R.id.wall_recycler_id)
 mainlayout = requireView().findViewById<LinearLayout>(R.id.mainlayout)
 mainlayout.setOnClickListener { Log.d(TAG, "onViewCreated(): hello world");}
    }
Anchal Singh
  • 329
  • 3
  • 13
  • Can you share me your onCreateView code and declaration of view as a global Thanks – Ramesh Sep 26 '17 at 08:39
  • I have updated my answer, if it works select it as a right answer. – Anchal Singh Sep 26 '17 at 09:21
  • 1
    You don't need to call `getView()` within `onViewCreated()` method. You already have `view: View?` object over there. And by the way, if @Ramesh has written definition of `initializeView()` in `onCreateView()` itself, it would have worked. Or he can simply supply the `view` object as parameter in `initializeView()`, like `initializeView(view: View?)`. – krishh Sep 26 '17 at 19:06