当前,我有一个要填充的列表,但是列表项可以具有不同的数据。我有两个数据类,为了容纳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的类型匹配,您也无法在编译时证明它,因此编译器会对您大吼大叫。您无法进行调用bind
,BaseViewHolder<*>
因为参数必须是*
不可能发生的类型。您在那里需要什么,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] 删除。
我来说两句