LoginSignup
5
12

More than 5 years have passed since last update.

ProgressDialogが非推奨らしいので自分で作ってみた

Posted at

公式ドキュメントを見ると、Deprecated since API level 26って書いてあるので、これからアプリを作るときは使わないほうが良さげ。

でもどうしても使いたいので自分で作ってみた。

ダイアログ本体

ProgressDialog.java
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.widget.ProgressBar;
import android.widget.TextView;

public class ProgressDialog extends DialogFragment {
    private static final int DELAY_MILLISECOND = 450;
    private static final int SHOW_MIN_MILLISECOND = 300;

    private ProgressBar mProgressBar;
    private TextView mProgressMessage;
    private boolean mStartedShowing;
    private long mStartMillisecond;
    private long mStopMillisecond;

    private String mMessage;

    // required default constructor
    public ProgressDialog() {
        super();
    }

    public static ProgressDialog newInstance(String message) {
        ProgressDialog instance = new ProgressDialog();

        Bundle arguments = new Bundle();
        arguments.putString("message", message);
        instance.setArguments(arguments);

        return instance;
    }

    @NonNull
    @Override
    @SuppressLint("InflateParams")
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        mMessage = getArguments().getString("message");

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();

        builder.setView(inflater.inflate(R.layout.dialog_progress, null));
        return builder.create();
    }

    @Override
    public void onStart() {
        super.onStart();
        mProgressBar = getDialog().findViewById(R.id.progress);
        mProgressMessage = getDialog().findViewById(R.id.progress_message);
        mProgressMessage.setText(mMessage);
    }

    @Override
    public void show(final FragmentManager manager, final String tag) {
        mStartMillisecond = System.currentTimeMillis();
        mStartedShowing = false;
        mStopMillisecond = Long.MAX_VALUE;

        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (mStopMillisecond > System.currentTimeMillis()) {
                    showDialogAfterDelay(manager, tag);
                }
            }
        }, DELAY_MILLISECOND);
    }

    private void showDialogAfterDelay(FragmentManager manager, String tag) {
        mStartedShowing = true;
        super.show(manager, tag);
    }

    public void cancel() {
        mStopMillisecond = System.currentTimeMillis();

        if (mStartedShowing) {
            if (mProgressBar != null) {
                cancelWhenShowing();
            } else {
                cancelWhenNotShowing();
            }
        }
    }

    private void cancelWhenShowing() {
        if (mStopMillisecond < mStartMillisecond + DELAY_MILLISECOND + SHOW_MIN_MILLISECOND) {
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    dismissAllowingStateLoss();
                }
            }, SHOW_MIN_MILLISECOND);
        } else {
            dismissAllowingStateLoss();
        }
    }

    private void cancelWhenNotShowing() {
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                dismissAllowingStateLoss();
            }
        }, SHOW_MIN_MILLISECOND);
    }

    public void setMessage(String message) {
        if (mProgressMessage == null) {
            mProgressMessage = getDialog().findViewById(R.id.progress_message);
        }
        mProgressMessage.setText(message);
    }
}

ダイアログのレイアウト

dialog_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/progress"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="16dp" />

    <TextView
        android:id="@+id/progress_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        app:layout_constraintBottom_toBottomOf="@+id/progress"
        app:layout_constraintLeft_toRightOf="@+id/progress"
        app:layout_constraintTop_toTopOf="@+id/progress"
        app:layout_constraintVertical_bias="0.507" />
</android.support.constraint.ConstraintLayout>

使い方

呼び出し方

ProgressDialog progressDialog = ProgressDialog.newInstance("表示するメッセージ");
progressDialog.show(getSupportFragmentManager(), "Tag");

progressDialog.dismiss();

何段階かある処理で今何をやってるのか都度変更する

MainActivity
public class MainActivity extends AppCompatActivity {
    private Button mButton;
    private ProgressDialog mProgressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                doStepOne();
            }
        });
    }

    private void doStepOne() {
        // 最初のメッセージだけはsetMessage()でセットできない。
        // getDialogしてもnullになる。LifeCycleとやらを理解しないと駄目そう
        mProgressDialog = ProgressDialog.newInstance("Step one ...");
        mProgressDialog.show(getSupportFragmentManager(), "tag");

        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... aVoid) {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                doStepTwo();
            }
        }.execute();
    }

    private void doStepTwo() {
        // 一度表示されてしまえばsetMessage()で表示が変えられる
        mProgressDialog.setMessage("Step two ...");
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... aVoid) {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                doFinish();
            }
        }.execute();
    }

    private void doFinish() {
        mProgressDialog.dismiss();
    }
}
5
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
12