Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visibility of ProgressBar

I need to process some data when the user click the button in one activity, so the screen looks like the app stops for 2-3 seconds. It isn't a lot but I want to give the user information that everything is ok and IMO the best way will be the progressbar which is visible only when data are processed.

I found the code of ProgressBar and it looks like this:

    <ProgressBar
    android:id="@+id/loadingdata_progress"
    style="?android:attr/progressBarStyle"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_alignBottom="@+id/fin2_note"
    android:layout_centerHorizontal="true"
    android:indeterminate="true"
    android:visibility="invisible" />

and inserted it on the middle of my layout.

And to try if the progressbar works, I put this code

loadingimage= (ProgressBar) findViewById(R.id.loadingdata_progress); loadingimage.setVisibility(View.VISIBLE);

into onCreate method and everything looks fine. Then I recreated the code to show this progressbar only if the data is processed.

After click the user invoke this method

   public void fin2_clickOnFinalization(View v)
   {    

            loadingimage= (ProgressBar) findViewById(R.id.loadingdata_progress);
    loadingimage.setVisibility(View.VISIBLE);

          // code where data is processing
            loadingimage.setVisibility(View.INVISIBLE);
       }

and nothing appear on the screen. I don't know where is the mistake. If I found the progress bar by id, It's strange for me that I can control it in onCreate method but in onclick method it's out of my control.

like image 793
MyWay Avatar asked Sep 25 '13 12:09

MyWay


3 Answers

Your UI thread cannot show progress bar cause it is busy due to your data processing. Try to use this kind of code :

public void fin2_clickOnFinalization(View v) {

    new YourAsyncTask().execute();
}

private class YourAsyncTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... args) {
        // code where data is processing
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {         
        loadingimage.setVisibility(View.INVISIBLE);
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        loadingimage.setVisibility(View.VISIBLE);
    }
}

EDIT:

AsyncTask let you run code in separate thread and make app more responsive, just put time-consuming code inside doInBackground.

like image 144
sswierczek Avatar answered Oct 22 '22 16:10

sswierczek


You're not giving the UI time to refresh. Your "data processing" code is running on the UI thread, blocking any visible changes. By the time the system gets control to refresh the display, you've already set it back to invisible.

To fix this, move your processing code to a separate thread or AsyncTask. Then you can set the progress bar to visible, start the task, and have it turn itself invisible once it's done.

I'd recommend AsyncTask for this purpose about 90% of the time on Android, since it comes stock with useful callbacks. The developer guide for it(in the Javadoc linked above) is pretty explicit, and outlines all the steps you need to take.

like image 4
Geobits Avatar answered Oct 22 '22 17:10

Geobits


AsyncTask is too heavily-weighted for such task.

A better much solution

Handler handler = new Handler(getMainLooper());
handler.post(new Runnable() {
    @Override
    public void run() {
        loadingimage.setVisibility(View.VISIBLE);
    }
});

Or even simpler (does essentially the same thing as solution above)

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        loadingimage.setVisibility(View.VISIBLE);
    }
});
like image 4
kevin Avatar answered Oct 22 '22 17:10

kevin