我从一个名为UserViewHolder的官方样本中学习了ViewHolder的使用。
public class UserViewHolder extends RecyclerView.ViewHolder {
static UserViewHolder create(LayoutInflater inflater, ViewGroup parent) {
UserItemBinding binding = UserItemBinding
.inflate(inflater, parent, false);
return new UserViewHolder(binding);
}
private UserItemBinding mBinding;
private UserViewHolder(UserItemBinding binding) {
super(binding.getRoot());
mBinding = binding;
}
public void bindTo(User user) {
mBinding.setUser(user);
mBinding.executePendingBindings();
}
}
我要写很多ViewHolder
个类,所以我希望我能写一个抽象类。在Java中,它看起来像:
public abstract static class BaseViewHolder {
abstract static BaseViewHolder create()
abstract void bindTo()
}
我尝试使用Kotlin编写它,但最后我发现它并不像Java中那么简单。
abstract class BaseViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
abstract fun bindTo(viewModel: BaseViewModel)
}
在Kotlin中,如果我想要一个静态函数,我需要在“伴侣对象”中编写该函数。但它不可能是“抽象的”。
在Java中,带抽象类的抽象类很常见。
但是如何在Kotlin中写出来?
更新
我已经编写了自己的 SleepViewHolder 。我要写很多ViewHolder,比如AppleViewHolder,BananaViewHolder等等。所以我想构建一个 BaseViewHolder 作为模式。我的问题是,在这种情况下,编写模式 BaseViewHolder 的最佳方法是什么?我应该更改它的构成,还是将创建功能公开?
open class SleepViewHolder private constructor(private val binding: ItemSleepBinding)
: RecyclerView.ViewHolder(binding.root) {
companion object {
@JvmStatic
fun create(inflater: LayoutInflater, parent: ViewGroup): SleepViewHolder {
val binding: ItemSleepBinding
= DataBindingUtil.inflate(inflater, R.layout.fragment_base, parent, false)
return SleepViewHolder(binding)
}
}
open fun bindTo(viewmodel: SleepViewModel) {
binding.vm = viewmodel
binding.executePendingBindings()
}
}
答案 0 :(得分:2)
在Kotlin
中,与Java or C#,
类不同,没有静态方法。在大多数情况下,建议只使用包级功能。
如果您需要编写一个可以在没有类实例但需要访问类的内部(例如,工厂方法)的情况下调用的函数,则可以将其作为对象声明的成员写入其中类。
更具体地说,如果在类中声明一个伴随对象,您将能够使用与Java/C#
中调用静态方法相同的语法来调用其成员,只使用类名作为限定符。
这是你编写伴侣类的方法
class MyClass {
companion object { } // will be called "Companion"
}
fun MyClass.Companion.foo() { // ...
}
这就是你如何调用foo()函数......
MyClass.foo()
答案 1 :(得分:0)
默认情况下,嵌套类在Kotlin中为static
。因此,您不必在类名之前添加任何修饰符。您可以参考下面提供的示例作为起点。
注意::ItemFruit
是ItemApple
和ItemBanana
的超类
class ExampleAdapter: RecyclerView.Adapter<ExampleAdapter.BaseViewHolder<ItemFruit>>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DynamicSpinnerAdapter.ViewHolder {
when(viewType){
VIEW_TYPE_BANANA -> BananaViewHolder(....) // Inflate your view Banana layout here
VIEW_TYPE_APPLE -> AppleViewHolder(....) // Inflate your view Banana layout here
else -> // Do something for default case
}
}
override fun onBindViewHolder(holder: BaseViewHolder<ItemFruit>, position: Int){
holder.bind(itemAppleOrBanana) // binds your item to corresponding view
}
override fun getItemViewType(position: Int): Int {
return when (position){
condition_banana -> VIEW_TYPE_BANANA
condition_apple -> VIEW_TYPE_BANANA
else -> VIEW_TYPE_NONE
}
}
inner class BananaViewHolder(itemView: View): BaseViewHolder<ItemBanana>(itemView) {
override fun bind(item: ItemBanana) {
// Implement your logic
}
}
inner class AppleViewHolder(itemView: View): BaseViewHolder<ItemApple>(itemView) {
override fun bind(item: ItemApple) {
// Implement your logic
}
}
inner abstract class BaseViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView){
internal abstract fun bind(item: T)
}
internal abstract inner class GenericViewHolder<T>(itemView: View) :
RecyclerView.ViewHolder(itemView) {
internal abstract fun bind(item: T, position: Int)
}
}