Display a loading overlay on Android screen Display a loading overlay on Android screen android android

Display a loading overlay on Android screen


Maybe too late, but I guess somebody might find it useful.

Activity:

public class MainActivity extends Activity implements View.OnClickListener {    String myLog = "myLog";    AlphaAnimation inAnimation;    AlphaAnimation outAnimation;    FrameLayout progressBarHolder;    Button button;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button = (Button) findViewById(R.id.button);        progressBarHolder = (FrameLayout) findViewById(R.id.progressBarHolder);        button.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.button:                new MyTask().execute();                break;        }    }    private class MyTask extends AsyncTask <Void, Void, Void> {        @Override        protected void onPreExecute() {            super.onPreExecute();            button.setEnabled(false);            inAnimation = new AlphaAnimation(0f, 1f);            inAnimation.setDuration(200);            progressBarHolder.setAnimation(inAnimation);            progressBarHolder.setVisibility(View.VISIBLE);        }        @Override        protected void onPostExecute(Void aVoid) {            super.onPostExecute(aVoid);            outAnimation = new AlphaAnimation(1f, 0f);            outAnimation.setDuration(200);            progressBarHolder.setAnimation(outAnimation);            progressBarHolder.setVisibility(View.GONE);            button.setEnabled(true);        }        @Override        protected Void doInBackground(Void... params) {            try {                for (int i = 0; i < 5; i++) {                    Log.d(myLog, "Emulating some task.. Step " + i);                    TimeUnit.SECONDS.sleep(1);                }            } catch (InterruptedException e) {                e.printStackTrace();            }            return null;        }    }}

Layout xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Start doing stuff"        android:id="@+id/button"        android:layout_below="@+id/textView"        android:layout_centerHorizontal="true" />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textAppearance="?android:attr/textAppearanceLarge"        android:text="Do Some Stuff"        android:id="@+id/textView"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true" />    <FrameLayout        android:id="@+id/progressBarHolder"        android:animateLayoutChanges="true"        android:visibility="gone"        android:alpha="0.4"        android:background="#000000"        android:layout_width="match_parent"        android:layout_height="match_parent">        <ProgressBar            style="?android:attr/progressBarStyleLarge"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:indeterminate="true"            android:layout_gravity="center" />    </FrameLayout></RelativeLayout>


I like the approach in Kostya But's answer.

Building on that, here's a couple of ideas to make the same overlay easily reusable across your app:

Consider putting the overlay FrameLayout in a separate layout file, e.g. res/layout/include_progress_overlay:

<FrameLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/progress_overlay"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:alpha="0.4"    android:animateLayoutChanges="true"    android:background="@android:color/black"    android:clickable="true"    android:visibility="gone">    <ProgressBar        style="?android:attr/progressBarStyleLarge"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:indeterminate="true"/></FrameLayout>

(One thing I added in the overlay FrameLayout is android:clickable="true". So while the overlay is shown, it prevents clicks going through to UI elements underneath it. At least in my typical use cases this is what I want.)

Then include it where needed:

<!-- Progress bar overlay; shown while login is in progress --><include layout="@layout/include_progress_overlay"/>

And in code:

View progressOverlay;[...]progressOverlay = findViewById(R.id.progress_overlay);[...]// Show progress overlay (with animation): AndroidUtils.animateView(progressOverlay, View.VISIBLE, 0.4f, 200);[...]// Hide it (with animation): AndroidUtils.animateView(progressOverlay, View.GONE, 0, 200); 

With animation code extracted into a util method:

/** * @param view         View to animate * @param toVisibility Visibility at the end of animation * @param toAlpha      Alpha at the end of animation * @param duration     Animation duration in ms */public static void animateView(final View view, final int toVisibility, float toAlpha, int duration) {    boolean show = toVisibility == View.VISIBLE;    if (show) {        view.setAlpha(0);    }    view.setVisibility(View.VISIBLE);    view.animate()            .setDuration(duration)            .alpha(show ? toAlpha : 0)            .setListener(new AnimatorListenerAdapter() {        @Override        public void onAnimationEnd(Animator animation) {            view.setVisibility(toVisibility);        }    });}

(Here using view.animate(), added in API 12, instead of AlphaAnimation.)


I have ProgressBar in Relative Layout and I hide or show it respectively. And yes activity can be transparent.

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <LinearLayout        android:id="@+id/hsvBackgroundContainer"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_alignParentLeft="true"        android:layout_alignParentTop="true"    </LinearLayout>    <ProgressBar        android:id="@+id/pbProgess"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true" /></RelativeLayout>