ダイアログの出し方メモ その1
ダイアログの出し方が、結構ややこしいので、忘れないうちにメモしておこうというコーナーです。
まずは、簡単なダイアログの出し方。
端末のメニューボタンを押すと、「Settings」メニューが出てくるので、
タップすると、ダイアログが出てきます。
ところが、端末を回転させたとき、ダイアログが消えてしまいます。
Activityが破棄されてしまうからです。
そういう仕様だと思ってましたが、閉じない方法があるということを後で知りました。
ダイアログを出すのに「show()」を使ってますが、どうやら、推奨されていないらしい。
MainActivity.java
package com.example.test06;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
My_Alt_Dialog1();
return true;
}
public void My_Alt_Dialog1(){
// ダイアログ
AlertDialog.Builder adlog = new AlertDialog.Builder( this );
adlog.setTitle( "ダイアログ" );
//レイアウトに画像
Bitmap image = BitmapFactory.decodeResource(
getResources(),R.drawable.ic_launcher);
ImageView imgvw = new ImageView(this);
imgvw.setImageBitmap(image);
imgvw.setScaleType(ImageView.ScaleType.FIT_XY);
imgvw.setAdjustViewBounds(true);
adlog.setView(imgvw);
adlog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "OK", Toast.LENGTH_SHORT ).show();
}
});
adlog.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "CANCEL", Toast.LENGTH_SHORT ).show();
}
});
adlog.show();
}
}
| |
ダイアログの出し方メモ その2
「showDialog(int id)」を使えば、端末を回転させても大丈夫ということらしいです。
IDで紐付けして、アクティビティが破棄されても、ダイアログが出るようにしてるということです。
なるほど、端末を回転させても、ダイアログは出たままですね。
MainActivity.java
package com.example.test07;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final int DIALOG_ID1 = 7;
boolean are1;
boolean sore1;
boolean kore1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
showDialog(DIALOG_ID1);
return true;
}
@Override
protected Dialog onCreateDialog(int id) {
return My_Alt_Dialog2(id);
}
private Dialog My_Alt_Dialog2(int id){
if (id == DIALOG_ID1) {
final CharSequence[] items={"あれとか","これとか","それとか"};
final boolean [] checkedItems ={are1,sore1,kore1};
AlertDialog.Builder adlog = new AlertDialog.Builder(this);
//タイトル
adlog.setTitle("セッティング");
//チェックボックス
adlog.setMultiChoiceItems(items, checkedItems,
new DialogInterface.OnMultiChoiceClickListener(){
@Override
public void onClick(DialogInterface dialog, int which,boolean isChecked) {
// TODO 自動生成されたメソッド・スタブ
//チェックされたこと
switch(which){
case 0:
break;
case 1:
break;
case 2:
break;
}
}
});
adlog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "OK", Toast.LENGTH_SHORT ).show();
}
});
adlog.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "CANCEL", Toast.LENGTH_SHORT ).show();
}
});
return adlog.create();
}
return null;
}
}
| |
ダイアログの出し方メモ その3 ダイアログフラグメント
しかし、eclipseによると、「メソッドshowDialogはActiivityで使用すべきではありません」と、注意されてしまうので、
これも、非推奨ということなのでしょう。
ならばどうするかというと、「DialogFragment」を使いましょうということらしいです。
どうやら、フラグメントからは逃げられない運命のようです。
というわけで、ダイアログフラグメントを試してみました。
端末を回転させても、ダイアログフラグメントは出たままです。
まず、ダイアログフラグメントのクラスを作る。
「extends DialogFragment」として、継承する。
サポートライブラリを使用するなら、
「import android.support.v4.app.DialogFragment;」をインポートする。
「import android.app.DialogFragment;」をインポートするとエラーになるので注意。
「getFragmentManager()」ではなく、「getSupportFragmentManager()」を使う。
DialogF1.java
package com.example.test08;
import android.support.v4.app.DialogFragment; //こちらをインポートする
//import android.app.DialogFragment; //こちらをインポートするとエラー
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.widget.Toast;
public class DialogF1 extends DialogFragment{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("ダイアログ フラグメント")
.setMessage("メッセージ")
.setPositiveButton("OK", OK_Listener)
.setNeutralButton("SKIP",SKIP_Listener)
.setNegativeButton("CANCEL", CANCEL_Listener);
return builder.create();
}
private DialogInterface.OnClickListener OK_Listener
= new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Toast.makeText(getActivity(), "OK", Toast.LENGTH_LONG).show();
}
};
private DialogInterface.OnClickListener SKIP_Listener
= new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Toast.makeText(getActivity(), "SKIP", Toast.LENGTH_LONG).show();
}
};
private DialogInterface.OnClickListener CANCEL_Listener
= new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Toast.makeText(getActivity(), "CANCEL", Toast.LENGTH_LONG).show();
}
};
}
| |
次に、MainActivityでは、「extends FragmentActivity 」として継承する。
サポートライブラリを使用するなら、
「import android.support.v4.app.FragmentActivity;」をインポートする。
「import android.support.v4.app.FragmentManager;」をインポートする。
「import android.app.FragmentManager;」をインポートするとエラーになる。
MainActivity.java
package com.example.test08;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager; //こちらをインポートする
//import android.app.FragmentManager; //こちらをインポートするとエラー
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
My_Alt_Dialog3();
return true;
}
private void My_Alt_Dialog3(){
//APIレベル4でフラグメント使用
FragmentManager fm = getSupportFragmentManager();
DialogF1 df = new DialogF1();
df.show(fm, "dialog_fragment");
}
}
| |
ダイアログの出し方メモ その4 プログレスダイアログ
ここまでのダイアログは、端末の戻るキーでダイアログを消すことができましたが、
消されると困るものに、プログレスダイアログがあります。
「setCancelable(false)」を指定することで、端末の戻るキーで、ダイアログが消えなくなります。
もちろん、端末を回転させてもプログレスダイアログは消えません。
10秒後、処理が終わった時に消えてくれます。
ProgressDialogF1.java
package com.example.test09;
import android.support.v4.app.DialogFragment; //こちらをインポートする
//import android.app.DialogFragment; //こちらをインポートするとエラー
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
public class ProgressDialogF1 extends DialogFragment{
private static ProgressDialog progressDialog = null;
//コンストラクタ
public ProgressDialogF1(){}
// インスタンス
public static ProgressDialogF1 newInstance(){
ProgressDialogF1 instance = new ProgressDialogF1();
return instance;
}
// ProgressDialog作成
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
if (progressDialog != null)
return progressDialog;
String title = getArguments().getString("title");
String message = getArguments().getString("message");
progressDialog = new ProgressDialog(getActivity());
progressDialog.setTitle(title);
progressDialog.setMessage(message);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); // スタイルを円スタイルに設定
// 戻るボタンで、プログレスダイアログのキャンセル不可
setCancelable(false);
return progressDialog;
}
// progressDialog取得
@Override
public Dialog getDialog(){
return progressDialog;
}
// ProgressDialog破棄
@Override
public void onDestroy(){
super.onDestroy();
progressDialog = null;
}
}
| |
MainActivity.java
package com.example.test09;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
My_Alt_Dialog4();
return true;
}
private void My_Alt_Dialog4(){
//APIレベル4でフラグメント使用
Bundle arguments = new Bundle();
arguments.putString("title", "処理中です");
arguments.putString("message", "しばらくお待ちください");
final ProgressDialogF1 pd;
pd = ProgressDialogF1.newInstance();
pd.setArguments(arguments);
pd.show(getSupportFragmentManager(), "progress");
//10秒後に終了
new Handler().postDelayed(new Runnable(){
public void run(){
// Dialog終了
pd.getDialog().dismiss();
}
},10000);
}
}
| |
ちなみに、
Builder#setPositiveButton()、Builder#setNeutralButton()、Builder#setNegativeButton()の場合、
ボタンを押したときに、自動的にダイアログが閉じられるようです。
ダイアログを閉じるか閉じないか、任意に制御したいときは、Buttonを作って、
Button#setOnClickListener() を使いましょう。
閉じるときは、dismiss()を使います。
「showDialog(DIALOG_ID1)」で呼び出した場合は、
「dismissDialog(DIALOG_ID1)」か、「removeDialog(DIALOG_ID1)」で消します。
dismissDialogは、表示が消えても実体は残ってるようで、showDialogをしても、onCreateDialogが呼ばれません。
ダイアログに毎回初期設定をしたい場合は、removeDialogで消します。