(恐らく)原因が分かったので少しだけ修正しました。
その代わり、実行時にエラーが発生し強制終了するようになりました
わずかな修正コード
コード:
package jp.denpa.alertdialogsample;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import android.support.v4.app.DialogFragment;
public class AlertDialogSampleActivity extends ActionBarActivity implements View.OnClickListener, DialogInterface.OnClickListener,
DialogInterface.OnMultiChoiceClickListener{
static final int DIALOG_1_ID = 0;
static final int DIALOG_2_ID = 1;
static final int DIALOG_3_ID = 2;
static final int DIALOG_4_ID = 3;
static final int DIALOG_5_ID = 4;
private static AlertDialog dialog1;
private static AlertDialog dialog2;
private static AlertDialog dialog3;
private static AlertDialog dialog4;
private static AlertDialog dialog5;
private static EditText mInputText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
findViewById(R.id.button4).setOnClickListener(this);
findViewById(R.id.button5).setOnClickListener(this);
mInputText = new EditText(this);
}
public static class AlartDialogFragment extends DialogFragment{
private int id;
//コンストラクタでIDを取得する
AlartDialogFragment(int id){
this.id = id;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
Dialog dialog;
AlertDialog.Builder builder;
final CharSequence items[] = {"red", "Orange", "Yellow", "Blue", "Indigo", "Violet"};
boolean flags[]={true, false, true, false, true, false, true};
switch(id){
case DIALOG_1_ID:
builder = new AlertDialog.Builder(getActivity()); //ここはgetActivity()だったのを忘れていた。
builder.setTitle("ボタンのあるダイアログ");
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage("ボタンは最大3つまで表示できる");
builder.setPositiveButton("OK", (OnClickListener) this); //Error
builder.setNeutralButton("キャンセル",(OnClickListener) this); //Error
builder.setNegativeButton("NG",(OnClickListener) this); //Error
dialog1 = builder.create();
dialog = dialog1;
break;
case DIALOG_2_ID:
builder = new AlertDialog.Builder(getActivity()); //ここはgetActivity()だったのを忘れていた。
builder.setTitle("リストダイアログ");
builder.setItems(items, (OnClickListener) this); //Error
builder.setNegativeButton("キャンセル", null);
dialog2 = builder.create();
dialog = dialog2;
break;
case DIALOG_3_ID:
builder = new AlertDialog.Builder(getActivity()); //ここはgetActivity()だったのを忘れていた。
builder.setTitle("ラジオボタンダイアログ");
builder.setSingleChoiceItems(items, -1, (OnClickListener) this);//Error //単一のラジオボタンダイアログ(単一選択)
builder.setNegativeButton("閉じる", null);
dialog3 = builder.create();
dialog = dialog3;
break;
case DIALOG_4_ID:
builder = new AlertDialog.Builder(getActivity()); //ここはgetActivity()だったのを忘れていた。
builder.setTitle("チェックボックスダイアログ");
builder.setMultiChoiceItems(items, flags, (OnMultiChoiceClickListener) this);//Error //複数のラジオボタンダイアログ(複数選択)
builder.setNegativeButton("閉じる", null);
dialog4 = builder.create();
dialog = dialog4;
break;
case DIALOG_5_ID:
builder = new AlertDialog.Builder(getActivity()); //ここはgetActivity()だったのを忘れていた。
builder.setTitle("カスタムダイアログ");
builder.setView(mInputText);
builder.setNegativeButton("閉じる", null);
dialog5 = builder.create();
dialog = dialog5;
break;
default:
dialog = null;
}
return dialog;
}
}
//ボタンクリック時の処理:ここで処理を書かないのは画面の向きを変えたときにコールバックが壊れないようにする為・・・らしい。確信持てない
@Override
public void onClick(View v){
AlartDialogFragment dlg;
switch(v.getId()){
case R.id.button1:
dlg = new AlartDialogFragment(DIALOG_1_ID);
dlg.show(getSupportFragmentManager(), "tag");
break;
case R.id.button2:
dlg = new AlartDialogFragment(DIALOG_2_ID);
dlg.show(getSupportFragmentManager(), "tag");
break;
case R.id.button3:
dlg = new AlartDialogFragment(DIALOG_3_ID);
dlg.show(getSupportFragmentManager(), "tag");
break;
case R.id.button4:
dlg = new AlartDialogFragment(DIALOG_4_ID);
dlg.show(getSupportFragmentManager(), "tag");
break;
case R.id.button5:
dlg = new AlartDialogFragment(DIALOG_5_ID);
dlg.show(getSupportFragmentManager(), "tag");
break;
default:
break;
}
}
//ダイアログがタップされたときに呼ばれる
@Override
public void onClick(DialogInterface dialog, int id){
if(dialog == dialog1){
switch(id){
case AlertDialog.BUTTON_POSITIVE:
Toast.makeText(this, "三番目のボタン", Toast.LENGTH_LONG).show();
break;
case AlertDialog.BUTTON_NEUTRAL:
Toast.makeText(this, "二番目のボタン", Toast.LENGTH_LONG).show();
break;
case AlertDialog.BUTTON_NEGATIVE:
Toast.makeText(this, "一番目のボタン", Toast.LENGTH_LONG).show();
break;
default:
break;
}
}else if(dialog == dialog2){
String item = dialog2.getListView().getAdapter().getItem(id).toString();
Toast.makeText(this, item, Toast.LENGTH_LONG).show();
}else if(dialog == dialog3){
String item = dialog3.getListView().getAdapter().getItem(id).toString();
Toast.makeText(this, item, Toast.LENGTH_LONG).show();
}else if(dialog == dialog4){
SparseBooleanArray positions = dialog4.getListView().getCheckedItemPositions();
StringBuffer sb = new StringBuffer();;
for(int i=0; i<positions.size(); i++){
if(positions.valueAt(i)){
sb.append(dialog4.getListView().getAdapter().getItem(positions.keyAt(i)).toString()).append(" ");
}
}
Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
}
else if(dialog == dialog5){
Toast.makeText(this, mInputText.getText(), Toast.LENGTH_LONG).show();
}
}
//チェックボックスダイアログがクリックされたときに呼ばれる
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked){
StringBuffer sb = new StringBuffer();
sb.append(dialog4.getListView().getAdapter().getItem(which).toString());;
if(isChecked){
sb.append("がチェックされました");
}else{
sb.append("のチェックが外されました");
}
Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.alert_dialog_sample, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
エラー内容は
実際に画面に表示されているボタンを押したら
java.lang.ClassCastException: jp.denpa.alertdialogsample.AlertDialogSampleActivity$AlartDialogFragment cannot be cast to android.content.DialogInterface$OnClickListener
と言うエラーを吐いて終了。大体原因の想像がつくのですが対処方法が思いつきません・・・
その想定している原因は上記コードの//Errorと書かれているコード。
内部ではonClickListenerの情報が存在しないよということだと思っています。(まぁ親クラスにしか存在しないので必然だったでしょうが・・・)
もう一つのエラーは定数DIALOG_5_ID、カスタムダイアログの処理を実行した時のエラーで、初回は動作するのですが、2度目の実行をしようとすると
下記エラーを吐いて強制終了します。
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
こちらは原因がViewに関すること以外検討がつきません・・・