web-dev-qa-db-ja.com

Android画面に読み込みオーバーレイを表示する

アプリがサーバーへのログインを試行している間、画面上に小さな読み込みティッカーまたは場合によってはテキストを表示するオーバーレイを表示しようとしています。私のログイン画面は、すべて縦長の線形レイアウト内にあります。

私が達成しようとしている効果は次のようなものです: http://docs.xamarin.com/recipes/ios/standard_controls/popovers/display_a_loading_message

43
James Monger

遅すぎるかもしれませんが、誰かが役に立つと思うかもしれません。

アクティビティ:

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;
        }
    }

}

レイアウト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>
94
Kostya Buts

Kostya But's answer のアプローチが好きです。

その上に、アプリ全体で同じオーバーレイを簡単に再利用可能にするためのアイデアをいくつか紹介します。

オーバーレイFrameLayoutを別のレイアウトファイルに配置することを検討してください。 _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>
_

(オーバーレイFrameLayoutで追加したものの1つは_Android:clickable="true"_です。そのため、オーバーレイが表示されている間、クリックがその下のUI要素に移動するのを防ぎます。

次に、必要に応じてそれを含めます。

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

コード内:

_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); 
_

Utilメソッドに抽出されたアニメーションコードの場合:

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

(ここでは、AlphaAnimationの代わりにAPI 12に追加されたview.animate()を使用します。)

58
Jonik

相対レイアウトにProgressBarがあり、それぞれ非表示または表示します。そして、はいアクティビティは透過的です。

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

ProgressDialogを使用して、アプリケーション上のメッセージを含むスピナーを作成できます。写真のように正確な効果は得られませんが、アプリが機能していることを示すには良い方法です。

3
James Monger

私は同じ質問をしました、私は解決策を試しましたが、最高のUIではなかったので、次の手順を実行しました。

  1. 画面を2つのビューに分割します:コンテンツとプログレスバー。
  2. ProgressBarを呼び出す場合は、可視性をVISIBLEに変更し、progressBarコンテナではなくコンテンツid = contentに次のプロパティを追加します。

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