144 votes

"Pas assez d'informations pour déduire le paramètre T" avec Kotlin et Android

Je suis en essayant de reproduire le suivant ListView dans mon application Android à l'aide de Kotlin: https://github.com/bidrohi/KotlinListView.

Malheureusement, je reçois une erreur, je suis incapable de résoudre moi-même. Voici mon 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
    }
}
}

Les modèles sont exactement comme ici: https://github.com/bidrohi/KotlinListView/tree/master/app/src/main/res/layout

Le plein de message d'erreur que j'obtiens est ceci: Erreur:(92, 31) l'inférence de Type a échoué: Pas assez d'information pour en déduire le paramètre T dans le plaisir findViewById(p0: Int): T! Merci de le préciser explicitement.

J'apprécierais toute aide que je peux obtenir.

263voto

nmw Points 1836

Vous devez être à l'aide de l'API de niveau 26 (ou ci-dessus). Cette version a changé la signature d' View.findViewById() - voir ici https://developer.android.com/preview/api-overview.html#fvbi-signature

Donc dans votre cas, où le résultat d' findViewById est ambigu, vous devez fournir le type:

1/ Changement

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

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

2/ Changement

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

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

Notez que dans le 2, la distribution des rôles n'est nécessaire car l' row est nullable. Si label a nullable trop, ou si vous avez fait row accepte pas la valeur null, il ne serait pas nécessaire.

9voto

Trinea Points 86

Andoid O changement findViewById api de

à la Vue du public findViewById(int id);

pour

public final T findViewById(int id)

donc, si vous êtes la cible d'API 26, vous pouvez modifier

val listView = findViewById(R. id.liste) que ListView

pour

val listView = findViewById(R. id.liste)

ou

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

7voto

Keshav Gera Points 1892

Ça marche

API de niveau 25 ou inférieur utilise cette

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

API de niveau 26 ou supérieur utiliser cette

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

Bon codage!

4voto

Alf Moh Points 3265

Changez votre code pour cela. Les principaux changements survenus sont signalés par des astérisques.

 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 }**
    }
}
 

1voto

pauminku Points 406

Je vous suggère d'utiliser synthetics kotlin Android extension:

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

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

Dans votre cas, le code ressemblera à ceci:

init {
   this.label = row.label
}

Aussi simple que ça ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X