Есть несколько вещей, которые вы можете улучшить:
Вы в настоящее время пишете Javlin или Kotva, то есть смесь Java и Kotlin.
Вы не должны раздувать компоновку для каждого getView, и в идеале вы должны использовать шаблон ViewHolder (теперь показан ниже).
Но причина вашего вопроса, ошибка компилятора, вызывающая super
. Вы определяете свой конструктор как функцию, а не конструктор.
В Java конструкторы определяются написанием методов с тем же именем, что и у класса. В Kotlin вы просто передаете параметры конструктора в определении класса. например,
class WordAdapter(context: Context, objects: List<Word>)
и передать эти параметры в расширенный класс следующим образом:
class WordAdapter(context: Context, objects: List<Word>) :
ArrayAdapter<Word>(context, R.layout.list_item, R.id.default_text_view, objects)
альтернативный подход, обычно зарезервированный для вторичных конструкторов:
class WordAdapter : ArrayAdapter<Word> {
constructor(context: Context, objects: List<Word>) : super(
context, R.layout.list_item, R.id.default_text_view, objects
)
}
Вот несколько Kotlinified версия вашего кода (я видел, что вы меняли default и miwok в вашем getView, я предположил, что это было ошибкой, и не копировал это). Я также разместил копию на Github .
class MainActivity : AppCompatActivity() {
private val words = arrayListOf(
Word("one", "lutti"),
Word("two", "otiiko"),
Word("three", "tolookosu"),
Word("four", "oyyisa"),
Word("five", "massokka"),
Word("six", "temmokka"),
Word("seven", "kenekaku"),
Word("eight", "kawinta"),
Word("nine", "wo’e"),
Word("ten", "na’aacha")
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val listView = findViewById<ListView>(R.id.list)
val adapter = WordAdapter(this, words)
listView.adapter = adapter
}
}
data class Word(val defaultTranslation: String, val miwokTranslation: String)
class WordAdapter(context: Context, objects: List<Word>) :
ArrayAdapter<Word>(context, R.layout.list_item, R.id.default_text_view, objects) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val listItemView = super.getView(position, convertView, parent)
val defaultTextView = listItemView.findViewById<TextView>(R.id.default_text_view)
val miwokTextView = listItemView.findViewById<TextView>(R.id.miwok_text_view)
getItem(position)?.run {
defaultTextView.text = defaultTranslation
miwokTextView.text = miwokTranslation
}
return listItemView
}
}
Вот пример адаптера, использующего (версию) шаблон ViewHolder (если вы установите точку останова ведения журнала на любой из row.findViewById
, вы увидите, что они вызываются только для того количества элементов, которое отображается, а не для каждый элемент в списке):
class WordAdapter(context: Context, objects: List<Word>) :
ArrayAdapter<Word>(context, R.layout.list_item, R.id.default_text_view, objects) {
class ViewHolder(row: View) {
init {
row.tag = this
}
val defaultTextView = row.findViewById<TextView>(R.id.default_text_view)!!
val miwokTextView = row.findViewById<TextView>(R.id.miwok_text_view)!!
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val listItemView = super.getView(position, convertView, parent)
val holder = listItemView.tag as? ViewHolder ?: ViewHolder(listItemView)
getItem(position)?.run {
holder.defaultTextView.text = defaultTranslation
holder.miwokTextView.text = miwokTranslation
}
return listItemView
}
}
Если вы хотите пойти за борт [:)] идиомы Kotlin:
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View =
super.getView(position, convertView, parent).also { row ->
(row.tag as? ViewHolder ?: ViewHolder(row)).apply {
getItem(position)?.run {
defaultTextView.text = defaultTranslation
miwokTextView.text = miwokTranslation
}
}
}