android Listview,gridview區域性重新整理,部分重新整理

yangxi_001發表於2016-03-18

眾所周知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功能相似,只是顯示方式不同,原理一樣,需要的同學可以自己修改一下試試

原始碼下載

相關文章