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.
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.
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)
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!
Ä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 }**
}
}
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 ;)