Reputation: 63
I learn the use of ViewHolder from an offical sample named UserViewHolder.
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();
}
}
I'm going to write many ViewHolder
classes, so I hope I can write an abstract class. In Java, it looks like:
public abstract static class BaseViewHolder {
abstract static BaseViewHolder create()
abstract void bindTo()
}
I try to write it using Kotlin , but finally I find that it's not as simple as it in Java.
abstract class BaseViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
abstract fun bindTo(viewModel: BaseViewModel)
}
In Kotlin, if I want a static function, I need to write the function in "companion objects". But it can't be a "abstract".
In Java, a abstract class with abstract classes is common.
But how can I write it in Kotlin?
update:
I have wrote my own SleepViewHolder. I'm going to write lots of ViewHolder, such as AppleViewHolder, BananaViewHolder and so on. So I want to build a BaseViewHolder as a pattern. My question is that, in that case, what's the best way to write the pattern BaseViewHolder? Should I change the constrcuter of it, or make the create function public?
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()
}
}
Upvotes: 6
Views: 12185
Reputation: 2553
By default, nested classes are static
in Kotlin. So you don't have to add any modifier before your class name. You can refer to the example I presented below as a starting point.
Note: ItemFruit
is superclass of both ItemApple
and 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)
}
}
Upvotes: 0
Reputation: 3960
In Kotlin
, unlike Java or C#,
classes do not have static methods. In most cases, it's recommended to simply use package-level functions instead.
If you need to write a function that can be called without having a class instance but needs access to the internals of a class (for example, a factory method), you can write it as a member of an object declaration inside that class.
Even more specifically, if you declare a companion object inside your class, you'll be able to call its members with the same syntax as calling static methods in Java/C#
, using only the class name as a qualifier.
This is how you can write a companion class
class MyClass {
companion object { } // will be called "Companion"
}
fun MyClass.Companion.foo() { // ...
}
this is how you call foo() function...
MyClass.foo()
Upvotes: 5