• android:ListView的局部刷新


    1.简介

    对于android中的ListView刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifyDataSetChanged()刷新ListView。在这种模式下,我们会在getView中,根据不同的数据源,让控件显示不同的内容。这种模式是最常见的刷新模式,当我们来回滑动ListView的时候,调用adapter的getView方法,然后listview对adapter返回的View进行绘制。这种模式下,View的显示内容或状态都记录在adapter里面的数据源中,listview的更新频率不频繁,它随着数据源的变化而更新。

    ->ListView局部刷新问题的引入:

    假设我们的ListView的Item中有一个进度条(ProgressBar)和一个按钮,当我们点击一下按钮,进度条就会从0到100进行刷新,而且一般都需要在1s以内完成刷新过程,也就是说:在ListView的任一个Item中,触发了Button的事件之后,在1s以内,或者更短的时间,ProgressBar需要刷新100次。显然,如果我们使用修改数据源,调用notifyDataSetChanged()进行刷新的机制明显是不恰当的,效率极低,而且不一定凑效。那么,我们自然想到当点击的时候,希望能够获取到点击后的View内部的ProgressBar控件的对象,然后直接调用progressBar的setProgress就可以了,本以为这样就大功告成了。忽然,你会发现,当progressBar正在更新的时候,此时,往下滑listview,突然发现下面的某个进度条也在更新。仔细一分析,还真有道理,因为ListView中的View是复用的,当你向下滑动listview的时候,你此时操作的progressBar对象,已经不是刚才点击的那个Item了,因为很多Item复用一个View。那么如何解决这个问题呢?

    2.解决方案

    记录点击的Item的position,然后在更新过程中,不断的判断,该position是不是介于可见的Item之间,如果是,则更新,否者,不更新。

    private void updateProgressPartly(int progress,int position){
            int firstVisiblePosition = listview.getFirstVisiblePosition();
            int lastVisiblePosition = listview.getLastVisiblePosition();
            if(position>=firstVisiblePosition && position<=lastVisiblePosition){
                View view = listview.getChildAt(position - firstVisiblePosition);
                if(view.getTag() instanceof ViewHolder){
                    ViewHolder vh = (ViewHolder)view.getTag();
                    vh.pb.setProgress(progress);
                }
            }
        }

    其他相关代码:

    ListAdapter

    /*
     * $filename: ListAdapter.java,v $
     * $Date: 2014-9-19  $
     * Copyright (C) ZhengHaibo, Inc. All rights reserved.
     * This software is Made by Zhenghaibo.
     */
    package net.mobctrl.listviewdemo;
     
    import java.util.ArrayList;
    import java.util.List;
     
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.ProgressBar;
     
    /*
     *@author: ZhengHaibo  
     *blog:     http://blog.csdn.net/nuptboyzhb
     *mail:    zhb931706659@126.com
     *web:     http://www.mobctrl.net
     *2014-9-19  Nanjing,njupt,China
     */
    public class ListAdapter extends BaseAdapter {
     
        private List<model> datas;
        private Context context;
         
        private UpdateCallback updateCallback;
         
        public UpdateCallback getUpdateCallback() {
            return updateCallback;
        }
     
        public void setUpdateCallback(UpdateCallback updateCallback) {
            this.updateCallback = updateCallback;
        }
     
        public ListAdapter(Context context) {
            datas = new ArrayList<model>();
            this.context = context;
        }
     
        public void addData(Model model) {
            datas.add(model);
            notifyDataSetChanged();
        }
     
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return datas.size();
        }
     
        @Override
        public Object getItem(int pos) {
            // TODO Auto-generated method stub
            return datas.get(pos);
        }
     
        @Override
        public long getItemId(int arg0) {
            // TODO Auto-generated method stub
            return 0;
        }
     
        @Override
        public View getView(final int pos, View convertView, ViewGroup viewGroup) {
            final Model model = datas.get(pos);
            ViewHolder viewHolder = null;
            if (null == convertView) {
                viewHolder = new ViewHolder();
                convertView = LayoutInflater.from(context).inflate(
                        R.layout.list_item_layout, null);
                viewHolder.pb = (ProgressBar) convertView
                        .findViewById(R.id.pb_show);
                viewHolder.btn = (Button) convertView.findViewById(R.id.btn);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
                convertView.setTag(viewHolder);
            }
            viewHolder.btn.setText(model.getName());
            viewHolder.btn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(null != updateCallback){
                        updateCallback.startProgress(model,pos);
                    }
                }
            });
            viewHolder.pb.setProgress(0);
            // cache the view
            return convertView;
        }
         
        public static class ViewHolder {
            ProgressBar pb;
            Button btn;
        }
     
    }

    Activity

    /*
     * $filename: ListAdapter.java,v $
     * $Date: 2014-9-19  $
     * Copyright (C) ZhengHaibo, Inc. All rights reserved.
     * This software is Made by Zhenghaibo.
     */
    package net.mobctrl.listviewdemo;
     
    import java.util.ArrayList;
    import java.util.List;
     
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.ProgressBar;
     
    /*
     *@author: ZhengHaibo  
     *blog:     http://blog.csdn.net/nuptboyzhb
     *mail:    zhb931706659@126.com
     *web:     http://www.mobctrl.net
     *2014-9-19  Nanjing,njupt,China
     */
    public class ListAdapter extends BaseAdapter {
     
        private List<model> datas;
        private Context context;
         
        private UpdateCallback updateCallback;
         
        public UpdateCallback getUpdateCallback() {
            return updateCallback;
        }
     
        public void setUpdateCallback(UpdateCallback updateCallback) {
            this.updateCallback = updateCallback;
        }
     
        public ListAdapter(Context context) {
            datas = new ArrayList<model>();
            this.context = context;
        }
     
        public void addData(Model model) {
            datas.add(model);
            notifyDataSetChanged();
        }
     
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return datas.size();
        }
     
        @Override
        public Object getItem(int pos) {
            // TODO Auto-generated method stub
            return datas.get(pos);
        }
     
        @Override
        public long getItemId(int arg0) {
            // TODO Auto-generated method stub
            return 0;
        }
     
        @Override
        public View getView(final int pos, View convertView, ViewGroup viewGroup) {
            final Model model = datas.get(pos);
            ViewHolder viewHolder = null;
            if (null == convertView) {
                viewHolder = new ViewHolder();
                convertView = LayoutInflater.from(context).inflate(
                        R.layout.list_item_layout, null);
                viewHolder.pb = (ProgressBar) convertView
                        .findViewById(R.id.pb_show);
                viewHolder.btn = (Button) convertView.findViewById(R.id.btn);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
                convertView.setTag(viewHolder);
            }
            viewHolder.btn.setText(model.getName());
            viewHolder.btn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(null != updateCallback){
                        updateCallback.startProgress(model,pos);
                    }
                }
            });
            viewHolder.pb.setProgress(0);
            // cache the view
            return convertView;
        }
         
        public static class ViewHolder {
            ProgressBar pb;
            Button btn;
        }
     
    }
    </model></model>
    
    Activity
     
    
     
    
    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    package net.mobctrl.listviewdemo;
     
    import net.mobctrl.listviewdemo.ListAdapter.ViewHolder;
     
    import org.androidannotations.annotations.AfterViews;
    import org.androidannotations.annotations.EActivity;
    import org.androidannotations.annotations.UiThread;
    import org.androidannotations.annotations.ViewById;
     
    import android.app.Activity;
    import android.view.View;
    import android.widget.ListView;
    /**
     * @author 郑海波
     * @webset http://www.mobctrl.net
     * ListView的局部刷新
     */
    @EActivity(R.layout.activity_main)
    public class MainActivity extends Activity implements UpdateCallback{
     
        @ViewById
        ListView listview;
         
        private ListAdapter adapter;
         
        @AfterViews
        void afterViews() {
            adapter = new ListAdapter(this);
            adapter.setUpdateCallback(this);
            listview.setAdapter(adapter);
            initDatas();
        }
     
        private void initDatas() {
            for(int i = 0;i<100;i++){
                Model model = new Model(i, <click> --> );
                adapter.addData(model);
            }
        }
     
        @Override
        public void startProgress(final Model model,final int position) {
            /** start the Thread to update the Progress*/
            new Thread(new Runnable() {
                 
                @Override
                public void run() {
                    for(int i = 0;i<=100;i++){
                        updateProgressInUiThread(model, i,position);
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
         
        @UiThread
        void updateProgressInUiThread(Model model,int progress,int position){
            updateProgressPartly(progress,position);
        }
         
         
        private void updateProgressPartly(int progress,int position){
            int firstVisiblePosition = listview.getFirstVisiblePosition();
            int lastVisiblePosition = listview.getLastVisiblePosition();
            if(position>=firstVisiblePosition && position<=lastVisiblePosition){
                View view = listview.getChildAt(position - firstVisiblePosition);
                if(view.getTag() instanceof ViewHolder){
                    ViewHolder vh = (ViewHolder)view.getTag();
                    vh.pb.setProgress(progress);
                }
            }
        }
         
    }

    布局:

    整个项目的源代码:https://github.com/nuptboyzhb/ListViewPartRefreash

    效果为:

    /

  • 相关阅读:
    插入排序(二)
    选择排序(一)
    (转)示例化讲解RIP路由更新机制
    Css元素居中设置
    (转)盒子概念和DiV布局
    (转)浅析CSS——元素重叠及position定位的z-index顺序
    (转)Java中的static关键字解析
    (转)字符串循环移位
    linux把某个文件拷贝到不同的目录下面
    linux中查找文件并合并文件
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/5662651.html
Copyright © 2020-2023  润新知