1. Introduction
For the ListView refresh mechanism in Android, most programmers are familiar with modifying or adding adapter data sources, and then calling Notifydatasetchanged () to refresh the ListView. In this mode, we will let the control display different content in GetView based on different data sources. This mode is the most common refresh mode, when we slide the ListView back and forth, call adapter's GetView method, and then the ListView will draw the view returned by the adapter. In this mode, the display content or status of the view is recorded in the data source inside the adapter, and the ListView is not updated frequently, and it is updated as the data source changes.
- Introduction of the ListView local Refresh problem:
Suppose our ListView item has a progress bar (ProgressBar) and a button, when we click the button, the progress bar will be refreshed from 0 to 100, and generally need to complete the refresh process within 1s, In other words: In any item in the ListView, after the event that triggered the button, the ProgressBar needs to be refreshed 100 times within 1s or less. Obviously, if we use a modified data source, the mechanism for calling notifydatasetchanged () to refresh is obviously inappropriate, inefficient, and not necessarily effective. Then, we naturally think when clicked, want to be able to get to the click of the inside of the view of the ProgressBar control object, and then directly call the ProgressBar setprogress on it, I thought this would be done. Suddenly, you will find that when the ProgressBar is being updated, at this point, to slide the ListView, suddenly found that the following progress bar is also updated. Careful analysis, it really makes sense, because the ListView in the view is reused, when you swipe down the ListView, you at this time the operation of the ProgressBar object, is not just clicked on the item, because a lot of item re-use a view. So how do we solve this problem?
2. Solution
Record the clicked item's position, and then during the update process, constantly judge that the position is not between the visible item, if it is, then update, no, not update.
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);}}}
Other related code:
ListAdapter
/* * $filename: LISTADAPTER.JAVA,V $ * $Date: 2014-9-19 $ * Copyright (C) Zhenghaibo, Inc. All rights reserved. * This software are 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: [Email prot Ected] *web:http://www.mobctrl.net *2014-9-19 Nanjing,njupt,china */public class ListAdapter extends BaseAdapter {PR Ivate 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 ();} @Overridepublic int GetCount () {//TODO auto-generated method Stubreturn datas.size ();} @Overridepublic Object getItem (int pos) {//TODO auto-generated method Stubreturn Datas.get (POS);} @Overridepublic long getitemid (int arg0) {//TODO auto-generated method Stubreturn 0;} @Overridepublic 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 (con Text). 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 () {@Overridepublic void OnClick (View v) {if (null! = Updatecallback) { Updatecallback.startprogress (Model,pos);}}); ViewHolder.pb.setProgress (0);//cache the Viewreturn Convertview;} public static class Viewholder {ProgressBar PB; Button btn;}}
Activity
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 * Local Refresh of ListView */@EActivity (R.layout.activity_main) public class Mainactivity extends activity Implements updatecallback{@ViewByIdListView listview;private listadapter adapter; @AfterViewsvoid 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);}} @Overridepublic void startprogress (final Model model,final int position) {/** start the Thread to update the progress*/new ThreAD (New Runnable () {@Overridepublic void Run () {for (int i = 0;i<=100;i++) {updateprogressinuithread (model, i,position) ; try {thread.sleep;} catch (Interruptedexception e) {//TODO auto-generated catch Blocke.printstacktrace ();}}}). Start ();} @UiThreadvoid 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);}}}
Layout:
<?xml version= "1.0" encoding= "Utf-8"? ><relativelayout xmlns:android= "http://schemas.android.com/apk/res/ Android "Android:layout_width=" Match_parent "android:layout_height=" Match_parent "> <button android: Id= "@+id/btn" android:layout_width= "wrap_content" android:layout_height= "40DP" Android:layout_alignpa Rentleft= "true" android:layout_centervertical= "true" android:gravity= "center" android:text= "test"/&G T <progressbar android:id= "@+id/pb_show" style= "@android: Style/widget.holo.progressbar.horizontal" a Ndroid:layout_width= "Match_parent" android:layout_height= "40DP" android:layout_alignparentright= "true" Android:layout_centervertical= "true" android:layout_marginleft= "10DP" android:layout_marginright= "10DP" android:layout_torightof= "@id/btn" android:background= "@android: Color/background_light" android:max= "10 0 "android:progress="0"/></relativelayout>
Source code for the entire project: Https://github.com/nuptboyzhb/ListViewPartRefreash
The effect is:
Swipe up or down the listview anyway to refresh normally
Not permitted for commercial purposes without permission
Welcome to join QQ Group discussion: Android Development Alliance: 272209595
Partial refresh of Android:listview