【问题标题】:Android: How to show progressbar on each imageview in griidview while sending multipal images to serverAndroid:如何在向服务器发送多个图像时在gridview中的每个图像视图上显示进度条
【发布时间】:2016-06-24 07:22:24
【问题描述】:

嗨,我在为我的问题搜索解决方案时感到沮丧。我的问题是我有一个 gridview 来显示我从图库中选择的所有图像。我想在 gridview 中的每个图像上显示进度条。同时使用上传图像到服务器多部分我也想更新进度条..

我在每个图像视图上都显示了进度条,但我无法在每个进度条上显示进度。

所以请帮助我展示如何在每个图像视图上显示进度条及其各自的过程。

提前致谢

【问题讨论】:

  • 考虑在 AsyncTask 中使用上传部分,并使用 onProgressUpdate() 方法了解您的进程进度。

标签: android


【解决方案1】:

为观察者创建接口:

interface ProgressListener {
  void onProgressUpdate(String imagePath, int progress);
}

让视图持有者实现那个观察者并知道图像路径:

public class ViewHolder implements ProgressListener {
   ImageView imgQueue;
   ProgressBar pb;
   TextView tv;
   String imagePath; //set this in getView!

   void onProgressUpdate(String imagePath, int progress) {
       if (!this.imagePath.equals(imagePath)) {
          //was not for this view
          return;
       }

       pb.post(new Runnable() {
         pb.setProgress(progress);
       });
   }

   //your other code
}

适配器应保存特定图像路径/uri 的观察者地图,并具有由上传/下载任务调用的方法。还要添加方法来添加和删除观察者:

public class SelectedAdapter_Test extends BaseAdapter {
  private Map<String, ProgressListener> mProgressListener = new HashMap<>();

 //your other code

 synchronized void addProgressObserver(String imagePath, ProgressListener listener) {
    this.mListener.put(imagePath, listener);
 }

 synchronized void removeProgressObserver(String imagePath) {
   this.mListener.remove(imagePath);
 }

 synchronized void updateProgress(String imagePath, int progress) {
   ProgressListener l = this.mListener.get(imagePath);
   if (l != null) {
     l.onProgressUpdate(imagePath, progress);
   }
 }

 //other code
}

在适配器的getView中将视图持有者注册为观察者:

public View getView(final int i, View convertView, ViewGroup viewGroup) {
  //other code

  holder.imagePath = data.get(i).getSdcardPath();

  this.addProgressObserver(holder.imagePath, holder);

  return convertView;
}

现在的问题是,我们注册了观察者但没有取消注册。所以让适配器实现View.addOnAttachStateChangeListener:

public class SelectedAdapter_Test extends BaseAdapter implements View.addOnAttachStateChangeListener {
  //other code
  void onViewAttachedToWindow(View v) {
    //We ignore this
  }

  void onViewDetachedFromWindow(View v) {
    //View is not visible anymore unregister observer
    ViewHolder holder = (ViewHolder) v.getTag();
    this.removeProgressObserver(holder.imagePath);
  }

  //other code
}

在您返回视图时注册该观察者。

public View getView(final int i, View convertView, ViewGroup viewGroup) {
  //other code

  convertView.addOnAttachStateChangeListener(this);

  return convertView;
}

你终于可以告诉视图进度了:

@Override
public void transferred(long num) {
   int progress = (int) ((num / (float) totalSize) * 100);
   selectedAdapter.onProgressUpdate(listOfPhotos.get(i).getSdcardPath(), progress);
}

最后一个问题仍然存在,如果在上传过程中活动消失了怎么办?您需要检查活动是否仍然存在。也许在 onCreate 中将适配器中的标志设置为 true 并在 onDestroy 中设置为 false 就可以了。然后最后一个代码片段可以检查该标志并且不再通知适配器更改。

所以这基本上就是如何解决这个问题的想法。它有效吗?我不知道我是从头开始写的,没有经过任何测试。即使是这样,当进度为 0 或 100 时,您仍然必须管理状态。但我把它留给您。此外,您可能希望更改 RecyclerView 的 BaseAdapter,以便我们可以摆脱 View.addOnAttachStateChangeListener。

【讨论】:

  • 先生如何在回收站视图中执行该功能您有任何参考
  • 如果更好,我会使用它
  • RecyclerView 的使用方法有很多很好的例子,这里不再赘述。关于所示实现的唯一变化是,您不需要实现 View.addOnAttachStateChangeListener,因为 RecyclerView.Adapter 已经具有上述方法。
  • 先生,您有这种类型的示例教程吗?或者您有此示例的示例代码吗?然后发送链接或通过我的电子邮件发送。我正在等待您的回复
  • 或者您可以提供此类示例的参考链接
【解决方案2】:
  • 在适配器类中添加布尔值
    public SelectedAdapter_Test(Context c, ArrayList<CustomGallery> data, boolean showProgress) {
         mContext = c;
         inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         this.data = data;
         this.showProgress = showProgress;
    }
  • 适配器类 getView 的变化
        holder.pb = (ProgressBar) convertView.findViewById(R.id.progressbar);
        if (showProgress)
            holder.pb.setVisibility(View.VISIBLE);
        else
            holder.pb.setVisibility(View.GONE);
  • 更改doFileUpload
private void doFileUpload(View v) {
View vi = v;
for (i = 0; i < listOfPhotos.size(); i++) {
          <--your task-->           
     }
 //**important**
 SelectedAdapter_Test mTest = new SelectedAdapter_Test(context,data,false);
 // set above adapter object respectively;
  mList.setadapter(mTest);
}

仅供参考。设置适配器时,首次将 showProgress 值传递为 true。

【讨论】:

  • 还有一件事,它不会隐藏/显示一个图像视图
  • @unknownapk 因为你必须使用 AsyncTask 而不是简单的线程。 try this
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多