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
Related
In MainActivity, Context and MainActivity are different?
They are exactly getApplicationContext() and MainActivity.this in Method.
The reason I'm asking this is because i got error because of them.
if these are different, Complier didn't display red line in code.
I thought it was the same until now.
I got this error code.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.writeweight, PID: 24595
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:843)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:806)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:693)
at androidx.appcompat.app.AppCompatDialog.setContentView(AppCompatDialog.java:95)
at androidx.appcompat.app.AlertController.installContent(AlertController.java:232)
at androidx.appcompat.app.AlertDialog.onCreate(AlertDialog.java:279)
at android.app.Dialog.dispatchOnCreate(Dialog.java:702)
at android.app.Dialog.show(Dialog.java:424)
at com.example.writeweight.MainActivity.onOptionsItemSelected(MainActivity.java:85)
at android.app.Activity.onMenuItemSelected(Activity.java:4182)
And I changed from getApplicationContext() to MainActivity.this and it worked well.
Code
MainActivity.class
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); // HERE
builder.setTitle("SET");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(),"TEST", Toast.LENGTH_SHORT).show();
}
});
AlertDialog dialog = builder.create();
dialog.show();
return true;
}
Tell me please.
Thank you
getApplicationContext() (somewhat unsurprisingly) returns the application context, whilst MainActivity.this is itself an activity context. Themes associated with your activity will differ from your application. They aren't the same thing.
if these are different, Complier didn't display red line in code.
You wont see an error, because it's only a Context that is requested. I haven't tried it, but you probably could use an Application instance so long as you specify the theme as well by using new AlertDialog.Builder(getApplicationContext(), /* theme res id */)
However, all the examples in the Android documentation use an Activity context, so I'd suggest you just go with that.
I have a method in my class i want to test which shows an alert dialog .
When i call this method from the test class it is executed but the dialog is not shown?
The same happens when i call a method, that shows some toast or other popup dialog
my test class extends ActivityInstrumentationTestCase2.
public void showSaveName(String name){
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_menu_save)
.setTitle(R.string.savePopupLabel)
.setMessage(R.string.savePopupMessage)
.setPositiveButton(R.string.save_yes, new alter(name))
.setNegativeButton(R.string.save_no, null)
.show();
}
when i call this from my test class
getActivity().showSaveName(name);
the dialog is not shown?
Can anyone help me to figure out why it is happening ?or if i am doing something wrong?
That's normal.
Your test classes are not meant to make anything show on the device. You are supposed to programmatically make sure that the dialog appears.
In your test class, once you display the dialog, keep the instance of the Dialg box and then do
assertTrue(yourDialogInstance.isShown());
And if your dialog has not appeared, your test will fail.
That should do it.
Can you try:
public void showSaveName(String name) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(android.R.drawable.ic_menu_save)
.setTitle(R.string.savePopupLabel)
.setMessage(R.string.savePopupMessage)
.setPositiveButton(R.string.save_yes, new alter(name))
.setNegativeButton(R.string.save_no, null);
AlertDialog dialog = builder.create();
dialog.show();
}
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.
So a dialog is opened every time a text is received. I want it to not open one if there is one already open. I was trying to check if one was open by using isShowing() but I keep getting the method isShowing() is undefinded for the type AlertDialog.Builder. Here is the section of bad code. Any help would be so sweet right about now.
public class PopUpReply extends Activity{
AlertDialog.Builder alertbox;
AlertDialog.Builder alert;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// prepare the alert box
alertbox.isShowing();
alertbox = new AlertDialog.Builder(this);
There is no isShowing() method on the AlertDialog.Builder class. There is one on the Dialog class though.
AlertDialog.Builder
Dialog
An AlertDialog.Builder is used to create an AlertDialog. Once you have an instance of an AlertDialog, you can determine whether or not it is still showing by then calling isShowing() on it.
Im trying to make an activity that has a multiple choice dialog after you push a button. In there you select from a list of things. But these things are received from a web method before the dialog appears.
So I create a string array after I receive them inside the onCreate to initialise it there with the correct size.
But my dialog method then cant get the array because propably its out of its scope.
My code looks like this
#Override
protected Dialog onCreateDialog(int id)
//Here is where the array is loaded to the multiple select dialog
etc
#Override
public void onCreate(Bundle savedInstanceState)
//Here is where i initialise the array and get its contents
etc
I cant initialise my array when the class starts because I dont know its size yet.
This has to do something with the scopes of my variables and I am pretty confused
make the string array a class member, just populate it in onCreate. You can load it into the dialog in onCreateDialog if the array never changes, if it may change between calls to the dialog then you should do it in onPrepareDialog.
So in your class define:
private String mDialogStrings[];
then in onCreate something like:
mDialogStrings = new String[numItems];
mDialogStrings[0] = string1;
etc...
if you use showDialog and want activity managed dialogs (you should do this) then you must implement onCreateDialog to actually create the dialog. This will get called once for each dialog you have. onPrepareDialog gets called every time you call showDialog(). So the code to update the dialog showing the string array should go in onPrepareDialog and the code to create the dialog should go in onCreateDialog.
public Dialog onCreateDialog(int id) {
switch(id) {
case MY_DIALOG:
Dialog d = new Dialog(this);
return d;
}
}
public void onPrepareDialog(Dialog d, int id) {
switch(id) {
case MY_DIALOG:
d.setSomeStringArray();
break;
}
}