For ListView Data Refresh, you know, change the adapter data source, and then call the adapter notifydatesetchanged () method.
But in the company project, there is a download module, because it is possible to download several data at the same time, so use the ListView to show all the content being downloaded. Because the download progress to be updated in real time, you have to keep calling notifydatesetchanged to refresh the data. This will continue to redraw the entire ListView interface, the performance overhead is very high. And if each item has pictures, each item's picture needs to reload, even if the picture did the memory cache, refresh the picture will flash, keep the refresh will cause the picture of each item keep flashing, experience is not good.
So is there a solution to the above problem? Of course it is. We can update the item locally without affecting other item that is not modified. So how to achieve it? Let's look at the code below.
private void Updateview (int itemindex) {
To get the first position to display the control,
int visibleposition = Mlistview.getfirstvisibleposition ();
Skip updates only if the view that you want to update is updated when it is visible and is not visible
if (itemindex-visibleposition >= 0) {
Get view of item to be updated
View view = Mlistview.getchildat (itemindex-visibleposition);
Call Adapter Update interface
Madapter.updateview (view, itemindex);
}
}
This function is mainly based on the incoming itemindex to get the view that the ItemIndex data shows. ItemIndex is the data to be modified in the list of the location, such as my download progress here has been updated, sent a broadcast here received, you need to modify the content of the download progress bar, broadcast receiver can write:
@Override
public void OnReceive (context context, Intent Intent) {
Appcontent appcontent = Intent.getparcelableextra ("appcontent");
if (appcontent = null) return;
int itemindex = 0;
for (Appcontent appcontent1:mlist) {
if (Appcontent.geturl (). Equals (Appcontent1.geturl ())) {
ItemIndex = Mlist.indexof (appContent1);
Appcontent1.setdownloadpercent (Appcontent.getdownloadpercent ());
Break
}
}
Updateview (ItemIndex);
}
Here's a look at adapter's specific code:
public class Appcontentadapter extends baseadapter{
Private list<appcontent> mdates = null;
Private context Mcontext;
Public Appcontentadapter {
This.mcontext = context;
}
@Override
public int GetCount () {
return Mdates.size ();
}
@Override
Public Object getitem (int position) {
return Mdates.get (position);
}
@Override
public long getitemid (int position) {
return position;
}
public void Setdates (list<appcontent> mdates) {
This.mdates = mdates;
}
@Override
Public View GetView (int position, View Convertview, ViewGroup parent) {
Viewholder holder = null;
if (Convertview = = null) {
Holder = new Viewholder ();
Convertview = Layoutinflater.from (Mcontext). Inflate (
R.layout.listitem_download, NULL);
Holder.statusicon = (Downloadpercentview) Convertview.findviewbyid (R.id.status_icon);
Holder.name = (TextView) Convertview.findviewbyid (r.id.name);
Holder.downloadpercent = (TextView) Convertview.findviewbyid (r.id.download_percent);
Holder.progressbar = (ProgressBar) Convertview.findviewbyid (R.id.progressbar);
Convertview.settag (holder);
} else {
Holder = (viewholder) convertview.gettag ();
}
SetData (holder, position);
return convertview;
}
/**
* Set the Viewholder data
* @param Holder
* @param itemindex
*/
private void SetData (viewholder holder, int itemindex) {
Appcontent appcontent = Mdates.get (itemindex);
Holder.name.setText (Appcontent.getname ());
Holder.progressBar.setProgress (Appcontent.getdownloadpercent ());
Seticonbystatus (Holder.statusicon, Appcontent.getstatus ());
if (appcontent.getstatus () = = AppContent.Status.PENDING) {
Holder.downloadPercent.setVisibility (view.invisible);
} else {
Holder.downloadPercent.setVisibility (view.visible);
Holder.statusIcon.setProgress (Appcontent.getdownloadpercent ());
Holder.downloadPercent.setText ("Download progress:" + appcontent.getdownloadpercent () + "%");
}
}
/**
* Local Refresh
* @param view
* @param itemindex
*/
public void Updateview (view view, int itemindex) {
if (view = = null) {
Return
}
Get holder from view
Viewholder holder = (viewholder) view.gettag ();
Holder.statusicon = (Downloadpercentview) View.findviewbyid (R.id.status_icon);
Holder.name = (TextView) View.findviewbyid (r.id.name);
Holder.downloadpercent = (TextView) View.findviewbyid (r.id.download_percent);
Holder.progressbar = (ProgressBar) View.findviewbyid (R.id.progressbar);
SetData (holder, itemindex);
}
/**
* Set icon based on status
* @param Downloadpercentview
* @param status
*/
private void Seticonbystatus (Downloadpercentview downloadpercentview, Appcontent.status Status) {
Downloadpercentview.setvisibility (view.visible);
if (status = = AppContent.Status.PENDING) {
Downloadpercentview.setstatus (downloadpercentview.status_pedding);
}
if (status = = AppContent.Status.DOWNLOADING) {
Downloadpercentview.setstatus (downloadpercentview.status_downloading);
}
if (status = = AppContent.Status.WAITING) {
Downloadpercentview.setstatus (downloadpercentview.status_waiting);
}
if (status = = AppContent.Status.PAUSED) {
Downloadpercentview.setstatus (downloadpercentview.status_paused);
}
if (status = = AppContent.Status.FINISHED) {
Downloadpercentview.setstatus (downloadpercentview.status_finished);
}
}
Private class Viewholder {
Private Downloadpercentview Statusicon;
private TextView name;
Private TextView downloadpercent;
Private ProgressBar ProgressBar;
}
}
ListView Local Refresh Item implementation download progress bar local Update
When you update a task that is currently being downloaded, use the notifydatasetchanged () method to flush the entire page.
and progress updates more frequently, which caused the memory consumption and page cotton (in the process of updating very frequently), the author even appeared stuck on the page can not operate.
So I thought about whether or not to refresh a part of the item. Also looked down the data, problem solving.
Solution idea:
The Listview.getfirstvisibleposition () method gets the first position of the displayed item, and then calculates the position of the view according to position. When you get to a specific view, you can perform a partial refresh by manipulating the view.
Key code:
public void Updateview (int itemindex) {
To get the first position to display the control,
int visibleposition = Mlistview.getfirstvisibleposition ();
Skip updates only if the view that you want to update is updated when it is visible and is not visible
if (itemindex-visibleposition >= 0) {
Get view of item to be updated
View view = Mlistview.getchildat (itemindex-visibleposition);
Get holder from view
Viewholder holder = (viewholder) view.gettag ();
hashmap<string, object> item = Data.get (ItemIndex);
To get to the specific control,
Holder.name = (TextView) View.findviewbyid (r.id.name);
Holder.process = (Processbar) View.findviewbyid (r.id.process);
.......
To manipulate a control
Holder.process.setMax (Item.get ("Max"));
Holder.process.setProgress (Item.get ("Progress"));
......
}
}