“Not enough information to infer parameter T” with Kotlin and Android

后端 未结 5 1924
遥遥无期
遥遥无期 2020-12-13 05:17

I\'m trying to replicate the following ListView in my Android app using Kotlin: https://github.com/bidrohi/KotlinListView.

Unfortunately I\'m getting an error I\'m u

相关标签:
5条回答
  • 2020-12-13 05:44

    You must be using API level 26 (or above). This version has changed the signature of View.findViewById() - see here https://developer.android.com/about/versions/oreo/android-8.0-changes#fvbi-signature

    So in your case, where the result of findViewById is ambiguous, you need to supply the type:

    1/ Change

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

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

    2/ Change

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

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

    Note that in 2/ the cast is only required because row is nullable. If label was nullable too, or if you made row not nullable, it wouldn't be required.

    0 讨论(0)
  • 2020-12-13 05:44

    Andoid O change findViewById api from

    public View findViewById(int id);

    to

    public final T findViewById(int id)

    so, if you are target to API 26, you can change

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

    to

    val listView = findViewById(R.id.list)

    or

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

    0 讨论(0)
  • 2020-12-13 05:51

    Change your code to this. Where the main changes occurred are marked with asterisks.

    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)
                    return@OnNavigationItemSelectedListener true
                }
                R.id.navigation_dashboard -> {
                    mTextMessage!!.setText(R.string.title_dashboard)
                    return@OnNavigationItemSelectedListener true
                }
                R.id.navigation_notifications -> {
                    setContentView(R.layout.activity_list_view)
                    return@OnNavigationItemSelectedListener 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 }**
        }
    }
    
    0 讨论(0)
  • 2020-12-13 05:58

    I would suggest you to use synthetics kotlin Android extension:

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

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

    In your case the code will be something like this:

    init {
       this.label = row.label
    }
    

    As simple as that ;)

    0 讨论(0)
  • 2020-12-13 06:01

    Its Working

    API Level 25 or below use this

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

    API Level 26 or Above use this

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

    Happy Coding !

    0 讨论(0)
提交回复
热议问题