android Listview,gridview局部刷新,部分刷新

众所周知Listview和Gridview的刷新界面的方式是调用adapter.notifyDataSetChanged()进行界面刷新。

但是此方法有其弊端,他是将界面中的数据全部刷新一遍,不论数据有没有变化。如果listview加载了很多的数据(如:100条)

在进行刷新时就会造成很大的系统开销如何像qq空间个人动态那样点赞只刷新一条呢:

主要原理:

对listview的某一个item进行刷新

1.要获取要刷新的item当前索引position和数据

2.对获取的数据进行重置

3.将重置的数据放到adapter中的数据集的原来的位置(根据position刷新原数据集的某一条数据)

4.在listview中获取需要刷新的子item的view

5.从更新过的数据集中获取新数据,更新viwe中的数据(handler中操作,实现界面的刷新)

功能如下,代码中有详细注释:

  1. public class MainActivity extends Activity  
  2. {  
  3.   
  4.     private ArrayList<MyListItem> list = null;  
  5.     private ListView              lv;  
  6.     private MyListAdapter         adapter;  
  7.   
  8.     @Override  
  9.     protected void onCreate(Bundle savedInstanceState)  
  10.     {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.activity_main);  
  13.         intitData();  
  14.         lv = (ListView) findViewById(R.id.listView1);  
  15.         adapter = new MyListAdapter(list, getApplicationContext());  
  16.         adapter.setListView(lv);  
  17.         lv.setAdapter(adapter);  
  18.   
  19.         lv.setOnItemClickListener(new OnItemClickListener()  
  20.         {  
  21.   
  22.             @Override  
  23.             public void onItemClick(AdapterView<?> parent, View view, int position, long id)  
  24.             {  
  25.                 // 获取listview中点击item的数据  
  26.                 MyListItem item = (MyListItem) parent.getItemAtPosition(position);  
  27.                 Log.i("eee", item.getData() + " == " + item.getPosition());  
  28.                 // 更新数据  
  29.                 item.setData("update item " + position);  
  30.                 // 更新界面  
  31.                 adapter.updateItemData(item);  
  32.             }  
  33.         });  
  34.   
  35.     }  
  36.   
  37.     /** 
  38.      * 初始化数据 
  39.      */  
  40.     private void intitData()  
  41.     {  
  42.         list = new ArrayList<MyListItem>();  
  43.         for (int i = 0; i < 20; i++)  
  44.         {  
  45.             MyListItem item = new MyListItem();  
  46.             item.setData("item " + i);  
  47.             item.setPosition(i);  
  48.             list.add(item);  
  49.         }  
  50.     }  
  51.   
  52.     /** 
  53.      * 自定义item数据类型 
  54.      */  
  55.     class MyListItem  
  56.     {  
  57.         /** 
  58.          * 数据id 
  59.          */  
  60.         private int    dataId;  
  61.         /** 
  62.          * 数据 
  63.          */  
  64.         private String data;  
  65.   
  66.         public int getPosition()  
  67.         {  
  68.             return dataId;  
  69.         }  
  70.   
  71.         public void setPosition(int position)  
  72.         {  
  73.             this.dataId = position;  
  74.         }  
  75.   
  76.         public String getData()  
  77.         {  
  78.             return data;  
  79.         }  
  80.   
  81.         public void setData(String data)  
  82.         {  
  83.             this.data = data;  
  84.         }  
  85.   
  86.     }  
  87. }  
activity进行调用,功能操作主要封装在adapter中如下:

  1. public class MyListAdapter extends BaseAdapter  
  2. {  
  3.   
  4.     /** 
  5.      * listview中的数据集 
  6.      */  
  7.     private ArrayList<MyListItem> mDataList;  
  8.   
  9.     private Context               mContext;  
  10.     private ListView              mListView;  
  11.   
  12.     public MyListAdapter(ArrayList<MyListItem> list, Context cont)  
  13.     {  
  14.         this.mDataList = list;  
  15.         this.mContext = cont;  
  16.     }  
  17.   
  18.     /** 
  19.      * 设置listview对象 
  20.      *  
  21.      * @param lisv 
  22.      */  
  23.     public void setListView(ListView lisv)  
  24.     {  
  25.         this.mListView = lisv;  
  26.     }  
  27.   
  28.     /** 
  29.      * update listview 单条数据 
  30.      *  
  31.      * @param item 新数据对象 
  32.      */  
  33.     public void updateItemData(MyListItem item)  
  34.     {  
  35.         Message msg = Message.obtain();  
  36.         int ids = -1;  
  37.         // 进行数据对比获取对应数据在list中的位置  
  38.         for (int i = 0; i < mDataList.size(); i++)  
  39.         {  
  40.             if (mDataList.get(i).getPosition() == item.getPosition())  
  41.             {  
  42.                 ids = i;  
  43.             }  
  44.         }  
  45.         msg.arg1 = ids;  
  46.         // 更新mDataList对应位置的数据  
  47.         mDataList.set(ids, item);  
  48.         // handle刷新界面  
  49.         han.sendMessage(msg);  
  50.     }  
  51.   
  52.     @SuppressLint("HandlerLeak")  
  53.     private Handler han = new Handler()  
  54.                         {  
  55.                             public void handleMessage(android.os.Message msg)  
  56.                             {  
  57.                                 updateItem(msg.arg1);  
  58.                             };  
  59.                         };  
  60.   
  61.     /** 
  62.      * 刷新指定item 
  63.      *  
  64.      * @param index item在listview中的位置 
  65.      */  
  66.     private void updateItem(int index)  
  67.     {  
  68.         if (mListView == null)  
  69.         {  
  70.             return;  
  71.         }  
  72.   
  73.         // 获取当前可以看到的item位置  
  74.         int visiblePosition = mListView.getFirstVisiblePosition();  
  75.         // 如添加headerview后 firstview就是hearderview  
  76.         // 所有索引+1 取第一个view  
  77.         // View view = listview.getChildAt(index - visiblePosition + 1);  
  78.         // 获取点击的view  
  79.         View view = mListView.getChildAt(index - visiblePosition);  
  80.         TextView txt = (TextView) view.findViewById(R.id.textView1);  
  81.         // 获取mDataList.set(ids, item);更新的数据  
  82.         MyListItem data = (MyListItem) getItem(index);  
  83.         // 重新设置界面显示数据  
  84.         txt.setText(data.getData());  
  85.     }  
  86.   
  87.     @Override  
  88.     public int getCount()  
  89.     {  
  90.         // TODO Auto-generated method stub  
  91.         return mDataList.size();  
  92.     }  
  93.   
  94.     @Override  
  95.     public Object getItem(int position)  
  96.     {  
  97.         // TODO Auto-generated method stub  
  98.         return mDataList.get(position);  
  99.     }  
  100.   
  101.     @Override  
  102.     public long getItemId(int position)  
  103.     {  
  104.         // TODO Auto-generated method stub  
  105.         return position;  
  106.     }  
  107.   
  108.     @Override  
  109.     public View getView(int position, View convertView, ViewGroup parent)  
  110.     {  
  111.         // TODO Auto-generated method stub  
  112.         if (convertView == null)  
  113.         {  
  114.             convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, null);  
  115.         }  
  116.         TextView txt = (TextView) convertView.findViewById(R.id.textView1);  
  117.         txt.setText(mDataList.get(position).getData());  
  118.         return convertView;  
  119.     }  
  120.   
  121. }  

由于listview与gridview功能相似,只是显示方式不同,原理一样,需要的同学可以自己修改一下试试

源码下载

android Listview,gridview局部刷新,部分刷新
上一篇:UWP 下拉刷新控件(PullToRefreshControl)


下一篇:业务代码的救星——Java对象转换框架MapStruct