关于kotlin泛型的使用

因为之前一直想用kotlin开发,正好现在要开一个新项目,所以准备用kotlin来做。把我之前用的mvvm框架的java代码自动转成kotlin以后,有很多地方都报了异常,主要都是泛型的部分,由于框架的基础部分应用了很多泛型,导致自动转了以后很多地方都不符合语法,所以努力的查阅了很多资料,终于修改成了kotlin的代码。

网上很多关于kotlin的泛型的教程都讲的很复杂,形变,投影,协变,逆变,看了半天看的很迷惑。所以这块我把自己改好的源码贴出来,底下会放我整个框架的链接,kotlin的部分为了方便直接上传到了之前的mvvm框架练习的代码里面,这样对照java的源码,可以看一下比较复杂的情况,kotlin的代码是应该如何写的。我个人认为比看那些很多专业名词的教程要直观。下面先贴一个比较复杂的一个adapter的基类的java源码和kotlin源码。两个类是一样的只是语法实现不同。不太会用kotlin泛型的人。翻到这篇可以用来参考一下。上面是kotlin代码,下面是java的代码,这是一个recyclerview的适配器积累,包含footer的那种。也就是说会有两种不同的布局。加上我的框架使用了viewbinding。所以这一个文件用了三个泛型,算是比较复杂的。通过对比可以很好的掌握kotlin泛型的写法。文章最底下是整个框架的源码包含java和kotlin的。直接运行的话,是java的代码。kotlin部分也有使用的实例但是布局文件并没有放进来。也是非常的简单,可以根据代码推测出布局文件的样子。主要是比较懒不想单独传一个项目。所以只是在之前的框架的源码建了一个目录把这次改成kotlin的上传了。

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding

abstract class BaseHaveFooterAdapter<T,  B:ViewBinding, F : ViewBinding> :RecyclerView.Adapter<BaseHaveFooterAdapter.ViewHolder<in ViewBinding>>{
    var onItemClick: OnItemClick? = null


    protected var mDatas:List<T>? = null
    protected var context: android.content.Context
    fun getmDatas(): List<T>? {
        return mDatas
    }

    fun setmDatas(mDatas:List<T>?) {
        this.mDatas = mDatas
    }

    constructor(context: android.content.Context) {
        this.context = context
    }

    constructor(context: android.content.Context, mDatas: kotlin.collections.List<T>?) {
        this.mDatas = mDatas
        this.context = context
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): ViewHolder<in ViewBinding> {
        val inflater = LayoutInflater.from(context)
       if (viewType == 0) {
            val binding = setBinding(inflater, parent)
            val viewHolder =   BaseHaveFooterAdapter.ViewHolder<B>(binding!!.root)
            viewHolder.binding=binding;
            if (onItemClick != null) {
                viewHolder.onItemClick = onItemClick
            }
           return viewHolder as ViewHolder<in ViewBinding>;
        } else {
            val binding = setFootBinding(inflater, parent)
            val viewHolder =
                BaseHaveFooterAdapter.ViewHolder<F>(binding!!.root)
            viewHolder.binding=binding;
            if (onItemClick != null) {
                viewHolder.onItemClick = onItemClick
            }
            return viewHolder as ViewHolder<in ViewBinding>;
        }
    }

    override fun onBindViewHolder(
        holder: BaseHaveFooterAdapter.ViewHolder<ViewBinding>,
        position: Int
    ): kotlin.Unit {
        if (position == mDatas?.size) {
            val myholder =
                holder as BaseHaveFooterAdapter.ViewHolder<B>
            onBindFooterHolder(myholder, position)
        } else {
            val myholder =
                holder as BaseHaveFooterAdapter.ViewHolder<F>
            onBindHolder(myholder, position)
        }
    }

    protected abstract fun onBindHolder(
        holder: ViewHolder<F>,
        position: Int
    ): kotlin.Unit

    protected abstract fun onBindFooterHolder(
        holder: ViewHolder<B>,
        position: Int
    ): kotlin.Unit

    override fun getItemViewType(position: Int): Int {
        return if (position == mDatas!!.size) 1 else 0
    }

    override fun getItemId(position: Int): kotlin.Long {
        return position.toLong()
    }

    protected abstract fun setBinding(inflater: LayoutInflater?, parent: ViewGroup?): B
    protected abstract fun setFootBinding(inflater: LayoutInflater?, parent: ViewGroup?): F
    override fun getItemCount(): Int {
        return if (mDatas == null) 1 else mDatas!!.size + 1
    }

    class ViewHolder<in ViewBinding>(itemView: android.view.View) :
        RecyclerView.ViewHolder(itemView), android.view.View.OnClickListener {
        var onItemClick: BaseHaveFooterAdapter.OnItemClick? =
            null
        var binding: androidx.viewbinding.ViewBinding? = null


        fun setClick(vararg views: android.view.View): kotlin.Unit {
            if (onItemClick != null) {
                for (view in views) {
                    view.setOnClickListener(this)
                }
            }
        }

        fun setOnFooterClick(vararg views: android.view.View) {
            if (onItemClick != null) {
                for (view in views) {
                    view.setOnClickListener { v -> onItemClick?.onFooterClick(v) }
                }
            }
        }

        override fun onClick(v: android.view.View){
            onItemClick?.onClick(v, getAdapterPosition())
        }
    }

    interface OnItemClick {
        fun onClick(view: android.view.View, position: Int)
        fun onFooterClick(view: android.view.View)
    }
}
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;

/**
 * Created by Administrator on 16-7-18.
 */
public abstract class BaseHaveFooterAdapter<T, B extends ViewBinding,F extends  ViewBinding> extends RecyclerView.Adapter<BaseHaveFooterAdapter.ViewHolder> {
    protected OnItemClick onItemClick;
    protected List<T> mDatas;
    protected Context context;

    public List<T> getmDatas() {
        return mDatas;
    }

    public void setmDatas(List<T> mDatas) {
        this.mDatas = mDatas;
    }

    public BaseHaveFooterAdapter(Context context) {
        this.context = context;
    }

    public BaseHaveFooterAdapter(Context context, List<T> mDatas) {
        this.mDatas = mDatas;
        this.context = context;
    }

    public OnItemClick getOnItemClick() {
        return onItemClick;
    }

    public void setOnItemClick(OnItemClick onItemClick) {
        this.onItemClick = onItemClick;

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        LayoutInflater inflater = LayoutInflater.from(context);
        if(viewType==0) {

            B binding = setBinding(inflater, parent);
            ViewHolder<B> viewHolder = new ViewHolder<B>(binding.getRoot());
            viewHolder.setBinding(binding);


            if (onItemClick != null) {
                viewHolder.setOnItemClick(onItemClick);
            }
            return viewHolder;
        }else{
            F binding = setFootBinding(inflater, parent);
            ViewHolder<F> viewHolder = new ViewHolder<F>(binding.getRoot());
            viewHolder.setBinding(binding);


            if (onItemClick != null) {
                viewHolder.setOnItemClick(onItemClick);
            }
            return viewHolder;
        }


    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

        if(position==mDatas.size()){
            ViewHolder<F> myholder = (ViewHolder<F>) holder;
            onBindFooterHolder(myholder, position);
        }else {
            ViewHolder<B> myholder = (ViewHolder<B>) holder;
            onBindHolder(myholder, position);
        }
    }

    protected abstract void onBindHolder(ViewHolder<B> holder, int position);

    protected abstract void onBindFooterHolder(ViewHolder<F> holder, int position);

    @Override
    public int getItemViewType(int position) {
        return  position == mDatas.size() ? 1 : 0;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    protected abstract B setBinding(LayoutInflater inflater, ViewGroup parent);

    protected abstract F setFootBinding(LayoutInflater inflater, ViewGroup parent);

    @Override
    public int getItemCount() {
        return mDatas == null  ? 1: mDatas.size() + 1;
    }

    public static class ViewHolder<B extends ViewBinding> extends RecyclerView.ViewHolder implements View.OnClickListener {
        protected OnItemClick onItemClick;
        public B binding;

        public OnItemClick getOnItemClick() {
            return onItemClick;
        }

        public void setOnItemClick(OnItemClick onItemClick) {
            this.onItemClick = onItemClick;
        }

        public B getBinding() {
            return binding;
        }

        public void setBinding(B binding) {
            this.binding = binding;
        }

        public ViewHolder(View itemView) {
            super(itemView);
        }

        public void setClick(View... views) {
            if (onItemClick != null) {
                for (View view : views) {
                    view.setOnClickListener(this);
                }
            }
        }
        public void setOnFooterClick(View... views) {
            if (onItemClick != null) {
                for (View view : views) {
                    view.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            onItemClick.onFooterClick(v);
                        }
                    });
                }
            }
        }

        @Override
        public void onClick(View v) {
            onItemClick.onClick(v, getAdapterPosition());
        }
    }

    public static interface OnItemClick {
        void onClick(View view, int position);
        void onFooterClick(View view);
    }

}

源码已经上传github

地址:https://github.com/roofroot/test_view_binding

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值