actx23a 2019-12-17 14:30 采纳率: 0%
浏览 1470
已结题

android oncreateviewholder,getItemViewType,onBindViewHolder方法什么时候调用

如题:android oncreateviewholder,getItemViewType,onBindViewHolder方法什么时候调用?

  • 写回答

1条回答 默认 最新

  • 王能 2019-12-17 16:55
    关注

    这个是RecyclerView用于回调的方法,至于什么时候调用不需要关心,要关心的应该是他们的作用。
    一下摘自我的博客,建议去看看:给新人的一些基础常识

    复用的原理:首先listview(RecyclerView同理)会从第一个去加载view,当第10个时发现铺满全屏了,加载结束。现在你往下滑了一下,需要加载第11个,此时lv判断出第一个已经在屏幕外了,于是lv将第一个移除,放在了getView的convertView里,剩下的就是大家经常做的了,如下代码如果convertView不是null就将convertView拿来修修补补再返回给lv,如果是null(一般就是那前10个)就创建新的。

        public final View getView(int position, View convertView, ViewGroup parent) {
            VH holder;
            if (convertView == null || convertView.getTag(R.id.tag_view_holder) == null) {
                //模仿recyclerview,除了bind是position外,其他都是viewType
                holder = onCreateViewHolder(parent, getItemViewType(position), mInflater);
                holder.itemView.setTag(R.id.tag_view_holder, holder);
            } else {
                holder = (VH) convertView.getTag(R.id.tag_view_holder);
            }
            bindViewHolder(holder, position);
            return holder.itemView;
        }
    

    RecyclerView就是把listview的if判断整个成了2个方法:onCreat和onBind

    oncreateviewholder:当rv请求创建新的viewholder时,没有可复用的控件时会调用创建一个新的复用控件。此时就是大家熟知的new ViewHolder了。

    onBindViewHolder:当rv要展示到ui页面上时。这就是我们设置数据的时候了,其中的holder有可能是上一次复用的view。

    getItemViewType:获取当前position的所属的类别,为了实现展示不同样式的条目而用的(俗称多条目)。直接举例吧:做一个RecyclerView列表,需求是0-10ImageView,10-20TextView,20-30ImageView...以此循环。此时你会是懵逼的,因为onCreateViewHolder没有position,但他有viewType,这个其实就是RecyclerView调用你的getItemViewType得到的。
    我们的getItemViewType为了区分ImageView和TextView的类别应该这样写:

                @Override
                public int getItemViewType(int position) {
                    if (position / 10 % 2 == 0) {//0-10是iv,10-20是tv,所以先除以10看看是不是奇偶数就行了
                        return 0;
                    } else {
                        return 1;
                    }
                }
    

    这时在onCreateViewHolder的时候就可以辨别了

                @Override
                public  ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                    if (viewType==0){
                        //创建iv的viewholder
                    }else {
                        //创建tv的viewholder
                    }
                }
    

    而在onBindViewHolder没有viewType,因为我们也可以用position调getItemViewType呀:

                @Override
                public void onBindViewHolder(ViewHolder holder, int position) {
                    int viewType = getItemViewType(position);
                    if (viewType==0){
                        //强制成tv的viewholder
                        TvViewHolder tvHolder = (TvViewHolder) holder;
                        tvHolder.mTv.setText("这是tv"+position);
                    }else {
                        //强制成iv的viewholder
                        IvViewHolder ivHolder = (IvViewHolder) holder;
                        ivHolder.mIv.setImageResource(R.drawable.xxx);
                    }
                }
    

    这样你就实现了每隔10个tv和iv的复用列表

    为什么复用列表这么麻烦,像h5那种直接添加一列多简单?
    虽然复用列表麻烦,但他理论上可以无限滑动下去并且内存都不带涨的,因为你滑来滑去就是那10来个控件修修补补而已,而像h5那种可以明显感受到滑的越多越卡。

    问答版主就是牛,从现在起只回论坛,不在踏入问答半步

    评论

报告相同问题?

悬赏问题

  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换