I have create a singleton helper class for creating the dialogs I need to use across my application.
The class looks like this:
public class DialogHelper {
private static final String TAG = DialogHelper.class.getSimpleName();
public static final int CHOOSE_COUNTRY_DIALOG = 1;
public static final int DISTANCE_UNIT_DIALOG = 2;
public static final int COUPON_DIALOG = 3;
public static final int VERSION_DIALOG = 4;
private static DialogHelper instance = null;
private AlertDialog.Builder builder;
private AlertDialog dialog;
private ListView dialogList;
private static Activity activity;
private Context context;
private DialogHelper(Context context) {
CupsLog.d(TAG, "DialogHelper()");
this.context = context;
this.activity = (Activity) context;
builder = new AlertDialog.Builder(context);
dialogList = new ListView(context);
}
public static DialogHelper getInstance(Context context) {
if (instance == null) {
instance = new DialogHelper(context);
}
else
{
activity = (Activity)context;
}
return instance;
}
public AlertDialog getAlertDialog(int dialogType)
{
switch (dialogType)
{
case CHOOSE_COUNTRY_DIALOG:
{
builder.setTitle(R.string.choose_country_title_string);
configureDialogListView(dialogType);
builder.setView(dialogList);
break;
}
case DISTANCE_UNIT_DIALOG:
{
builder.setTitle(R.string.distance_units_string);
configureDialogListView(dialogType);
builder.setView(dialogList);
break;
}
case COUPON_DIALOG:
{
builder.setTitle(activity.getResources().getString(R.string.coupon_dialog_title));
final EditText input = new EditText(activity);
builder.setView(input);
builder.setPositiveButton(R.string.ok_string, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Editable value = input.getText();
AsyncHttpClient client = new AsyncHttpClient();
client.setCookieStore(CookieUtil.getInstance(activity).getPersistentCookieStore());
CupsLog.d(TAG, "promotion url " + Consts.stringUri("/account/promotion?code=" + Uri.encode(value.toString())));
client.post(Consts.stringUri("/account/promotion?code=" + Uri.encode(value.toString())), new JsonHttpResponseHandler() {
@Override
public void onSuccess(int arg0, JSONObject arg1) {
CupsLog.d(TAG, "onSuccess(int arg0, JSONObject arg1)");
/*String title = null;*/
String msg = null;
try {
CupsLog.d(TAG, "promotion response JSON: " + arg1.toString(3));
msg = arg1.getString("msg");
} catch (JSONException e) {
e.printStackTrace();
}
if (/*title != null && */msg != null) {
AlertDialog.Builder response = new AlertDialog.Builder(activity);
//response.setTitle(title);
response.setMessage(msg);
response.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
AccountService.getInstance(activity).pullAccountDetailsFromServer();
}
});
response.show();
}
}
@Override
public void onFailure(Throwable arg0, JSONObject arg1) {
CupsLog.d(TAG, "onFailure(Throwable arg0, JSONObject arg1)");
String msg = null;
try {
CupsLog.d(TAG, "promotion response JSON: " + arg1.toString(3));
msg = arg1.getString("msg");
} catch (JSONException e) {
e.printStackTrace();
}
if (/*title != null && */msg != null) {
AlertDialog.Builder response = new AlertDialog.Builder(activity);
//response.setTitle(title);
response.setMessage(msg);
response.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {}
});
response.show();
}
super.onFailure(arg0, arg1);
}
});
}
});
break;
}
}
builder.setNegativeButton(activity.getResources().getString(R.string.close), new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog = builder.create();
if (dialogType == COUPON_DIALOG)
{
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
return dialog;
}
private void configureDialogListView(int dialogType)
{
dialogList.removeAllViewsInLayout();
switch (dialogType)
{
case CHOOSE_COUNTRY_DIALOG:
{
dialogList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int arg2, long arg3) {
String chosenUnit = ((TextView) view).getText().toString();
String countryString;
if (chosenUnit.equals(activity.getResources().getString(R.string.israel_string))) {
countryString = "il";
} else {
countryString = "us";
}
dialog.dismiss();
((LoginActivity)activity).onCountryFound(countryString);
}
});
String[] stringArray = new String[]{activity.getResources().getString(R.string.usa_string), activity.getResources().getString(R.string.israel_string)};
ArrayAdapter<String> modeAdapter = new ArrayAdapter<String>(activity, android.R.layout.simple_list_item_1, android.R.id.text1, stringArray);
dialogList.setAdapter(modeAdapter);
break;
}
case DISTANCE_UNIT_DIALOG:
{
dialogList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int arg2, long arg3) {
String chosenUnit = ((TextView)view).getText().toString();
App.getInstance().isDistanceUnitChanged = true;
if (chosenUnit.equals(activity.getResources().getString(R.string.metric_string))){
BusProvider.getInstance().post(new DialogChangeEvent(Consts.DISTANCE_UNIT, activity.getResources().getString(R.string.metric_string)));
FileAccessUtil.getInstance(activity.getApplicationContext()).setStringProperty(Consts.DISTANCE_UNIT, Consts.DISTANCE_UNIT_KILOMETER);
}
else {
BusProvider.getInstance().post(new DialogChangeEvent(Consts.DISTANCE_UNIT, activity.getResources().getString(R.string.imperial_string)));
FileAccessUtil.getInstance(activity.getApplicationContext()).setStringProperty(Consts.DISTANCE_UNIT, Consts.DISTANCE_UNIT_MILE);
}
dialog.dismiss();
}
});
String[] stringArray = new String[] { activity.getResources().getString(R.string.metric_string), activity.getResources().getString(R.string.imperial_string)};
ArrayAdapter<String> modeAdapter = new ArrayAdapter<String>(activity, android.R.layout.simple_list_item_1, android.R.id.text1, stringArray);
dialogList.setAdapter(modeAdapter);
break;
}
}
}
}
Now, to show the needed dialog I use this line of code:
DialogHelper.getInstance(this).getAlertDialog(DialogHelper.DISTANCE_UNIT_DIALOG).show();
And it all works great, for the first time. For the second time I get the exception specified in the title. Now, from previous questions I searched here I understand that I probably showing the dialog for the first time, and for the second time it probably attached to the parent activity.
The question is: How can I handle this situation from inside the helper class without tight coupling it to a specific activity?