Kotlin,Android Studio:我无法让我的程序使用第二个适配器。列表视图

Posted

技术标签:

【中文标题】Kotlin,Android Studio:我无法让我的程序使用第二个适配器。列表视图【英文标题】:Kotlin, Android Studio: I can't get my program to use a second adapter. List Views 【发布时间】:2020-07-28 22:06:40 【问题描述】:

我对在 Kotlin 上使用 android Studio 进行编程相对较新,我目前正在开发我的列表视图的一些问题。

我目前关注this tutorial,并进行了一些更改以使其适用于我的程序,尽管它专注于从 JSON 文件获取数据并且我从 Firestore 获取数据。

我从 Firestore 数据库中读取了我的数据。首先,我阅读它以列出我所在地区的餐馆(文件),我对此没有任何问题。但是,一旦我尝试根据这些餐馆(文件)的数据(例如菜单上的产品类别(饮料、沙拉、汉堡等))创建另一个列表,我就无法在屏幕上显示任何内容,即使我在这个新类上使用完全相同的方法和适配器。

这是我在第一堂课中使用的代码,我可以在其中正确显示列表:

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.ListView
import androidx.appcompat.app.AppCompatActivity
import com.al.tfmteleco.utiles.AdaptadorListaEstablecimientos
import com.google.firebase.firestore.FirebaseFirestore


val db = FirebaseFirestore.getInstance()


class Explorar : AppCompatActivity() 

    lateinit var listView: ListView
    private val establecimientosList = ArrayList<ModelEstablecimientos>()
    private var establecimiento: ModelEstablecimientos? = null
    private var IDEstablecimiento: Int? = null

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

        listView = findViewById<ListView>(R.id.listaEstablecimientos)
// 1
        getEstablecimientos()

        listView.setOnItemClickListener_,_,position,_ ->
            finish()
            establecimiento = establecimientosList[position]
            IDEstablecimiento = establecimiento!!.ID

            println("La ID es: $IDEstablecimiento")
            val intent = Intent(this@Explorar, Establecimiento::class.java)
            intent.putExtra("establecimientoID", IDEstablecimiento.toString())
            startActivity(intent)

        
    

    private fun getEstablecimientos() 

        db.collection("establecimientos")
            .get()
            .addOnSuccessListener  result ->
                for (document in result) 
                    establecimientosList.add(
                        ModelEstablecimientos(
                            document.getString("Nombre"),
                            document.getString("Categoria1"),
                            document.getString("Categoria2"),
                            document.getString("Categoria3"),
                            document.getString("Precio"),
                            document.getString("Localizacion"),
                            document.getLong("MesasDisponibles")?.toInt(),
                            document.getLong("MesasOcupadas")?.toInt(),
                            document.getLong("Abierto")?.toInt(),
                            document.getLong("PuntosOpiniones")?.toFloat(),
                            document.getLong("OpinionesTotales")?.toInt(),
                            document.id.toInt()
                        )
                    )

                    Log.d("Documentos", "$document.id => $document.data")

// 2
                    val listItems = arrayOfNulls<String>(establecimientosList.size)
// 3
                    for (i in 0 until establecimientosList.size) 
                        val establecimiento = establecimientosList[i]
                        listItems[i] = establecimiento.nombre
                    
// 4
                    val adapter =
                        AdaptadorListaEstablecimientos(
                            this,
                            establecimientosList
                        )
                    listView.adapter = adapter
                
            
            .addOnFailureListener  exception ->
                Log.d("Documentos", "Error getting documents: ", exception)
            

    

这个来自适配器类,用于那个列表。

import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import com.al.tfmteleco.ModelEstablecimientos
import com.al.tfmteleco.R


class AdaptadorListaEstablecimientos(private val context: Context,
    private val dataSource: ArrayList<ModelEstablecimientos>) : BaseAdapter() 

    private val inflater: LayoutInflater
            = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

    //1
    override fun getCount(): Int 
        return dataSource.size
    

    //2
    override fun getItem(position: Int): Any 
        return dataSource[position]
    

    //3
    override fun getItemId(position: Int): Long 
        return position.toLong()
    

    //4
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View 
        // Get view for row item
        val rowView = inflater.inflate(R.layout.lista_establecimientos, parent, false)
        // Get title element
        val nombreTextView = rowView.findViewById(R.id.nombreEstablecimiento) as TextView

        // Get cat1 element
        val cat1TextView = rowView.findViewById(R.id.cat1Establecimiento) as TextView

        // Get cat1 element
        val cat2TextView = rowView.findViewById(R.id.cat2Establecimiento) as TextView

        // Get cat1 element
        val cat3TextView = rowView.findViewById(R.id.cat3Establecimiento) as TextView

        // Get rangoprecio element
        //val rangoprecioTextView = rowView.findViewById(R.id.precioEstablecimiento) as TextView

        // Get mapa element
        val mapaButton = rowView.findViewById(R.id.mapaEstablecimiento) as ImageView

        // Get mesas element
        val mesasTextView = rowView.findViewById(R.id.mesasEstablecimiento) as TextView

        // Get mensaje element
        val mensajeTextView = rowView.findViewById(R.id.mensajeEstablecimiento) as TextView

        // Get info element
        val infoButton = rowView.findViewById(R.id.infoEstablecimiento) as ImageView

        // Get points element
        val ptsTextView = rowView.findViewById(R.id.ptsOpinion) as TextView
        val ratingBarView = rowView.findViewById(R.id.ratingBar) as RatingBar

// 1
        val listaEstablecimientos = getItem(position) as ModelEstablecimientos

// 2
        nombreTextView.text = listaEstablecimientos.nombre                  // NOMBRE DEL ESTABLECIMIENTO
        cat1TextView.text = listaEstablecimientos.cat1                      // CATEGORIA 1 DEL ESTABLECIMIENTO
        cat2TextView.text = listaEstablecimientos.cat2                      // CATEGORIA 2 DEL ESTABLECIMIENTO
        cat3TextView.text = listaEstablecimientos.cat3                      // CATEGORIA 3 DEL ESTABLECIMIENTO


// LOCALIZACIÓN DEL ESTABLECIMIENTO
        if(listaEstablecimientos.loc == null)
            mapaButton.visibility = View.INVISIBLE
        
            else
            mapaButton.visibility = View.VISIBLE
        

// MESAS DISPONIBLES DEL ESTABLECIMIENTO
        mesasTextView.text = listaEstablecimientos.mesasOcupadas.toString() +
                "/" +
                listaEstablecimientos.mesasDisponibles.toString() + " mesas ocupadas"
        var mesasO : Float = listaEstablecimientos.mesasOcupadas!!.toFloat()
        var mesasD : Float = listaEstablecimientos.mesasDisponibles!!.toFloat()
        if (mesasO/mesasD <= 0.2)
            mesasTextView.setTextColor(Color.parseColor("#2D6E30"))
        
            else if (mesasO/mesasD <= 0.6)
            mesasTextView.setTextColor(Color.parseColor("#D14F00"))
        
            else if (mesasO/mesasD >= 0.85)
            mesasTextView.setTextColor(Color.parseColor("#8A0000"))
        

// ESTADO DEL ESTABLECIMIENTO
        if(listaEstablecimientos.mensaje == 0)
            mensajeTextView.text = "Cerrado"
            mensajeTextView.setTextColor(Color.parseColor("#8A0000"))
        
            else if(listaEstablecimientos.mensaje == 1)
            mensajeTextView.text = "Abierto"
            mensajeTextView.setTextColor(Color.parseColor("#2D6E30"))
        

// PUNTUACIÓN DEL LOCAL POR PARTE DE LOS USUARios
        var puntos : Float = listaEstablecimientos.puntos!!.toFloat()
        var opiniones : Float = listaEstablecimientos.opiniones!!.toFloat()

        // Formato para mostrar el número con un solo decimal
        var pts= "%.$1f".format(puntos/opiniones).toFloat()

        ptsTextView.text = pts.toString()
        ratingBarView.rating = pts


// Si la posición del establecimiento en la lista es par, el fondo es algo más oscuro
        if(position % 2 == 0)
            rowView.setBackgroundColor(Color.parseColor("#E8E8E8"))
        

        return rowView
    

“好吧,如果它有效,请尝试适应它”​​ - 我想。我试过了,它应该更简单,因为我只需要使用标准列表模式,列表中只有一个项目(类别名称)。由于某种原因,它不起作用。它可以很好地读取数据,但似乎无法适应另一个列表。

这是我正在使用的代码,我在其中遇到了问题:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.ListView

class Categorias : AppCompatActivity() 

    private lateinit var listViewCategorias: ListView
    private val categoriasList = ArrayList<ModelCategorias>()

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_categorias)
        listViewCategorias = findViewById(R.id.listaCategorias)

        val establecimientoID=intent.getStringExtra("establecimientoID")
        println(establecimientoID)
        getCategorias(establecimientoID.toInt())

        setContentView(R.layout.activity_categorias)
    

    private fun getCategorias(ID:Int) 

        db.collection("establecimientos").document(ID.toString()).collection("categorias")
            .get()
            .addOnSuccessListener  result ->
                for (document in result) 
                    categoriasList.add(
                        ModelCategorias(
                            document.getString("Nombre_Categoria"),
                            document.id.toInt()
                        )
                    )

                    Log.d("Categorias", "$document.id => $document.data")

// 2
                    val listItems = arrayOfNulls<String>(categoriasList.size)
// 3
                    for (i in 0 until categoriasList.size) 
                        val categoria = categoriasList[i]
                        listItems[i] = categoria.nombreCategoria.toString()
                        println(listItems[i].toString())
                    

                    val adapter = ArrayAdapter(this,android.R.layout.simple_list_item_1, listItems)

                    listViewCategorias.adapter = adapter
                
            
            .addOnFailureListener  exception ->
                Log.d("Documentos", "Error getting documents: ", exception)
            
    

对于这么长的第一篇文章,我感到非常抱歉,但我相当绝望。也请原谅我生疏的英语。

提前谢谢你。

【问题讨论】:

“它无法适应另一个列表”是什么意思?编译错误,堆栈跟踪崩溃,还有什么? 它与 ArrayList 一起正常运行,因为 println() 工作正常,但它不会崩溃,显示任何错误或任何类型的警告,它只是没有按应有的方式显示列表一旦我尝试了该应用程序。 所以列表是完全空白的?我在上面的代码中没有看到任何错误,除了您在循环中创建适配器,因此您创建了多个无用的适配器,并且实际上只使用了最后一个。但这不会阻止它显示您的数据。 是的,名为 categoriasList 的 ArrayList 已正确填充,但必须在屏幕上显示该数据的 ListView 对象不像第一段代码那样工作。感谢您对循环问题的输入,我会看看并尝试使其更有效:) 【参考方案1】:

正在运行的活动:

val 适配器 = AdaptadorListaEstablecimientos(this, establecimientosList)


不工作的活动:

val 适配器 = ArrayAdapter(this,android.R.layout.simple_list_item_1, listItems)

如果 ArrayAdapter 和 AdaptadorListaEstablecimientos 基本上是相同的适配器,则不需要额外的属性(在本例中为 android.R.layout.simple_list_item_1)。您应该进一步了解适配器之间的差异。

【讨论】:

这是自定义Adapter和提供的ArrayAdapter的区别。没有理由期望它们具有相同的构造函数参数。自定义适配器是为特定的列表项布局设计的,因此不需要将其传递给其构造函数。 当然可以,但是如果他们想知道为什么一个有效而另一个无效,那我会去看看。他们传递给默认 ArrayAdapter 的模型完全有可能不适用于他们正在使用的 ArrayAdapter(Context context, int resource, T[] objects) 构造函数。 看起来他们正确使用了 ArrayAdapter,但我可能错过了一个细节。 ArrayAdapter 适用于任何类型的对象数组,因为它只是在每个项目上调用toString()。他们没有说到底出了什么问题。它不会影响最终结果,但他们应该将适配器设置移到 for 循环之外,以避免创建一堆过时的适配器。不过,这也是他们原始代码中的一个问题。 是的,我只是在拍摄任何看起来不寻常的东西。 我之前用的是同一个适配器,但也没有用。所以我换了一个更简单的,以便查看我的那个类的“新”适配器是否是问题,但不是。它不会在我的活动中显示数组。

以上是关于Kotlin,Android Studio:我无法让我的程序使用第二个适配器。列表视图的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin,Android Studio:我无法让我的程序使用第二个适配器。列表视图

Kotlin,Android Studio:我无法让我的程序使用第二个适配器。列表视图

在 Kotlin/Android Studio 中无法将 mp3 转换为 pcm - UnsupportedAudioFileException

如何使用 kotlin 在 android studio 中引用 timerPicker

如何在 Kotlin 中创建一个打开新活动(Android Studio)的按钮?

Android Studio无法运行项目