ダイアログ フラグメント


2014年4月15日現在、私が理解している内容です。
間違っている場合があります。


ダイアログの出し方メモ その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で消します。













戻る