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

activity进行调用,功能操作主要封装在adapter中如下:

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

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

源码下载

android Listview,gridview局部刷新,部分刷新
上一篇:Vue学习3:计算属性computed与监听器


下一篇:android listView嵌套gridview的使用心得