我创建了一个单例辅助类,用于创建我需要在我的应用程序中使用的对话框。
该课程如下:
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;
}
}
}
}
现在,为了显示所需的对话框,我使用了这行代码:
DialogHelper.getInstance(this).getAlertDialog(DialogHelper.DISTANCE_UNIT_DIALOG).show();
这一切都很有效,这是第一次。我第二次得到标题中指定的异常。现在,从我之前在这里搜索的问题中我了解到我可能是第一次显示对话框,并且第二次它可能附加到父活动。
问题是:如何在不将其与特定活动紧密耦合的情况下从助手类内部处理这种情况?
答案 0 :(得分:0)
Because problem is in instance create
in your Code
static DialogHelper storedInstance;
public static DialogHelper getInstance(Context context) {
if (instance == null) {
instance = new DialogHelper(context);
}
else
{
activity = (Activity)this.context;
}
return instance;
}
First time you pass Contect and Create dialog successfully with Context but second time you pass second reference context and instance already created so it returns previous context instance.that is problem...
so 2 way to solve problem
first Close agove dialog and every time create new Dialog instance
or
second is return privois dialog reference like this
public static DialogHelper getInstance(Context context) {
if (instance == null) {
instance = new DialogHelper(context);
storedInstance=instance ;
}
else
{
instance=storedInstance;
}
return instance;
}
答案 1 :(得分:0)
根据我的理解,我的案例中的问题是我尝试将相同的ListView
附加到同一个Dialog
构建器,因此创建两个new instance
都删除了此错误。所以我所做的是在getAlertDialog
方法的开头我添加了这个:
public AlertDialog getAlertDialog(final int dialogType)
{
builder = new AlertDialog.Builder(activity);
dialogList = new ListView(activity);
...