繁体   English   中英

Kotlin:java.lang.NullPointerException:指定为非空的参数在 Java 2 Kotlin 迁移后为空

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

将 CustomSubjectSpinnerAdapter 从 Java 迁移到 Kotlin 后,我遇到了下一个异常:

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)

迁移前的适配器类(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);
            }
        }
    }
}

迁移后的适配器类 (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)
    }
}

首先是getItem中的编译问题

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

它提醒我“Null 不能是非 null 类型 Any 的值”

所以我试过了

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

为了 - 至少 - 让它编译,但在类实例化之后:

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
}

提到的异常被抛出。 有什么帮助吗?

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

只需添加“?” 函数返回类型的可空类型,因为 kotlin 使用可空值与 java 不同,而基适配器在后台使用 java:Java 中的对象等同于 Any? 不给任何

Adapter 的工作方式是convertView可能为空。 这就是为什么在您的方法中检查它是否为空,如果它为空则创建一个新视图。

在 Kotlin 中,您必须将此参数声明为可为空,因为它可能为空。 您还可以利用 Elvis 运算符获得更简洁的代码:

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
}

同样,如果您希望能够从getItem()返回 null,则必须将返回类型标记为可为 null:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM