webentwicklung-frage-antwort-db.com.de

Zeigen Sie eine Ladeüberlagerung auf dem Android-Bildschirm an

Ich möchte ein Overlay über dem Bildschirm anzeigen, in dem ein wenig ladender Ticker oder möglicherweise sogar Text angezeigt wird, während meine App versucht, sich beim Server anzumelden. Mein Anmeldebildschirm befindet sich in einem vertikalen linearen Layout.

Der Effekt, den ich erreichen möchte, ist ungefähr wie folgt: http://docs.xamarin.com/recipes/ios/standard_controls/popovers/display_a_loading_message

35
James Monger

Vielleicht zu spät, aber ich denke, jemand könnte es nützlich finden.

Aktivität:

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>
76
Kostya Buts

Ich mag den Ansatz in Kostya Buts Antwort

Darauf aufbauend möchten wir Ihnen ein paar Ideen nennen, mit denen Sie die gleiche Überlagerung einfach wiederverwendbar in Ihrer App machen können:

Ziehen Sie das Overlay-FrameLayout in eine separate Layout-Datei, z. 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>

(Eine Sache, die ich im Overlay-FrameLayout hinzugefügt habe, ist Android:clickable="true". Während das Overlay angezeigt wird, verhindert es jedoch, dass Klicks auf die darunter liegenden Benutzeroberflächenelemente verlaufen. In meinen typischen Anwendungsfällen ist dies das, was ich will.)

Dann fügen Sie es bei Bedarf hinzu: 

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

Und im 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); 

Mit Animationscode, der in eine util-Methode extrahiert wurde: 

/**
 * @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);
        }
    });
}

(Hier mit view.animate(), hinzugefügt in API 12 anstelle von AlphaAnimation.)

51
Jonik

Ich habe ProgressBar im relativen Layout und verstecken bzw. zeigen es an. Und ja, Aktivität kann transparent sein.

<?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>
5
Malachiasz

Ein Spinner mit einer Nachricht über die Anwendung kann mit einem ProgressDialog erstellt werden. Obwohl es nicht genau die Wirkung erzielt, die auf dem Bild zu sehen ist, ist es eine gute Möglichkeit, zu zeigen, dass die App funktioniert.

3
James Monger

Ich hatte die gleiche Frage, ich habe die Lösungen ausprobiert, war aber nicht die beste Benutzeroberfläche, also machte ich die folgenden Schritte.

  1. Teilen Sie den Bildschirm in 2 Ansichten: Inhalt und Fortschrittsleiste.
  2. Wenn Sie die ProgressBar aufrufen möchten, ändern Sie die Sichtbarkeit in VISIBLE und fügen Sie die folgenden Eigenschaften zum content id = content und nicht zum progressBar-Container hinzu.

content.background = "# 000000" content.alpha = "0.4"

<FrameLayout 
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">

        <RelativeLayout
            Android:id="@+id/content"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:animateLayoutChanges="true"
            tools:context=".MainActivity">

            <Button
                Android:id="@+id/button"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_below="@+id/textView"
                Android:layout_centerHorizontal="true"
                Android:text="Start doing stuff" />

            <TextView
                Android:id="@+id/textView"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_alignParentTop="true"
                Android:layout_centerHorizontal="true"
                Android:text="Do Some Stuff"
                Android:textAppearance="?android:attr/textAppearanceLarge" />

        </RelativeLayout>

        <ProgressBar
            style="?android:attr/progressBarStyleLarge"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_gravity="center"
            Android:indeterminate="true"
            Android:visibility="gone" />

    </FrameLayout>
0