wake-up-neo.com

"Nicht genügend Informationen, um Parameter T abzuleiten" mit Kotlin und Android

Ich versuche, die folgende ListView in meiner Android-App mit Kotlin zu replizieren: https://github.com/bidrohi/KotlinListView .

Leider erhalte ich eine Fehlermeldung. Ich kann mich nicht selbst beheben. Hier ist mein Code:

MainActivity.kt:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val listView = findViewById(R.id.list) as ListView
    listView.adapter = ListExampleAdapter(this)
}

private class ListExampleAdapter(context: Context) : BaseAdapter() {
    internal var sList = arrayOf("Eins", "Zwei", "Drei")
    private  val mInflator: LayoutInflater

    init {
        this.mInflator = LayoutInflater.from(context)
    }

    override fun getCount(): Int {
        return sList.size
    }

    override fun getItem(position: Int): Any {
        return sList[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? {
        val view: View?
        val vh: ListRowHolder

        if(convertView == null) {
            view = this.mInflator.inflate(R.layout.list_row, parent, false)
            vh = ListRowHolder(view)
            view.tag = vh
        } else {
            view = convertView
            vh = view.tag as ListRowHolder
        }

        vh.label.text = sList[position]
        return view
    }
}

private class ListRowHolder(row: View?) {
    public val label: TextView

    init {
        this.label = row?.findViewById(R.id.label) as TextView
    }
}
}

Die Layouts sind genau wie hier: https://github.com/bidrohi/KotlinListView/tree/master/app/src/main/res/layout

Die vollständige Fehlermeldung, die ich bekomme, lautet wie folgt: Fehler: (92, 31) Typinferenz fehlgeschlagen: Nicht genügend Informationen, um Parameter T in fun zu finden es explizit.

Ich würde mich über jede Hilfe freuen, die ich bekommen kann.

72
Timo Güntner

Sie müssen API-Level 26 (oder höher) verwenden. Diese Version hat die Signatur von View.findViewById() geändert - siehe hier https://developer.Android.com/preview/api-overview.html#fvbi-signature

In Ihrem Fall, in dem das Ergebnis von findViewById nicht eindeutig ist, müssen Sie den folgenden Typ angeben:

1/Ändern

val listView = findViewById(R.id.list) as ListView to

val listView = findViewById<ListView>(R.id.list)

2/Ändern

this.label = row?.findViewById(R.id.label) as TextView to

this.label = row?.findViewById<TextView>(R.id.label) as TextView

Beachten Sie, dass in 2/die Besetzung nur erforderlich ist, weil row nullwertfähig ist. Wenn label ebenfalls nullfähig wäre oder wenn Sie row nicht nullfähig gemacht hätten, wäre dies nicht erforderlich.

201
nmw

Andoid O ändern findViewById api von

public View findViewById (int id);

zu 

public final T findViewById (int id)

wenn Sie sich also auf API 26 konzentrieren, können Sie dies ändern

val listView = findViewById (R.id.list) als ListView

zu

val listView = findViewById (R.id.list)

oder 

val listView: ListView = findViewById (R.id.list)

6
Trinea

Es funktioniert  

API Level 25 oder darunter verwenden diese  

    var et_user_name = findViewById(R.id.et_user_name) as EditText

API Level 26 oder höher verwenden diese  

    val et_user_name: EditText = findViewById(R.id.et_user_name)

Viel Spaß beim Codieren!

3
Keshav Gera

Ändern Sie dazu Ihren Code. Wo die Hauptänderungen stattgefunden haben, sind mit Sternchen markiert.

package com.phenakit.tg.phenakit

import Android.content.Context
import Android.os.Bundle
import Android.support.design.widget.BottomNavigationView
import Android.support.v7.app.AppCompatActivity
import Android.view.LayoutInflater
import Android.view.View
import Android.view.ViewGroup
import Android.widget.BaseAdapter
import Android.widget.ListView
import Android.widget.TextView

public class MainActivity : AppCompatActivity() {

    private var mTextMessage: TextView? = null

    private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
        when (item.itemId) {
            R.id.navigation_home -> {
                mTextMessage!!.setText(R.string.title_home)
                [email protected] true
            }
            R.id.navigation_dashboard -> {
                mTextMessage!!.setText(R.string.title_dashboard)
                [email protected] true
            }
            R.id.navigation_notifications -> {
                setContentView(R.layout.activity_list_view)
                [email protected] true
            }
        }
        false
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mTextMessage = findViewById(R.id.message) as TextView?
        val navigation = findViewById(R.id.navigation) as BottomNavigationView
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)


        **val listView = findViewById<ListView>(R.id.list)**



        **listView?.adapter = ListExampleAdapter(this)**
    }

    private class ListExampleAdapter(context: Context) : BaseAdapter() {
        internal var sList = arrayOf("Eins", "Zwei", "Drei")
        private  val mInflator: LayoutInflater

        init {
            this.mInflator = LayoutInflater.from(context)
        }

        override fun getCount(): Int {
            return sList.size
        }

        override fun getItem(position: Int): Any {
            return sList[position]
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? {
            val view: View?
            val vh: ListRowHolder

            if(convertView == null) {
                view = this.mInflator.inflate(R.layout.list_row, parent, false)
                vh = ListRowHolder(view)
                view.tag = vh
            } else {
                view = convertView
                vh = view.tag as ListRowHolder
            }

            vh.label.text = sList[position]
            return view
        }
    }

    private class ListRowHolder(row: View?) {
        public var label: TextView

        **init { this.label = row?.findViewById<TextView?>(R.id.label) as TextView }**
    }
}
2
Alf Moh

Ich würde vorschlagen, dass Sie die synthetics kotlin Android-Erweiterung verwenden:

https://kotlinlang.org/docs/tutorials/Android-plugin.html

https://antonioleiva.com/kotlin-Android-extensions/

In Ihrem Fall lautet der Code etwa so:

init {
   this.label = row.label
}

So einfach ist das ;)

0
pauminku