美文网首页
【Android面试题】高级UI面试题——如何对ListView

【Android面试题】高级UI面试题——如何对ListView

作者: 小城哇哇 | 来源:发表于2023-09-06 17:39 被阅读0次

    如何对ListView & RecycleView进行局部刷新的?

    这道题想考察什么?

    考察同学是否对列表局部刷新清楚。

    考生应该如何回答

    ListView

    我们要进行单条刷新就要手动调用这个方法。

    public View getView(int position, View convertView, ViewGroup parent)
    

    google 2011年开发者大会上提出了ListView的单条刷新方法,代码如下:

    private void updateSingleRow(ListView listView, long id) {
     
            if (listView != null) {
                int start = listView.getFirstVisiblePosition();
                for (int i = start, j = listView.getLastVisiblePosition(); i <= j; i++)
                    if (id == ((Messages) listView.getItemAtPosition(i)).getId()) {
                        View view = listView.getChildAt(i - start);
                        getView(i, view, listView);
                        break;
                    }
            }
        }
    

    RecyclerView

    RecyclerView 局部刷新一般使用 notifyItemChanged(position);方法。
    但是这个方法有个问题,同样会刷新item中所有东西,并且在不断刷新的时候会执行刷新Item的动画,导致滑动的时候会错开一下,还可能会造成图片重新加载或者不必要的消耗。
    所以下面我们看下源码如何解决这个问题。直接找到 RecyclerView 的 notifyItemChanged(position) 方法,如下:

    public final void notifyItemChanged(int position) {
        mObservable.notifyItemRangeChanged(position, 1);
    }
    
    

    这个方法里调用了notifyItemRangeChanged方法,继续跟踪

    public void notifyItemRangeChanged(int positionStart, int itemCount) {
        notifyItemRangeChanged(positionStart, itemCount, null);
    }
    
    

    发现这里执行了另一个重载方法
    最后一个参数为null?继续跟进

    public void notifyItemRangeChanged(int positionStart, int itemCount,
            @Nullable Object payload) {
        for (int i = mObservers.size() - 1; i >= 0; i--) {
            mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload);
        }
    }
    
    

    发现这里的参数为Object payload,然后我看到了notifyItemChanged的另一个重载方法,这里也有一个Object payload参数,看一下源码:

    public final void notifyItemChanged(int position, @Nullable Object payload) {
        mObservable.notifyItemRangeChanged(position, 1, payload);
    }
    
    

    payload 的解释为:如果为null,则刷新item全部内容,话外之音就是不为空就可以局部刷新了!
    继续从payload跟踪,发现在RecyclerView中有另一个onBindViewHolder的方法,多了一个参数,payload。

    public void onBindViewHolder(@NonNull VH holder, int position,
            @NonNull List<Object> payloads) {
        onBindViewHolder(holder, position);
    }
    
    

    发现它调用了另一个重载方法,而另一个重载方法就是我们在写adapter中抽象的方法,那我们就可以直接从这里入手了。
    1.重写onBindViewHolder(VH holder, int position, List payloads)这个方法

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position, List<Object> payloads) {
        super.onBindViewHolder(holder, position, payloads);
        if (payloads.isEmpty()){  
            //全部刷新
        }else {
            //局部刷新
        }
    }
    

    2.执行两个参数的notifyItemChanged,第二个参数只要不让它为空,随便什么都行,这样就可以实现只刷新item中某个控件了。

    有需要以上面试题的朋友可以关注一下哇哇,以上都可以分享!!!

    相关文章

      网友评论

          本文标题:【Android面试题】高级UI面试题——如何对ListView

          本文链接:https://www.haomeiwen.com/subject/mdakvdtx.html