Search code examples
androidprogress-barandroid-asynctasknine-patch

Custom ProgressBar won't update. (AsyncTask + 9patch)


Firs of all thanks for reading this. I'm having trouble updating the progress from my custom ProgressBar through an AsyncTask inner class. I'm using 9patch for the background and progress drawables. It just don't update. It stays there all filled like it was in the maxed value, I'm using the onProgressUpdate() to call the invalidate() and update the UI thread.

Here's what it looks like now, it goes visible and just stays there all filled up: http://imageshack.us/photo/my-images/651/mobicashprogressbar.png/

  • The progressbar should only be visible after the user concludes the form.
  • There's another inner AsyncTask handling the send SMS button that connects with an Web Service.

HERES THE CODE:

public void setTimerProgress(int progress){
    progressBar.setProgress(progress);
}

public void updateProgress(){
    progressBar.invalidate();
}

public void showProgress(){
    progressBar.setVisibility(View.VISIBLE);
}

//Classe auxiliar para controle da progress bar
private class TimerProgress extends AsyncTask<Void, Void, Void>{

    private int start;
    private final int OTP_TIMEOUT = 900000;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        showProgress();
        start = (int) System.currentTimeMillis();
    }

    @Override
    protected Void doInBackground(Void... param) {

        int timer = (int) System.currentTimeMillis() - start;

        while (timer <= OTP_TIMEOUT){
            setTimerProgress(timer);
            timer = (int) System.currentTimeMillis() - start;
            publishProgress();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        updateProgress();
    }
}

HERE'S XML:

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_gravity="center_horizontal"
        android:visibility="invisible"
        android:id="@+id/progress_bar_timer"
        android:max="900000"
        android:progress="3000"
        android:progressDrawable="@drawable/progress_bar"
        android:background="@drawable/progress_background"
        android:layout_width="fill_parent"
        android:layout_height="25dip"
        android:layout_marginRight="73sp"
        android:layout_marginLeft="70sp">
    </ProgressBar>

HERE'S ONE PLACE WHERE I CALL IT

@Override
public void onClick(View v) {
    if (v.getId() == R.id.refresh_otp) {
        saveParametersForOTP();
        if (edtIniPin.getText().length() == pinLengthInt) {
            try {
                disableEditText(edtIniPin);
                disableEditText(edtValue);
                edtOTP.setText(Facade.getInstance().nextOTP(Facade.getInstance().getPin(), Facade.getInstance().getValue()));
                //Inicia o timer da progressbar
                new TimerProgress().execute();

Help? :D

UPDATE:

For test purpuses I've set the OTP_TIMEOUT to 50000, made the following changes to the code and removed the 9patch drawables properties so it would use the native drawables for the bar. It works, however, when I use the images to customize the bar it appears the same old problem is happening. It is static, all filled up like before.

            private final int OTP_TIMEOUT = 50000;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.i("PROGRESS", "Chegou no PreExecute!");
        showProgress();
        ENABLE_REFRESH = false;
        start = (int) System.currentTimeMillis();
    }

    @Override
    protected Void doInBackground(Void... param) {

        int timer = (int) System.currentTimeMillis() - start;

        while (timer <= OTP_TIMEOUT){
            Log.i("PROGRESS", "Chegou no while!");
            setTimerProgress((int)timer);
            timer = (int) System.currentTimeMillis() - start;
            publishProgress();
            if (timer >= OTP_TIMEOUT) {
                ENABLE_REFRESH = true;
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        Log.i("PROGRESS", "Chegou no Progress Update!");
        updateProgress();
    }

Solution

  • You need to add a layer-list resource and configure your ProgressBar to use it.

    Here an example that I use. Note that in progress_bar.xml progress_bar_progress and progress_bar_background are nine-patch images.

    progress_bar.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@android:id/background" android:drawable="@drawable/progress_bar_background" />
        <item android:id="@android:id/progress" >
            <clip android:drawable="@drawable/progress_bar_progress" />
        </item>
    </layer-list>list>
    

    layout snippet:

    <ProgressBar 
        android:layout_width="fill_parent"
        android:layout_height="30dp"
        android:max="100"
        android:progress="50"
        android:progressDrawable="@drawable/progress_bar"
        android:indeterminateOnly="false" />