I have some code here (my activity class and some class, that extends WebViewClient)
so, in my activity I do something like this:
protected Dialog onCreateDialog(int id) {
switch(id) {
case 1:
//logging vk dialog
Log.d("OLOLOLO", "webview");
dialog = new Dialog(this);
dialog.setContentView(R.layout.webviewl);
dialog.setTitle("loggin in");
webview = (WebView) dialog.findViewById(R.id.vkWebView);
webview.setWebViewClient(wvClforVK);
webview.loadUrl(url);
// do the work to define the pause Dialog
break;
case 2:
// already logged vk dialog
break;
default:
dialog = null;
}
return dialog;
}
and then call showDialog(1) on some buttonclick listener.
In my webview class in onPageFinished() method I need to dismiss my dialog but I think it will be incorrect to do this:
MyActivity activity = new MyActivity(); //my main activity object
activity.dismissDialog(1);
It doesn't work:
01-03 20:41:10.758: E/AndroidRuntime(1172): java.lang.IllegalArgumentException: no dialog with id 1 was ever shown via Activity#showDialog
How can I get my activity object to correctly dismiss the dialog?
The problem is that you instantiate a new activity which doesn't have any dialog. You have to call the dismissDialog method on the same activity instance in which you created the dialog. If you call it in another class, you have to pass your activity somehow to that class (for example you can pass it as a parameter). Anyway, it is not recommended to instantiate activities in this way, they are instantiated automatically if you defined them in the manifest file of your project.
As the exception says, you are trying to dismiss a dialog that was not shown before using showDialog. You need to check the life cycle of the dialog. You can use Dialog.isShowing() method to confirm the dialog is shown before dismissing it.
Related
In my activity, I am loading some eight fragments, from the 8th fragment showing some alert dialog.After that session getting expired, so redirected them to the first fragment without user interaction.During that time alert dialog not getting closed which created from 8 fragments.
In the onPause() of your 8th Fragment you should hide the AlertDialog.
class XYZ extends Fragment{
//Keep the reference to AlertDialog as a member variable in your Fragment
AlertDialog mDialog;
//other member declarations ...
#Override
public void onPause() {
// check if dialog is not null and is already showing
if(mDialog !=null && mDialog.isHowing())
mDialog.hide();
super.onPause();
}
Note : If the viewpager removes 8th fragment from memory and some action that you perform in your dialog references your 8th fragment then it would cause null pointer exception.
If you using alert dialog like that:
AlertDialog.Builder builder = new AlertDialog.Builder(Activity);
you need to keep the dialog instance which returns from the show method and call dismiss from that instance.
AlertDialog dialog = builder.show();
//Use this anywhere to close
dialog.dismiss();
I have a dialog with some UI elements in there. This dialog is created and shown at some point later on via show(). I can create the dialog with the default constructor Dialog(Context). But my content view is only set on onCreate which is called after show() function. This causes NPE when I try to modify UI elements like this:
public void showNumber(String number)
{
labelNumber.setText(number);
show();
}
But if call change the above function as below, it works most of the time. (Sometimes it fails if the phone gets slower because setContentView wouldn't be called by the time it executed setText)
public void showNumber(String number)
{
show();
labelNumber.setText(number);
}
How do you create the dialog and set content view without showing it at all. If I call setContentView() manually, it will be re-called when i call show() for the first time.
All you need to do is call create(); on the dialog when you construct it.
When you call show it will create the dialog only if create(); hasn't been called and then call onStart(); on the dialog. Finally it will attach the dialog to the window.
Something like:
Dialog myDialog = new Dialog(context) {
protected void onCreate() {
super.onCreate();
doYourThing
}
};
myDialog.create();
I'm assuming you're doing logic in onCreate, because, in Dialog it's just an empty method for subclasses to override.
onCreate:
http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/app/Dialog.java#37
show:
http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/app/Dialog.java#254
Pre API level 21 (if you can't use an AlertDialog.Builder) you should be able to use onRestoreInstanceState to do what you want to do, like this (this is a hack):
Bundle myBundle = new Bundle();
myBundle.putBoolean("android:dialogShowing", false);
myBundle.putBundle("android:dialogHierarchy", new Bundle());
myDialog.onRestoreInstanceState(myBundle);
Info:
http://androidxref.com/4.4_r1/xref/frameworks/base/core/java/android/app/Dialog.java#411
Im writing an Android application in which a user selection triggers a custom Dialog, from which a selection may trigger a second Dialog.
When showing the initial Dialog from the Activity class, I'm setting an onDismissListener on it to pull out user selections which works fine other in cases where the 2nd Dialog is not triggered. The issue that I'm having is that I can't figure out how to have the first one Dialog remain open until the 2nd one is dismissed, so that the information from both is sent back to the Activity class.
Hopefully some code will make this a little more clear:
MainActivity class where I am launching the initial CustomDialog:
customDialog = new CustomDialog(this);
customDialog.show();
customDialog.setOnDismissListener(new OnDismissListener(){
public void onDismiss(DialogInterface di){
slection = customDialog.getselection();
updateUI(); //updates a listview with the results
}
});
Within the CustumDialog class where I am launching the SecondDialog on top of it:
if(specify){
SecondDialog secondDialog = new SecondDialog(context);
secondDialog.show();
secondDialog.setOnDismissListener( new OnDissmissListener(){
public void onDismiss(DialogInterface di){
// this is where I want to call the CustomDialog's dismiss() method
// so that they both close at the same time and the data from here
// can be sent back to the MainActiivty through the CustomDialog's
// onDismissListener
}
});
}
dismiss();
So, to reiterate: I'm trying to prevent the CustomDialog's dismiss() method to be called until the SecondDialog is also dismissed. Is there a way that I can call it from the SecondDialog's OnDismissListener?
You should create customDialog as an instance level variable. You then it will be accessible with onDismiss(...) of second dialog. There you can call customDialog.dismiss();
// Instance level variable
private Dialog customDialog = null;
Instanciate your customDialog, then create second dialog from within your customDialog. Your Second dialog's code would look like this.
if(specify){
SecondDialog secondDialog = new SecondDialog(context);
secondDialog.show();
secondDialog.setOnDismissListener( new OnDissmissListener(){
public void onDismiss(DialogInterface di){
// customDialog is accessible as it is declared as instance level variable
MyClassName.this.customDialog.dismiss();
}
});
}
dismiss();
I prefer to save the data in 1st dialog before going to send one and when dismiss the 2nd dialog, open the 1st dialog again with saved data .. i used this way in my developing and its effective ..
I have a problem creating a custom dialog. But I don't find the failure. Hopefully anybody can help me ...
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
switch (id) {
case DIALOG_ABOUT_ID:
dialog = buildAboutDialog();
break;
default:
dialog = null;
}
return dialog;
}
...
public Dialog buildAboutDialog() {
Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);
dialog.setContentView(R.layout.about_dialog);
dialog.setTitle("About this application");
return dialog;
}
Results in the following error:
12-30 19:27:02.593: ERROR/AndroidRuntime(383): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
I checked if the returned dialog == null - but it isn't.
I also tried the second way (inflater) described at http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog
I found out, that the dialog needs to be created with
Dialog dialog = new Dialog(this);
and not
Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);
I don't exactly know why. Perhaps anybody can explain it to me?
Dialog dialog = new Dialog(contex);
dialog.setContentView(R.layout.help_content);
this works for me .. may be getapplicationcontext not getting context of the your main class.
As it turns out, Context of an activity is different then object returned by getApplicationContext(). This you can check by using logging, just output ActivityName.this and getApplicationContext.
The object returned by getApplicationContext is a global thing while context of an activity, well, belongs to that activity only.
Log.e(tag,""+ getApplicationContext());
Log.e(tag,""+CustomDialogActivity.this);
where CustomDialogActivity is my activity in which I want to show my dialog.
Dialogs require context of an activity and getApplicationContext() does not provide that. As written here (read comments) context of an activity is superset of getApplicationContext(). so It is a good thing to always pass context of an activity rather then the global context.
Also to answer ffleandro's comment of this page if you are inside onClick() you can use
ActivityName.this to refer to activity. Hope this helps
In my activity I need a ProgressDialog with a horizontal progress bar to visualise the progress of a background task. To make the activity care for the dialog e.g. in case of screen rotation, I would like to use a managed dialog created in onCreateDialog. The problem is that I need to update the progress bar of the dialog after it has been created and therefor I need a reference to the managed progress dialog: Does anyone know how to retrieve a reference to a dialog created by onCreateDialog?
At the moment I am storing a reference to the dialog created in onCreateDialog, but that my fail with a InvalidArgumentException in the onFinished() method after the screen has been rotated (and the activity has been recreated):
public final class MyActivity extends Activity {
private static final int DIALOG_PROGRESS = 0;
private ProgressDialog progressDialog = null;
// [...]
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_PROGRESS:
progressDialog = createProgressDialog();
return progressDialog;
default:
return super.onCreateDialog(id);
}
}
// [...]
public void updateProgress(int progress) {
progressDialog.setProgress(0);
}
public void onFinished() {
progressDialog.dismiss();
}
// [...]
}
I would have expected something like a getDialog(int) method in the Activity class to get a reference to a managed dialog, but this doesn't seem to exist. Any ideas?
I answer myself:
There really is no getDialog(int) method available in the Activity class.
Storing the reference like shown above works correctly -- the bug was something else...
The problem was, that the parallel thread, that called the onFinished() method called this method on the already destroyed activity, thus the accessed ProgressDialog instance is still existing but no longer a valid dialog. Instead another activity with another ProgressDialog has already been created by Android.
So all I needed to do was to make the background thread call the onFinished() method of the new activity and everything works fine. To switch the reference I override the onRetainNonConfigurationInstance() and getLastNonConfigurationInstance() methods of the Activity class.
The good thing of the shown example: Android really cares about recreating the new dialog after the screen orientation changed. So constructing the ProgressDialog that way is definitely easier than using ProgressDialog.show() where I would need to handle the dialog recreation on my own (the two methods described above would be a good place to do this.