Kotlin: java.lang.NullPointerException: Parameter specified as non-null is null after Java 2 Kotlin migration

Issue

After migrating CustomSubjectSpinnerAdapter from Java to Kotlin I’m getting the next exception:

java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter view
        at com.xxx.xxx.activities.about.contact.CustomSubjectSpinnerAdapter.getView(Unknown Source:2)
        at android.widget.AbsSpinner.onMeasure(AbsSpinner.java:206)
        at android.widget.Spinner.onMeasure(Spinner.java:614)
        at androidx.appcompat.widget.AppCompatSpinner.onMeasure(AppCompatSpinner.java:438)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:25466)
        at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1412)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.widget.ScrollView.onMeasure(ScrollView.java:452)
        at android.view.View.measure(View.java:25466)
        at androidx.drawerlayout.widget.DrawerLayout.onMeasure(DrawerLayout.java:1119)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:25466)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:995)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:25466)
        at androidx.drawerlayout.widget.DrawerLayout.onMeasure(DrawerLayout.java:1119)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at com.android.internal.policy.DecorView.onMeasure(DecorView.java:747)
        at android.view.View.measure(View.java:25466)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3397)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2228)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2486)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
        at android.view.Choreographer.doFrame(Choreographer.java:731)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Adapter class before migration (Java)

class CustomSubjectSpinnerAdapter extends BaseAdapter {

    final private String[] subjectOptions;
    private final LayoutInflater inflter;

    CustomSubjectSpinnerAdapter(Context applicationContext, String[] subjectOptions) {
        this.subjectOptions = subjectOptions;
        inflter = (LayoutInflater.from(applicationContext));
    }

    @Override
    public int getCount() {
        return subjectOptions.length;
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {

        if (convertView == null)
        {
            LayoutInflater vi = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = vi.inflate(R.layout.subject_spinner_row, null);
        }
        View llLayout = super.getDropDownView(position, convertView, parent);

        roundCorners(parent);

        return llLayout;
    }

    private void roundCorners(ViewGroup parent) {

        View container2Round = ((View)parent.getParent());
        if (container2Round!=null) {
            GradientDrawable gd = new GradientDrawable(
                    GradientDrawable.Orientation.TOP_BOTTOM,
                    new int[] {Color.WHITE, Color.WHITE});
            int radius = AWScreen.dp2px(10);
            gd.setCornerRadius(radius);
            container2Round.setBackground(gd);
        }
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {

        view = inflter.inflate(R.layout.subject_spinner_row, null);
        TextView tvSubject = view.findViewById(R.id.subject);
        tvSubject.setText(subjectOptions[i]);
        if (subjectOptions[i].equals("")) tvSubject.setVisibility(View.GONE);

        setListItemRoundedCorners(tvSubject, i);

        if (i== subjectOptions.length - 1) {
            int padding = AWScreen.sp2px(10, view.getContext());
            tvSubject.setPadding(padding, padding, padding, padding);
        }

        return view;
    }

    private void setListItemRoundedCorners(TextView tvSubject, int i) {

        if (i==1){
            tvSubject.setBackgroundResource(R.drawable.rounded_border_top);
        }else{
            if (i==2){
                tvSubject.setBackgroundResource(R.drawable.rounded_border_bottom);
            }
        }
    }
}

Adapter class after migration (Kotlin)

internal class CustomSubjectSpinnerAdapter(
    applicationContext: Context?,
    private val subjectOptions: Array<String>
) : BaseAdapter() {
    private val inflter: LayoutInflater
    override fun getCount(): Int {
        return subjectOptions.size
    }

    override fun getItem(i: Int): Any {
        TODO("Not yet implemented")
    }

    override fun getItemId(i: Int): Long {
        return 0
    }

    override fun getDropDownView(_position: Int, _convertView: View, _parent: ViewGroup): View {
        var convertView: View? = _convertView
        if (convertView == null) {
            val vi =
                _parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            convertView = vi.inflate(R.layout.subject_spinner_row, null)
        }
        val llLayout = super.getDropDownView(_position, convertView, _parent)
        roundCorners(_parent)
        return llLayout
    }

    private fun roundCorners(parent: ViewGroup) {
        val container2Round = parent.parent as View
        val gd = GradientDrawable(
            GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(Color.WHITE, Color.WHITE)
        )
        val radius = AWScreen.dp2px(10)
        gd.cornerRadius = radius.toFloat()
        container2Round.background = gd
    }

    override fun getView(i: Int, view: View, viewGroup: ViewGroup): View {
        var view = view
        view = inflter.inflate(R.layout.subject_spinner_row, null)
        val tvSubject = view.findViewById<TextView>(R.id.subject)
        tvSubject.text = subjectOptions[i]
        if (subjectOptions[i] == "") tvSubject.visibility = View.GONE
        setListItemRoundedCorners(tvSubject, i)
        if (i == subjectOptions.size - 1) {
            val padding = AWScreen.sp2px(10f, view.context)
            tvSubject.setPadding(padding, padding, padding, padding)
        }
        return view
    }

    private fun setListItemRoundedCorners(tvSubject: TextView, i: Int) {
        if (i == 1) {
            tvSubject.setBackgroundResource(R.drawable.rounded_border_top)
        } else {
            if (i == 2) {
                tvSubject.setBackgroundResource(R.drawable.rounded_border_bottom)
            }
        }
    }

    init {
        inflter = LayoutInflater.from(applicationContext)
    }
}

The first is a compilation problem in getItem

override fun getItem(i: Int): Any {
    return null
}

It’s alerting me that "Null can not be a value of a non-null type Any"

so I’ve tried

override fun getItem(i: Int): Any {
    TODO("Not yet implemented")
}

To -at least- make it compile, but after class in instantiated in:

private fun createSubjectSpinner() {
    val contactUs = ContactUs()
    val strSubject = AWLocale.getStringResourceByName("activityreportproblem_textview_subject")
    val subjectOptions = arrayOf(
        contactUs.leaveCommentLiteral,
        contactUs.reportProblemLiteral,
        contactUs.requestFeatureLiteral
    )
    val fullSpinnerArray =
        arrayOf(strSubject, subjectOptions[0], subjectOptions[1], subjectOptions[2])
    binding!!.spSubject.setOnTouchListener { v: View?, event: MotionEvent ->
        if (event.action == MotionEvent.ACTION_UP) {
            spinnerOnTouch(subjectOptions, binding!!.spSubject)
        }
        false
    }
    val customAdapter = CustomSubjectSpinnerAdapter(this, fullSpinnerArray)
    binding!!.spSubject.adapter = customAdapter
}

The mentioned exception is thrown. Any help?

Solution

The way Adapter works is that the convertView might be null. That’s why in your method you check if it’s null and create a new view if it is null.

In Kotlin, you must declare this parameter as nullable, since it might be null. Also you can take advantage of the Elvis operator for more concise code:

override fun getDropDownView(position: Int, _convertView: View?, parent: ViewGroup): View {
    val convertView = _convertView ?:
        LayoutInflator.from(parent.context)
            .inflate(R.layout.subject_spinner_row, parent, false)
    val llLayout = super.getDropDownView(position, convertView, parent)
    roundCorners(parent)
    return llLayout
}

Likewise, if you want to be able to return null from getItem(), you must mark the return type as nullable:

override fun getItem(i: Int): Any? {
    return null
}

Answered By – Tenfour04

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published