对话框进度设置

9
我有一个异步任务,执行时进度条没有显示百分比。它一直停留在0% 0/100。
以下是我的代码:
     private class getAppInfo extends AsyncTask<String, String, String> {
    /** The system calls this to perform work in a worker thread and
      * delivers it the parameters given to AsyncTask.execute() */
    ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        if(showLoading == true){
             dialog = new ProgressDialog(SelfHelp.this);
             dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
             dialog.setMessage("Loading");
             dialog.setIndeterminate(true);
             dialog.setCancelable(false);   
             dialog.setMax(100);
             dialog.setProgress(100);
             dialog.show();
        }
    }

    @Override
    protected String doInBackground(String... urls) {                       
        String xml = null;
        int count = 0;
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(urls[0]);

            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            xml = EntityUtils.toString(httpEntity);

            while(count != 100){
                publishProgress(""+count);
                count += 5;
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }                                

        Document doc = parser.GetDomElement(xml);
        NodeList nl = doc.getElementsByTagName("topic");
        getChildElements(nl);                           
        return xml;
    }


    @Override
    protected void onProgressUpdate(String... progress) {
        Log.v("count",progress[0]);
        dialog.setProgress(Integer.parseInt(progress[0]));
   }

    /** The system calls this to perform work in the UI thread and delivers
      * the result from doInBackground() */
    @Override
    protected void onPostExecute(String result) {    
        //dialog.setProgress(100);
        menuList.setAdapter(setListItems(menuItems));
        menuList.setTextFilterEnabled(true);
        if(showLoading == true){
            dialog.dismiss();
            showLoading = false;
        }
    }

它确实进入了 onProgressUpdate,计数器增加了5,但进度条没有改变。我该如何使其增加5并正确显示进度?

3个回答

26
你的问题与setIndeterminate(true)有关: 如果你想获得进度更新,应将其设置为false。如果你使用了setIndeterminate(true),则ProgressDialog将像传统Windows沙漏一样工作。

那个建议没有改变任何事情。它仍然停留在0%。 - BigT
将 dialog.setProgress(100); 改为 0。 - Blackbelt
在preExecute中将进度设置为0仍然没有起作用。 - BigT
dialog.setIndeterminate(true); 设置为false - Blackbelt
1
搞定了。setIndeterminate 函数弄乱了它。谢谢。 那个函数到底是干什么用的? - BigT
1
不确定进度对话框类似于Windows沙漏。我会更新我的答案。请将答案标记为已接受。 - Blackbelt

3
您可以尝试以下代码,它会以百分比显示进度。这是代码:
public class ProgressBarExampleActivity extends Activity 
{
    ProgressThread progThread;
    ProgressDialog progDialog;
    Button button1, button2;
    int typeBar;                     // Determines type progress bar: 0 = spinner, 1 = horizontal
    int delay = 1000;                  // Milliseconds of delay in the update loop
    int maxBarValue = 30;           // Maximum value of horizontal progress bar

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

//      // Process button to start spinner progress dialog with anonymous inner class
//      button1 = (Button) findViewById(R.id.Button01);
//      button1.setOnClickListener(new OnClickListener()
//      {
//          public void onClick(View v) 
//          {
//              typeBar = 0;
//              showDialog(typeBar);
//          }
//      }); 

        // Process button to start horizontal progress bar dialog with anonymous inner class
        button2 = (Button) findViewById(R.id.Button02);
        button2.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v) 
            {
                typeBar = 1;
                showDialog(typeBar);
            }
        }); 
    }

    // Method to create a progress bar dialog of either spinner or horizontal type
    @Override
    protected Dialog onCreateDialog(int id) 
    {
        switch(id) 
        {
//      case 0:                      // Spinner
//          progDialog = new ProgressDialog(this);
//          progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
//          progDialog.setMessage("Loading...");
//          progThread = new ProgressThread(handler);
//          progThread.start();
//          return progDialog;
        case 1:                      // Horizontal
            progDialog = new ProgressDialog(this);
            progDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progDialog.setMax(maxBarValue);
            progDialog.setMessage("Dollars in checking account:");
            progThread = new ProgressThread(handler);
            progThread.start();
            return progDialog;
        default:
            return null;
        }
    }

    // Handler on the main (UI) thread that will receive messages from the 
    // second thread and update the progress.

    final Handler handler = new Handler() 
    {
        public void handleMessage(Message msg) 
        {
            // Get the current value of the variable total from the message data
            // and update the progress bar.
            int total = msg.getData().getInt("total");
            progDialog.setProgress(total);
//          if (total >= maxBarValue)
            if (total <= 0 )            
            {
                dismissDialog(typeBar);
                progThread.setState(ProgressThread.DONE);
            }
        }
    };

    // Inner class that performs progress calculations on a second thread.  Implement
    // the thread by subclassing Thread and overriding its run() method.  Also provide
    // a setState(state) method to stop the thread gracefully.

    private class ProgressThread extends Thread 
    {   
        // Class constants defining state of the thread
        final static int DONE = 0;
        final static int RUNNING = 1;

        Handler mHandler;
        int mState;
        int total;

        // Constructor with an argument that specifies Handler on main thread
        // to which messages will be sent by this thread.

        ProgressThread(Handler h) 
        {
            mHandler = h;
        }

        // Override the run() method that will be invoked automatically when 
        // the Thread starts.  Do the work required to update the progress bar on this
        // thread but send a message to the Handler on the main UI thread to actually
        // change the visual representation of the progress. In this example we count
        // the index total down to zero, so the horizontal progress bar will start full and
        // count down.

        @Override
        public void run() 
        {
            mState = RUNNING;   
            total = maxBarValue;
            while (mState == RUNNING) 
            {
                // The method Thread.sleep throws an InterruptedException if Thread.interrupt() 
                // were to be issued while thread is sleeping; the exception must be caught.
                try 
                {
                    // Control speed of update (but precision of delay not guaranteed)
                    Thread.sleep(delay);
                } catch (InterruptedException e) {
                    Log.e("ERROR", "Thread was Interrupted");
                }

                // Send message (with current value of  total as data) to Handler on UI thread
                // so that it can update the progress bar.

                Message msg = mHandler.obtainMessage();
                Bundle b = new Bundle();
                b.putInt("total", total);
                msg.setData(b);
                mHandler.sendMessage(msg);

                total--;    // Count down
            }
        }

        // Set current state of thread (use state=ProgressThread.DONE to stop thread)
        public void setState(int state) 
        {
            mState = state;
        }
    }
}

看一下输出结果, 输入图像描述

1

我会提及另一种方法,因为当我正在寻找一些实际的方法来从我的运行AsyncTask的服务返回到主UI时,我遇到了这个解决方案。Lucifer的解决方案对于服务来说不是模块化的,如果您需要在多个类中使用您的服务(这是我的情况),您将无法访问变量处理程序,据我所知,您甚至不能将Handler作为Intent发送到服务(但可以将其发送到AsyncTask)。解决方案是广播。

sendBroadcast(new Intent(WORK_DONE));

在 AsyncTask 中

private BroadcastReceiver receiver = new BroadcastReceiver() {
    public void onReceive(Context c, Intent i) { //update your UI here }
}

registerReceiver(receiver, new IntentFilter(WORK_DONE));

在你的活动中。
我不喜欢安卓开发者使用的所有内部类。我知道创建内部类并访问外部类变量更容易,但一旦你需要再次使用该类,你就会陷入困境,必须编辑代码!我对Android非常陌生,也许我错了,实际上你不需要重用这些类。我从未做过更大的项目,所以我不知道,但感觉不对,因为在学院里,他们努力教我们如何编写可重用的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接