Android之路

导航

关于RecyclerView.Adapter 的 onBindViewHolder 混合布局 不执行的问题

最近在一个现有Adapter中 添加了多种混合布局样式,结果运行发现,新增的混合布局所在的item 不会去执行 onBindViewHolder(@NotNull RecyclerView.ViewHolder holder,  int position)   纳闷啊,不应该啊,这怎么能有问题?起初,以为是混合布局中嵌套的RecyclerView的问题,换成只有一个TextView的标题布局也一样,首次加载列表就不执行。此时实在不知道是哪里的问题了,看了之前同样使用混合布局的其他Adapter,都正常,哪里有问题呢?怀疑人生了……  这种时候,借助一下万能的百度吧,查询到的结果,都是 什么没有设置setLayoutManager 类似这种,我的明显不属于这种情况。
      突然脑子灵光闪现,这个方法 onBindViewHolder(@NotNull RecyclerView.ViewHolder holder,  int position) 由谁触发的,查看源码,才能找到根本原因。果然,很快找到了答案,对比自己的代码,
确实是这个问题,修改后一切正常!!废话说多了,以下由源码引入:

        //暂时称之为【方法一】
        public abstract void onBindViewHolder(@NonNull VH var1, int var2);  //该方法是抽象的,其是由下述三个参数的重载方法调用的.

        //【方法二】
        public void onBindViewHolder(@NonNull VH holder, int position, @NonNull List<Object> payloads) {
            this.onBindViewHolder(holder, position); //此处真正的触发位置.  
        }
    
        由上,显而易见,若出现【方法一】没有执行的问题,是不是自己的代码重写了【方法二】,并在【方法二】中的逻辑书写有问题。一般重写【方法二】都是存在局部刷新item的
需求,默认不会去重写。但是重写时需要注意,尤其是混合布局时。以下为修改前的原始代码:
@Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List payloads) {
            if (holder instanceof ContentViewHolder) {
            if (payloads.isEmpty()) { //错误的位置
                onBindViewHolder(holder, position);
                   }else{
                     //执行局部更新的操作..
                  }
            }
   }  


      很明显,上述代码存在逻辑问题,当然,添加混合布局前,上述代码也没啥问题,因为只有ContentViewHolder 这一种布局,这不是一个好的习惯!回到本文开始,由于需求的变更,现在我加入了混合布局,此时,新增了CardViewHolder,但是可以发现public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List payloads) 的逻辑中没有相关的处理,默认payloads.isEmpty() 为空,但是该条件放在了holder instanceof ContentViewHolder内部,导致其他布局均无法触发onBindViewHolder(holder, position);   这就是文章开始遇到的问题。修改起来也很简单,如下:

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List payloads) {
        if (payloads.isEmpty()) {//正常执行流程.
            onBindViewHolder(holder, position);
        }else {
               //根据需要,进行相应的局部更新处理.
               if (holder instanceof ContentViewHolder) {

               } else if(holder instanceof CardViewHolder){
        
               } else if(...){

        }
}
    


    可以看到,该问题修改起来很简单,问题也很简单,但是明白前,就是摸不着头绪,严格来讲,这属于一个开发中自己挖的坑,由于代码的逻辑问题,或者说是对于onBindViewHolder理解的不透彻导致的问题。所以很多时候不要一知半解,没事儿多看看源码,或者出现问题了,优先查看源码,明白代码的执行流程,知其然更要知其所以然!这次算是一个教训吧,与大家共勉!!


posted on 2023-03-01 15:56  Android之路  阅读(844)  评论(0编辑  收藏  举报