Custom AlertDialog fails to initialize in onCreate() - java

I'm trying to build a custom AlertDialog by extending the AlertDialog class.
As usual, I'm setting up the dialog inside its onCreate() method. Or, I'm trying to do so:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle("Some title");
this.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
final FrameLayout custom = (FrameLayout) this
.findViewById(android.R.id.custom);
custom.addView(this.getLayoutInflater().inflate(R.layout.mydlg, null),
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
Now, when it comes to displaying an instance of this dialog, nothing is shown. The current Activity fades out and loses focus but not a single pixel of my dialog is displayed. Pressing Back brings the Activity back to the foreground, indicating to me that a dialog actually is shown, but just a completely empty one.
However, when I create an AlertDialog and use, for instance, dlg.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
the dialog is shown with the respective button.
Even when I set up my custom dialog in its constructor using the very same code as above everything seems to work ok.
Now, how can this be? Why can't I seem to initialize my dialog in its onCreate() method? Isn't this the way you're supposed to initialize any GUI element? What am I missing?
EDIT
Please note, that something is 'shown', fading out the Activity and taking focus from it. It's just that it seems to be completely empty/invisible.
Here another attempt:
this.setTitle("Some title");
this.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
final View v = this.getLayoutInflater().inflate(R.layout.mydlg, null);
this.setView(v);
These exact lines do work when put into my dialog's constructor.
These exact lines do not work when put into my dialog's onCreate().
What is going on here?!
Generally, am I not supposed to do it in onCreate()? - Am I facing trouble if I resort to doing the above initialization in the constructor instead? (This does not seem too clean to me, anyway.)

You need to call the show() method in order to see something.

You should consider using AlertDialog.Builder instead of subclassing AlertDialog itself. It allows you to do all the things you need in your example (in order: setTitle(),setPositiveButton() and setView() ). Don't forget to call create() at the end to actually get your dialog.
Also, check if your onCreateDialog() and onPrepareDialog() activity methods are implemented correctly. If you don't have them implemented at all (an unmanaged dialog), consider doing that anyway, especially if your app allows for orientation changes. You probably know about this, but here is a tutorial:
http://developer.android.com/guide/topics/ui/dialogs.html
also, DialogFragments are a bit easier way to implement this, but you need a newer API version or the Compatibility package:
http://developer.android.com/reference/android/app/DialogFragment.
One final issue - where are you calling show() in your activity? onResume() should be OK, onCreate() not as much.

Sorry I'm late to the party :)
You have to thing differently for the alert dialog.
The way I did it is to customize the view before creating the alert dialog:
// This is the activity that is the background of the AlertDialog
public class Main extends Activity {
public static final int DIALOG_CONFIG = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.emptybackground);
}
#Override
protected void onStart() {
super.onStart();
// Open the alert dialog on openning the Activity
showDialog(Main.DIALOG_CONFIG );
}
protected Dialog onCreateDialog(int id) {
LayoutInflater factory = LayoutInflater.from(this);
switch (id) {
case DIALOG_CONFIG:
// Here, we load the existing view R.layout.config
configView = factory.inflate(R.layout.config, null);
configDialog = new AlertDialog.Builder(this)
.setTitle("Configuration")
.setView(configView)
.create();
// Using configView, you can do whatever you want with the view. Here, we add value to a spinner.
Spinner spinner = (Spinner)configView.findViewById(R.id.config_select_conn);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add("TCP");
adapter.add("Bluetooth");
spinner.setAdapter(adapter);
return configPrinter;
}
return null;
}
}

you should call custom_alertDialog.create(); before custom_alertDialog.show();

Related

How to use a button to show a custom dialog in android application?

I am following a youtube tutorial and I've got most of the works done, but I still got some problems.
I have my custom layout for my custom dialog, all I wanted to do is to set the custom dialog on a button. Once we click the button ,the dialog shows, that's it. I've already set the onclicklistener on the button, here's my code.
Credit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Dialog credit = new Dialog(Main.this);
credit.setContentView(R.layout.creditdialog);
credit.setTitle(" ");
credit.show();
}
});
I followed all of this on a tutorial, but I don't know that the "MAIN" is about, I got an error there. Please tell me what to do. Sorry for my poor English.
new Dialog(Main.this);
The above line creates a new dialog object and associates it with the context of your Activity. SO you have to pass the context of your activity in the paranthesis..
Eg:
If you are calling the dialog from Activity "ActivityMain".. then use:
new Dialog(ActivityMain.this);
try this
Credit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Dialog credit = new Dialog(getApplicationContext());
credit.setContentView(R.layout.creditdialog);
credit.setTitle(" ");
credit.show();
}
});
it is common question! but you can extend dialog box and can set custom layout for your dialog than on button click just call dialog like this:
new CustomDialog(activity).show();
also you can follow this tutorial on custom dialog to understand how to customise dialog and how to use it on button click.
http://www.shaikhhamadali.blogspot.com/2013/09/types-of-dialogbox-part-two-custom.html

Android ListView within fragment doesn't refresh without a button click

My ListView doesn't refresh its contents when I call the appropriate method unless the method was invoked with a button click.
The follow example code is how my test button works (temporary button to check to see if it was a problem with my refresh code):
testBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
exampleRefresh();
}
});
And the method it calls:
public void exampleRefresh() {
exampleAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, arrayOfItems());
exampleListView.setAdapter(exampleAdapter);
}
This works fine.
However, if I call exampleRefresh() in the switch statement for a context menu, nothing happens. Again, when I click the test button, the ListView refreshes instantly. These are calling the same method, I don't understand the issue.
I have tried adding nofifyDataSetChange(), but it doesn't work. The ListView only refreshes when I invoke a button press.
It's also worth noting that even if I call the method on the invoke of a context menu, it refreshes. It does not do anything without an invoke, it appears.
Any help will be very much appreciated.
have you tried to
exampleAdapter = new ArrayAdapter<String>();
exampleAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, arrayOfItems());
exampleListView.setAdapter(exampleAdapter);
this should force it to clear and re-add the
if you are changing data in list and then you want to refresh listview then dont call setadapter method again. just call below method:
exampleAdapter.notifyDataSetChange();
Try invoking notifyDataSetChange() from exampleListView.post() like this:
exampleListView.post(new Runnable() {
public void run() {
exampleAdapter.notifyDatasetChange();
}
}

opening the same dialog from a list in android

I have a listActivity with many items.
For each item, I want to open the same popup while sending an item id\position\other
info object unique to that item.
But basically all the time I open the exact same popup.
Its buttons will send the extra unique data to the server.
I have read few tutorials, and saw a dialog is usually opened like this:
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.custom);
dialog.setTitle("Title...");
// set the custom dialog components - text, image and button
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Android custom dialog example!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.ic_launcher);
Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
I think it's more readable to create a different file to the dialog.
like this:
public class SocialActionsDialog extends Dialog {
public SocialActionsDialog(Context context) {
super(context);
mContext = context;
}
Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.social_actions);
setTitle("Title...");
}
but then I get a syntax error on the OnCreate.
Is it common and good practice to create new file? and if so- how to do it properly?
is it more efficient somehow - just showing the same dialog instead of initializing a new one each time? or is both ways the same?
For the syntax error, make sure you are importing the R class from your app and not the Android SDK class R resources.
For an experienced programmer your instinct is to move the dialog to a separate file, especially if it contains a lot of code. And that can be the right decision at times.
However, it is often convenient to have the dialog as an embedded class or to just create it inline (as in your example) because then it is within the scope of your activity and can access your state variables and protected methods on the Activity itself.
So you end up passing all this information to the dialog if you have it in a separate file, and at some point it just isn't worth it because the code becomes more complex and less maintainable.

Run a method after View is created - Android

I've currently got an activity that creates a view. this view uses other classes (such as one to create a random sequence of integers). I need to run a method (which will display the sequence using bitmaps) once the view is created. So once the user clicks "Start Game" this sequence will be displayed.
I've tried calling the method after setting the content view inside the onCreate method by the sequence is not generated (all 0's) correctly. I've tries this also with onStart and onFinishInflate inside the myView class.
Is there a way i can run this method after everything is inflated and initialized? So after the user clicks "Start Game" and the view is changed, the method needs to run.
Thanks for looking.
Edit: A failed attempt.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.gameView = new GameView(getApplicationContext(), getCellSource(getApplicationContext()));
setContentView(this.gameView);
// this.gameView.displaySequence(this.gameView.gameEngine.getGenSequence()); Need this to run once view is displayed.
}
Try using ViewTreeObserver as follow:
final View yourView = View.inflate(....);
ViewTreeObserver observer = yourView .getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
yourView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// Do what you need with yourView here...
}
});
Notice that the function removeGlobalOnLayoutListener(this) is different in some sdk versions.

PopUp dialog Android from background thread

I need a popup dialog to be shown when i get a message from different thread but the dialog should be not dependent on Activity i.e, it should display the dialog wherever the screen focus is.
Can it be done? Because the dialog is handled per Activity, I thought of using a service but again it would be one more thread added and I want to avoid that.
Any other options available?
If you're trying to ask how to show a dialog when your activity is not the focused activity on the user's phone then try using Notifications instead. Popping up a dialog over a different application interrupts the user when they may be doing something else. From the Android UI guidelines:
Use the notification system — don't
use dialog boxes in place of
notifications
If your background service needs to
notify a user, use the standard
notification system — don't use a
dialog or toast to notify them. A
dialog or toast would immediately take
focus and interrupt the user, taking
focus away from what they were doing:
the user could be in the middle of
typing text the moment the dialog
appears and could accidentally act on
the dialog. Users are used to dealing
with notifications and can pull down
the notification shade at their
convenience to respond to your
message.
A guide to create notifications is here: http://developer.android.com/guide/topics/ui/notifiers/notifications.html
Alternative solution :
AlertDialog dialog;
//add this to your code
dialog = builder.create();
Window window = dialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
lp.token = mInputView.getWindowToken();
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
//end addons
alert.show();
if I understand you correctly you could use a base class for all of your activities
public abstract class BaseActivity extends Activity{
protected static BaseActivity current_context = null;
#override
protected void onPause(){
current_context = null;
super.onPause();
}
#override
protected void onResume(){
current_context = this;
super.onResume();
}
public static void showDialog(/*your parameters*/){
//show nothing, if no activity has focus
if(current_context == null)return;
current_context.runOnUiThread(new Runnable() {
#override
public void run(){
AlertDialog.Builder builder =
new AlertDialog.Builder(current_context);
//your dialog initialization
builder.show();
}
});
}
}
in your thread show your dialog with BaseActivity.showDialog(..) But this approach doesn't work if you want to show your dialog on top of any activity of the target device.

Categories