在ListView的自定义适配器中使用Anko DSL时的上下文问题

时间:2016-09-12 10:46:15

标签: android android-layout android-studio kotlin anko

我正在尝试为ListView编写一个通用适配器,它允许使用Anko DSL作为项目的内容。代码如下所示。正如您所看到的,有一个丑陋的补丁with(viewGroup!!.context)可以使代码工作。它并不像你看到的其他Anko例子那样。如果我删除with语句,我的应用程序将崩溃

FATAL EXCEPTION: java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams 

有没有办法避免with声明?

import java.util.*
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter

class AnkoAdapter(itemFactory: () -> AbstractList<Any>, viewFactory: (index: Int, items: AbstractList<Any>, view: View?, viewGroup: ViewGroup?) -> View): BaseAdapter() {
    val viewFactory = viewFactory
    val items: AbstractList<Any> by lazy { itemFactory() }

    override fun getView(index: Int, view: View?, viewGroup: ViewGroup?): View {
        return viewFactory(index, items, view, viewGroup)
    }

    override fun getCount(): Int {
        return items.size
    }

    override fun getItem(index: Int): Any {
        return items.get(index)
    }

    override fun getItemId(index: Int): Long {
        return items.get(index).hashCode().toLong() + (index.toLong() * Int.MAX_VALUE)
    }
}

// -------------
// In main acitivty.
...
val items = listOf<String>("Mary", "Lisa", "Cheryl", "Linda")
val buttonCaption = "..."
listView.adapter = AnkoAdapter({items as AbstractList<Any>}) {
    index: Int, items: AbstractList<Any>, view: View?, viewGroup: ViewGroup? ->
    with(viewGroup!!.context) {
        linearLayout {
            textView(items[index].toString())
            button(buttonCaption)
        }
    }
}

1 个答案:

答案 0 :(得分:0)

根据此video,这是修改后的版本:

class AnkoAdapter<T>(itemFactory: () -> List<T>, viewFactory: Context.(index: Int, items: List<T>, view: View?) -> View): BaseAdapter() {
    val viewFactory = viewFactory
    val items: List<T> by lazy { itemFactory() }

    override fun getView(index: Int, view: View?, viewGroup: ViewGroup?): View {
        return viewGroup!!.context.viewFactory(index, items, view)
    }

    override fun getCount(): Int {
        return items.size
    }

    override fun getItem(index: Int): T {
        return items.get(index)
    }

    override fun getItemId(index: Int): Long {

        return (items.get(index) as Any).hashCode().toLong() + (index.toLong() * Int.MAX_VALUE)
    }
}

val items = listOf<String>("Mary", "Lisa", "Cheryl", "Linda")
val buttonCaption = "..."
lockView.adapter = AnkoAdapter<String>({ items }) {
    index, items, view ->
    linearLayout {
        textView(items[index])
        button(buttonCaption)
    }
}