将通用的RecyclerView适配器转换为Kotlin

Onemandan

当前,我有一个要填充的列表,但是列表项可以具有不同的数据。我有两个数据类,为了容纳RecyclerView,我有两个不同的ViewHolder扩展了基本的基本ViewHolder。由于不同的布局用于不同的数据类,因此需要不同的ViewHolders。

我已将视图持有人转换为Kotlin,但是适配器存在问题。

Kotlin中的基本ViewHolder:

abstract class BaseViewHolder<T> internal constructor(view: View) : RecyclerView.ViewHolder(view) {
    abstract fun bind(item: T)
}

一个在Kotlin中实现基本ViewHolder的ViewHolder:

class StandardViewHolder(view: View): BaseViewHolder<Standard>(view) {

    private val _eventView      : TextView = view.findViewById(R.id.eventTextView)
    private val _dateView       : TextView = view.findViewById(R.id.dateTextView)

    override fun bind(item: Standard) {
        _eventView.text     = item.event
        _dateView.text      = item.date.toString()
    }
}

在Java中,我可以创建一个使用以下ViewHolders的适配器:

public class ListAdapter extends RecyclerView.Adapter<BaseViewHolder> {

    private List<Object> _items;
    private Context _context;

    public ListAdapter(List<Object> items, Context context){
        _items      = items;
        _context    = context;
    }

    @NonNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == R.layout.item_standard){
            return new StandardViewHolder(LayoutInflater.from(_context).inflate(
                    R.layout.item_standard, parent, false));
        }

        return new AdvancedViewHolder(LayoutInflater.from(_context).inflate(
                R.layout.item_advanced, parent, false));
    }

    @Override
    @SuppressWarnings("unchecked")
    public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
        holder.bind(_items.get(position));
    }

    @Override
    public int getItemCount() {
        return _items.size();
    }

    @Override
    public int getItemViewType(int position) {
        if(_items.get(position) instanceof Standard){
            return R.layout.item_standard;
        }

        return R.layout.item_advanced;
    }
}

但是,如果将其转换为Kotlin,则在holder.bind上会收到错误消息,即:

投影类型为'BaseViewHolder <*>'的类型禁止使用'公共抽象有趣的绑定(item:T)'

class ListAdapter(private val _items: List<Any>, private val _context: Context) : RecyclerView.Adapter<BaseViewHolder<*>>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {
        return if (viewType == R.layout.item_standard) {
            StandardViewHolder(LayoutInflater.from(_context).inflate(
                    R.layout.item_standard, parent, false))
        } else {
            AdvancedViewHolder(LayoutInflater.from(_context).inflate(
                    R.layout.item_advanced, parent, false))
        }
    }

    override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) = holder.bind(_items[position])

    override fun getItemCount() = _items.size

    override fun getItemViewType(position: Int): Int {
        return if (_items[position] is Standard) {
            R.layout.item_standard
        } else {
            R.layout.item_advanced
        }
    }
}

如何在Kotlin中使用这些通用ViewHolders?

狮子座阿苏

问题是,即使您知道绑定的项目与为其创建的ViewHolder的类型匹配,您也无法在编译时证明它,因此编译器会对您大吼大叫。您无法进行调用bindBaseViewHolder<*>因为参数必须是*不可能发生的类型您在那里需要什么,BaseViewHolder<Any>但不能制造适配器,RecyclerView.Adapter<BaseViewHolder<Any>>因为那样会损坏onCreateViewHolder我试过了BaseViewHolder<out Any>,那也不行。

所以这是您的工作:使用BaseViewHolder<*>,然后onBindViewHolder将其内部强制转换为BaseViewHolder<Any>编译器将抱怨“嘿!这是未经检查的强制转换!您不应该这样做! ”,所以告诉它使用来关闭@Suppress("UNCHECKED_CAST")

class ListAdapter(
        private val _items: List<Any>,
        private val _context: Context
) : RecyclerView.Adapter<BaseViewHolder<*>>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {
        return if (viewType == R.layout.item_standard) {
            StandardViewHolder(LayoutInflater.from(_context).inflate(
                    R.layout.item_standard, parent, false))
        } else {
            AdvancedViewHolder(LayoutInflater.from(_context).inflate(
                    R.layout.item_advanced, parent, false))
        }
    }

    @Suppress("UNCHECKED_CAST")
    override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) {
        (holder as BaseViewHolder<Any>).bind(_items[position])
    }

    override fun getItemCount() = _items.size

    override fun getItemViewType(position: Int): Int {
        return if (_items[position] is Standard) {
            R.layout.item_standard
        } else {
            R.layout.item_advanced
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在我的recyclerview适配器中的Kotlin中将JSON日期转换为字符串?

创建通用基础适配器?

将单击侦听器添加到通用RecyclerView适配器

RecyclerView通用适配器,数据绑定

如何使用Kotlin实现像Realm RecyclerView适配器这样的延迟加载RecyclerView适配器

Kotlin:如何将数据从RecyclerView适配器发送到片段

如何将日期从适配器更新到recyclerView?

Kotlin-cant从RecyclerView适配器替换片段

如何将ListView适配器转换为RecyclerView适配器?

java.lang.ClassCastException适配器转换为Activity

从通用类型获取Moshi适配器-Kotlin

非通用委托的适配器

从RecyclerView适配器转换为FirestoreRecyclerAdapter

从适配器更新recyclerview

Moshi自定义适配器将json镜像类转换为另一个

在recyclerview适配器(Kotlin)中处理按钮单击?

将适配器代码从Java转换为Kotlin时出现的问题

如何从Android Kotlin中的RecyclerView适配器获取arraylist

被动将VGA转换为DVI-D适配器?

在Worklight适配器中将JSON转换为xml

我可以将本地无线适配器转换为加密狗吗?

将变量从活动访问到RecyclerView适配器

将数据从 Recyclerview 适配器传递到 Fragment

RecyclerView() 适配器

使用 SQLite 数据库将适配器 onBindViewHolder itemView 上下文转换为类上下文

Kotlin:将数据/数组从 Recyclerview Activity 传递到适配器

kotlin.Unit 不能转换为 java.util.List。用于 getFilter 上的自定义适配器

RecyclerView:没有附加适配器;跳过布局 - kotlin

如何在 Kotlin 中使用反向绑定适配器将小写文本转换为大写?