2012-03-02 43 views
3

编辑:这是不一样的ProgressDialog doesn't show just flashesProgressDialog只给出了一个即时

我一定要使用AsyncTasks为网络通信和文件操作,表现出不确定,取消ProgressDialog直到任务完成,因为我觉得我应该适当。

在某些情况下 - 移动互联网连接速度慢,老旧的设备不足 - 这可能需要几秒钟的时间。但是完全相同的任务可能会在其他情况下或其他设备上非常迅速地完成,导致ProgressDialog仅显示一小部分时间,基本上在屏幕上闪烁。

这里最好的做法是什么?我可以想到几个选项:

  1. 保持原样,知道某些用户会产生闪烁效果。
  2. 即使任务已经完成,强制进度对话框在最小时间(半秒,一秒)内保持可见状态,但我讨厌引入人工延迟的想法。
  3. 计时任务,并且只显示ProgressDialog,如果任务花费的时间超过最小设定时间(如半秒)。问题是这不是一个真正的解决方案;如果任务在这段时间内完成,那么很棒;如果任务需要很长时间,那么很好 - 但是如果最小时间为0.5秒,而任务实际需要0.7秒,那么你又有同样的问题了......一个短暂的闪烁。
  4. 如果您可以监控任务的进度,请对其进行简短测试,并从第一小部分或第一个x百分比中估算完成任务需要多长时间;如果预计需要一段时间,则显示ProgressDialog。但是,这将是相当复杂的,并不是每个背景任务都适合这种进度评估。

什么是最佳方法?有没有我错过的选择?有没有办法设置ProgressDialog,所以它只显示是否会有明显的延迟? (我怀疑是否存在,但是如果有一些神奇的方法会很好)。这些是“标准”解决方案之一吗?

+3

没有标准的方法,你有所有正确的想法。显示你的ProgressDialog,然后在一小段延迟(例如100ms)后运行你的AsyncTask并不是一个可怕的方法。你也可以只做一个ProgressBar(即微调),一个比Dialog更小巧的UI元素。 – CSmith 2012-03-02 22:00:48

+0

我同意CSmith,我会考虑把它从dialong中拿出来,然后把它添加到某个地方的UI中。这样就不会发生震动,但在需要时它仍然存在。 – FoamyGuy 2012-03-02 22:08:31

回答

0

保持进度对话框不变,特别是对于网络操作,因为您可能在开发环境中越来越幸运,但也因为您无法控制互联网连接在真实世界中的工作速度场景。

0

由于CSmith:它的建议,我尝试添加这对我的AsyncTask做所有的后台工作:

@Override 
     protected void onCancelled() { 
      completed = true; 
      super.onCancelled(); 
      dismissProgressDialog(); //calls handler.post and dismisses dialog 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      completed = true; 
      super.onPostExecute(result); 
      dismissProgressDialog(); 
     } 
@Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 


      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        try { 
         Thread.sleep(500); 
        } catch (InterruptedException ie) { 
         return; 
        } 
        handler.post(new Runnable() { 
         @Override 
         public void run() { 
          if (!completed) { 
           progressDialog = ProgressDialog.show(activity, activity.getString(R.string.loading_title), null, true, true, new DialogInterface.OnCancelListener() { 
            @Override 
            public void onCancel(DialogInterface dialog) { 
             cancel(true); 
            } 
           }); 
          } 
         } 
        }); 

       } 
      }).start(); 
     } 

如果任务在除指定的延迟时间不完成(500毫秒,在这种情况下),对话框不显示。如果需要更长时间,则在延迟后显示。请注意,这并不能完全防止“闪烁”......例如,如果任务花费了一秒钟,那么对话框将闪烁半秒钟。

这似乎有帮助,但我并不完全满意解决方案和欢迎的建议。

2

强制ProgressDialog留下可见的时间 的最小长度(半秒,一秒)消失之前,即使任务已 已经完成 - 但我讨厌引入人工 的想法延迟。

这是一个比让进度对话框在屏幕上短暂闪烁的更好的解决方案。从用户角度来看,它引入了一致性。如果它显示了一些时间而不是其他时间,它似乎有些东西不能正常工作。

我为我的异步任务添加了一个长变量,并在预执行时将其设置为System.nanoTime()。然后在执行后,我计算了多少时间过去并将其与设定的最短时间进行比较。如果在这段时间内,我用余下的时间wait()。目前,我已将它设置为1.5秒的延迟时间,以确保在消失前有足够的时间读取进度对话框。

private final class SyncPendingOrders extends AsyncTask<String, Integer, String> { 

    long timer = 0; 

    @Override 
    protected void onPreExecute(){ 
     timer = System.nanoTime(); 

     pd = ProgressDialog.show(context,null,"Updating Pending Orders",true,false); 
     pd.setIndeterminateDrawable(context.getResources().getDrawable(R.anim.spinner)); 
    } 

    @Override 
    protected String doInBackground(String... args) { 

     updatePendingOrders(); 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String me){ 

     long clock = System.nanoTime()-timer - 2000000000; 

     if(clock > 0) 
     { 
      try{ 
       wait(clock); 
      }catch(Throwable e){ 

      } 
     } 

     PendingOrdersView(); 
     pd.dismiss(); 
    } 

} 

这样用户总是看到相同的盒子并知道程序在做什么。一致性是关键。