对于ListView数据的刷新大家都知道,改变Adapter的数据源,然后调用Adapter的notifyDateSetChanged()方法即可。通过本篇文章给大家详细介绍Android开发之ListView实现Item局部刷新,感兴趣的朋友一起学习吧
对于android中的ListView刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifyDataSetChanged()刷新ListView。在这种模式下,我们会在getView中,根据不同的数据源,让控件显示不同的内容。这种模式是最常见的刷新模式,当我们来回滑动ListView的时候,调用adapter的getView方法,然后listview对adapter返回的View进行绘制。这种模式下,View的显示内容或状态都记录在adapter里面的数据源中,listview的更新频率不频繁,它随着数据源的变化而更新。
但是武林网小编在做公司项目的时候,有个下载模块,因为可能同时下载好几个数据,所以用的listview展示所有正在下载的内容。因为下载进度要实时更新,所以要不停的调用notifyDateSetChanged刷新数据。这样会不停的重新绘制整个listview的界面,性能开销非常大。而且如果每个item有图片的话,每个item的图片都需要重新加载,就算图片做了内存缓存,刷新一下图片也会闪一下,不停的刷新就会导致各个item的图片不停的闪,体验一点都不好。
那么对于上面问题,有没有解决办法呢?当然是有的。我们可以针对某一个item进行局部更新,而不影响其它没有修改的item。那么具体如何实现的呢?我们看下面的代码。
- private void updateView(int itemIndex) {
- //得到第一个可显示控件的位置,
- int visiblePosition = mListView.getFirstVisiblePosition();
- //只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新
- if (itemIndex - visiblePosition >= ) {
- //得到要更新的item的view
- View view = mListView.getChildAt(itemIndex - visiblePosition);
- //调用adapter更新界面
- mAdapter.updateView(view, itemIndex);
- }
- }
这个函数主要是根据传入的itemIndex来获取第itemIndex的数据所显示的view。itemIndex就是要修改的数据再List集合中的位置,比如我这里下载进度有更新,发了一个广播这里接收到了,需要修改该下载内容的进度条,广播接收器可以这么写:
- @Override
- public void onReceive(Context context, Intent intent) {
- AppContent appContent = intent.getParcelableExtra("appContent");
- if(appContent == null) return;
- int itemIndex = ;
- for(AppContent appContent : mList) {
- if(appContent.getUrl().equals(appContent.getUrl())) {
- itemIndex = mList.indexOf(appContent);
- appContent.setDownloadPercent(appContent.getDownloadPercent());
- break;
- }
- }
- updateView(itemIndex);
- }
下面看Adapter的具体代码:
- public class AppContentAdapter extends BaseAdapter{
- private List<AppContent> mDates = null;
- private Context mContext;
- public AppContentAdapter(Context context) {
- 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;
- }
- /**
- * 设置viewHolder的数据
- * @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("下载进度:" + appContent.getDownloadPercent() + "%");
- }
- }
- /**
- * 局部刷新
- * @param view
- * @param itemIndex
- */
- public void updateView(View view, int itemIndex) {
- if(view == null) {
- return;
- }
- //从view中取得holder
- 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);
- }
- /**
- * 根据状态设置图标
- * @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;
- }
- }
以上内容是关于Android开发之ListView实现Item局部刷新的全部内容,希望对大家有用,更多有关listview局部刷新问题,请登录武林网官网查询,谢谢!
新闻热点
疑难解答