从适配器更新Activity中的值(Kotlin)

siotufzp  于 2022-12-30  发布在  Kotlin
关注(0)|答案(1)|浏览(185)

对于Kotlin和一般的OOP来说,我在我的MainActivity中有一个链接到变量的TextView

var int = 0
findViewById<TextView>(R.id.textView).setText("$var")

问题是我想修改这个变量里面和适配器.

class Adapter(
    var myContext: Context,
    var resource: Int,
    var values: ArrayList<List>
) : ArrayAdapter<List>(myContext, resource, values) {

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val element = values[position]
        val view = LayoutInflater.from(myContext).inflate(resource, parent, false)
        
        findViewByID<Button>(R.id.button).setOnClickListener{
             int ++
             View(myContext).findViewByID<TextView>(R.id.textView).setText("$var")
             //here I get an error
        }
    }
}

我不知道这是否足够清楚,我看到我可以使用接口类,但问题是我不想传递数据,而是更新已经存在的数据。

agxfikkp

agxfikkp1#

您正在使用ArrayAdapter。如果您要使用适配器,您应该使用RecyvlerView.Adapter。既然您正在学习,这是一个完美的点,刮去它,学习编写代替,与此无关。
接口解决方案是正确的解决方案:

interface MyAdapterCallback {
    fun onButtonClicked(clickCount: Int)
}

然后在您的活动中实现它

class MyActivity : ..., MyAdapterCallback {

    override fun onButtonClicked(clickCount: Int) {
        findViewById<TextView>(R.id.textView).setText("$clickCount")
    }

}

你必须把它传递给你的适配器,这对于数组适配器或回收器应该是一样的,因为是在构造函数中传递它,然后使用它。

class Adapter(
    ...,
    private val callback: MyAdapterCallback
) {
  

   ...setOnClickListener{
             int ++ //this will work as long as int here is a valid thing
             callback.onButtonClicked(int)
        }

}

您可能会在delegate命名中看到这种模式,我使用callback只是为了使它更清楚。
另一个肮脏的解决方案是将视图传递给适配器。

class Adapter(
    ...,
    private val myView: TextView
) {
  

   ...setOnClickListener{
             int ++ //this will work as long as int here is a valid thing
             myView.text = "$int"
        }

}

这是一个非常糟糕的解决方案,因为它破坏了关注点分离原则,您应该只将其用于调试。
最后,您目前面临的问题是:

View(myContext).findViewByID<TextView>(R.id.textView).setText("$var")

这是示例化一个新的View,在View中,您试图找到R.id.textView,该视图是全新的,因此它没有任何内容。您的R.id.textView位于Activity布局中,一个完全不同的视图。因此,方法findViewByID返回null。但是,您声明该方法应该找到非空的TextView,这就是它崩溃的原因。如果您将其更改为TextView?,则它将被处理为可空,且不会崩溃,但由于它不存在,因此毫无意义。方法findViewByID不会搜索每个位置,只会在您正在访问View中进行搜索。

相关问题