AsyncTaskの使用方法を解説した前回の記事に続き、今回は、ログインボタン押下時に表示される著名的な「ローディング中」の UI 作为一种の実装方法を紹介します。ユーザーがログイン情報を入力した後、ボタンをタップすると、一時的な待機ダイアログが表示され、処理が完了するまでユーザーにフィードバックを与えます。
以下にこの機能を簡易的に実装する方法を示します。
1. レイアウト定義 (activity_main.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"
android:padding="16dp"
tools:context=".MainActivity" >
<TextView
android:id="@+id/tvEmailLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="メールアドレス" />
<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tvEmailLabel"
android:layout_alignBaseline="@id/tvEmailLabel"
android:inputType="textEmailAddress" />
<TextView
android:id="@+id/tvPasswordLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/etEmail"
android:layout_marginTop="24dp"
android:text="パスワード" />
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tvPasswordLabel"
android:layout_alignBaseline="@id/tvPasswordLabel"
android:inputType="textPassword" />
<Button
android:id="@+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/etPassword"
android:layout_marginTop="32dp"
android:text="ログイン" />
<Button
android:id="@+id/btnRegister"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/btnLogin"
android:layout_alignTop="@id/btnLogin"
android:layout_marginLeft="24dp"
android:text="登録" />
</RelativeLayout>
2. Activity 実装
ボタンクリック時に入力値を取得し、AsyncTask を起動して非同期処理を実行。処理前にProgressDialogを表示し、完了時に閉じて結果を通知します。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText mEmailInput;
private EditText mPasswordInput;
private Button mLoginButton;
private Button mRegisterButton;
private String email;
private String password;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
mEmailInput = findViewById(R.id.etEmail);
mPasswordInput = findViewById(R.id.etPassword);
mLoginButton = findViewById(R.id.btnLogin);
mRegisterButton = findViewById(R.id.btnRegister);
mLoginButton.setOnClickListener(this);
mRegisterButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
int id = view.getId();
if (id == R.id.btnLogin) {
email = mEmailInput.getText().toString().trim();
password = mPasswordInput.getText().toString().trim();
new LoginTask().execute();
} else if (id == R.id.btnRegister) {
Toast.makeText(this, "登録画面へ遷移中…", Toast.LENGTH_SHORT).show();
}
}
private class LoginTask extends AsyncTask {
private ProgressDialog loader;
@Override
protected void onPreExecute() {
super.onPreExecute();
loader = new ProgressDialog(this);
loader.setMessage("処理中です。しばらくお待ちください…");
loader.setIndeterminate(true);
loader.setCancelable(false);
loader.show();
}
@Override
protected Boolean doInBackground(Void... params) {
// モックサーバーとの通信を模倣
try {
Thread.sleep(3000);
} catch (InterruptedException ignored) {
return false;
}
return "user@example.com".equals(email) && "pass123".equals(password);
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (loader != null && loader.isShowing()) {
loader.dismiss();
}
if (result) {
Toast.makeText(MainActivity.this, "ログイン成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "ユーザー名またはパスワードが不正です", Toast.LENGTH_SHORT).show();
}
}
}
}
3. サーバー側モック(※簡易実装)
ネットワーク通信を模擬するためのクラス。実際のサーバー連携部に相当します。
public class MockAuthClient {
public boolean authenticate(String email, String password) {
// 模拟IOおよび通信遅延
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "test@test.com".equals(email) && "secret".equals(password);
}
}
※本番環境では、HTTPリクエスト送信やエラーハンドリング、 HTTPS通信などが必要であり、AndroidManifest.xml での <uses-permission android:name="android.permission.INTERNET" /> の宣言も忘れずに。