In the code, there is an alert box(for logout functionality).
This alert box is created inside a method (i.e. logout method) and then two onClickListener are anonymously added to it.
How can I call these anonymous listeners from outside?
Code:
AlertDialog.Builder builder
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id) {
//some logic
}
}
What I need is to somehow call this onClick method and pass the instance of same dialog box.
I have read examples of doing this with reflection, but in those examples anonymous class was a subclass i.e. return value of 'new' was catched
You could make the listener into a field variable.
private final DialogInterface.OnClickListener dialogYesListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//some logic
}
};
AlertDialog.Builder builder
builder.setPositiveButton("Yes", dialogYesListener);
You have two options:
1) Refactor your code to have a reference to an instance of an DialogInterfact.OnClickListener like this:
AlertDialog.Builder builder;
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//some logic
}
}
builder.setPositiveButton("Yes", listener);
2) I don't know whether there is such an API, but if yes, you can try to extract listener implementation from a builder. Pseudocode should look like this:
DialogInterface.OnClickListener listener =
builder.getPositiveButton().getListener(); //adjust this to a real API
Related
I'm trying to make a extern class for AlertDialog. I want to have an universal class to use it quickly.I know the code isn't difficult at all, but there are anyhow many rows to write (or copy) and if I would find a mistake I maybe had to change many code...
I've everything but one thing I don't get.
So it works but returning the correct onClick doesn't work.
I've also tried to make an while loop before returning, but then the app is hanging....
Has somebody any idea?
public class RalaAlertDialog{
private static AlertDialog.Builder alertDialog;
private static long onClick=RalaInterfaceDefault.FehlerSpezialZahl;
//neutralButton
public static long AlertDialogNeutral(Context class_this, String mssg, String ntrlBttnTxt, boolean dismissable, String title){
onClick=RalaInterfaceDefault.FehlerSpezialZahl; //default error number
alertDialog=new AlertDialog.Builder(class_this);
if(mssg.equals("")){
mssg="DEFAULT-TEXT";
}
if(title.equals("")){
title="DEFAULT-TITLE";
}
if(ntrlBttnTxt.equalsIgnoreCase("")){
System.out.println("No values set - default in use.");
ntrlBttnTxt="OK";
}
alertDialog.setMessage(mssg)
.setCancelable(dismissable);
alertDialog.setTitle(title);
alertDialog.setPositiveButton(ntrlBttnTxt,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id){
onClick=0;
dialog.dismiss();
}
}
);
AlertDialog a=alertDialog.create();
a.show();
//wait until button is click before continuing
return onClick;
}
public static AlertDialog getAlertDialog(Context ctx, String title, String message, String posButton, boolean dismissable, final DialogInterface.OnClickListener ocl) {
AlertDialog.Builder builder =new AlertDialog.Builder(ctx);
builder.setTitle(title)
.setMessage(message)
.setCancelable(dismissable)
.setPositiveButton(posButton,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id){
dialog.dismiss();
if(ocl!=null) ocl.onClick(dialog, id);
}
});
AlertDialog dialog = builder.create();
return dialog;
}
Use it like this :
AlertDialog dialog = getAlertDialog(this,"Hello","World","OK",false,new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.i("DIALOG","OK Clicked");
}
});
dialog.show();
Of course you need only one OnClickListener, but I like it better that way.
I'm new to Java/ Android development (I started learning last night) so it is entirely possible I'm doing something horrendously stupid. However, after more than an hour Googling I've come up with nothing. I'm using Eclipse as my editor.
I'm reading the docs here for AlertDialog, which gives an example:
public static class MyAlertDialogFragment extends DialogFragment {
public static MyAlertDialogFragment newInstance(int title) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(title)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((FragmentAlertDialog)getActivity()).doPositiveClick();
}
}
)
.setNegativeButton(R.string.alert_dialog_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((FragmentAlertDialog)getActivity()).doNegativeClick();
}
}
)
.create();
}
}
I originally re-wrote it so I can start committing some of the methods to memory, but got an error "FragmentAlertDialog cannot be resolved to a type". I hit Ctrl+Shift+O to make sure I had the proper imports, but still it didn't go away.
So I copied/ pasted the example code and did the following, in this order:
Hit Ctrl+Shift+O to get the imports right (using android.app.DialogFragment, not android.support.v4.app.DialogFragment)
Declared my package at the top
Replaced R.string.alert_dialog_ok and R.string.alert_dialog_cancel with android.R.string.ok and android.R.string.cancel respectively
Removed setIcon(), as I don't have an icon to put in yet
I'm still getting errors:
FragmentAlertDialog cannot be resolved to a type (x4)
Illegal modifier for the class MyAlertDialogFragment; only public, abstract & final are permitted
Am I doing something wrong, or is there something wrong with the example code?
1.FragmentAlertDialog
Make sure the Activity you want to cast to is named FragmentAlertDialog. Make sure to also save everything - sometimes Eclipse won't make the connection until everything is saved.
2.Illegal modifier for the class MyAlertDialogFragment; only public, abstract & final are permitted
Take out the static modifier:
public class MyAlertDialogFragment extends DialogFragment {
or keep static and move this Fragment so it is enclosed within the Activity you want. This means that MyAlertDialogFragment should be inside your Activity, before that Activity's closing brace.
I'm new to Java/Android development
Don't start off with something so complicated. Learn Java then move to Android.
Hi try these code to implement alert dialog
AlertDialog.Builder alert2 = new AlertDialog.Builder(this);
alert2.setTitle("Your Title");
alert2.setMessage("Your Messages");
final EditText input2 = new EditText(this);
input2.setInputType(InputType.TYPE_CLASS_PHONE);
alert2.setView(input2);
alert2.setPositiveButton(GButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Do something with value!
try
{
// do your stuff here
}
catch(Exception e)
{
}
}
});
alert2.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert2.show();
I'm currently writing a program that will use the Geocoder to search for possible GeoPoints of a city search. I then take the geopoints and add it to a map as overlays, the user can then click the overlay, and an alert dialog will pop up to ask if he/she is sure that this is the right one.
I couldn't figure out a way to get the alert dialog to work like swing where after the user clicks yes or no, I can retrieve the answer. So I extended the AlertDialog.Builder class like so, which also happens to be a Dialog.OnClicklistener
public class MyAlertDialog extends AlertDialog.Builder implements DialogInterface.OnClickListener{
final static int positiveMessage = 1;
final static int negativeMessage = 0;
final static int neutralMessage = -1;
private int myMessage;
public MyAlertDialog(Context activity) {
super(activity);
}
#Override
public void onClick(DialogInterface dialog, int which) {
if(which == dialog.BUTTON_POSITIVE){
myMessage = positiveMessage;
}
else if(which == dialog.BUTTON_NEGATIVE){
myMessage = negativeMessage;
}
else{
myMessage = neutralMessage;
}
}
public int getMessage() {
return myMessage;
}
and I implement it like so
protected boolean onTap(int index) {
OverlayItem item = overlays.get(index);
MyAlertDialog dialog = new MyAlertDialog(ctx);
dialog.setTitle(item.getTitle());
dialog.setMessage("Is this the " + item.getTitle()
+ " you're looking for?");
dialog.setPositiveButton("Yes",null);
dialog.setNegativeButton("Cancel", null);
dialog.show();
if(dialog.getMessage()== MyAlertDialog.positiveMessage){
//do some stuff
But for some reason the dialog wont show until after the method has returned, so it never does the stuff. Anyone have any ideas? Oh and ctx is a reference to my mapActivity
This is because the dialog.show(); method does not wait for the user to interact with the Dialog before returning. It does exactly what the name would suggest, and nothing more; it shows the Dialog, and then returns. So, that means that your myMessage field will always be null and this condition will never be true:
if(dialog.getMessage()== MyAlertDialog.positiveMessage){
What you should do instead is pass in OnClickListener for both your positive and negative button, and do whatever you need to in the respective OnClickListener. You won't even need to make a subclass of AlertDialog.Builder, because there won't be any benefit to doing that. Here's how that looks:
dialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which){
// Do some positive stuff here!
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which){
// Do some negative stuff here!
}
});
Here's a very simplified version of my Activity:
public class Search extends Activity {
//I need to access this.
public SearchResultsAdapter objAdapter;
public boolean onOptionsItemSelected(MenuItem itmMenuitem) {
if (itmMenuitem.getItemId() == R.id.group) {
final CharSequence[] items = {"Red", "Green", "Blue"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(itmMenuitem.getTitle());
builder.setSingleChoiceItems(lstChoices),
0, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
//I need to access it from here.
}
});
AlertDialog alert = builder.create();
alert.show();
return true;
}
}
}
When the menu button is pressed, my applications pops up an AlertDialog. When creating the AlertDialog and in-line onClickListener is attached to the each of the items in the dialog. I need to access the objAdapater variable that is defined in my Search activity. I don't have access to the search instance within my onClickListener so I can't access it. I have a little bit of a soup in my code with the passing of the Activity instance everywhere. Maybe I'm doing something wrong.
How would I get access to the Activity (Search instance) from within my onClickListener so I can access it's methods and variables.
Thank you.
Using Search.this.objAdapter to access objAdapter from the listener should work.
Search.this refers to the current instance of Search and allow you to access its fields and methods.
Make your activity implement OnClickListener:
public class Search extends Activity implements DialogInterface.OnClickListener { ...
Add the onclick method to your activity:
public void onClick(DialogInterface dialog, int item) {
//I need to access it from here.
}
Then pass your activity as the listener:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(itmMenuitem.getTitle());
builder.setSingleChoiceItems(lstChoices),0, this);
I know that creating static methods to create AlertDialogs is not a good sign. But, whenever I felt like creating some AlertDialogs, I always have to place them inside an Activity subclass. I've been looking around in SO, trying to find a good way to factor the code, so that I don't have to initialize and create AlertDialogs from an Activity subclass.
Here is an example of my code, designed in such a way that I have to sacrifice performance speed for AlertDialogs, which is very necessary in my project plans.
public void onCreate(Bundle b) {
super.onCreate(b);
accelerometer = new Accelero();
leaderboard = new Score(this);
renderView = new RenderView(this);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(renderView);
// TODO: Refactor this, to speed things up.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
input = new EditText(this);
builder.setView(input);
builder.setTitle("Enter Name for High Score!");
builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO: Polish the dialog.
// TODO: Add a method of obtaining the score from RenderView.
renderView.getStage().reset();
renderView.setDialogFlag(false);
}
});
builder.setNegativeButton("Back", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
PlayActivity.this.onBackPressed();
}
});
renderView.setLosingDialog(builder.create());
builder = new AlertDialog.Builder(this);
builder.setTitle("You win!");
builder.setPositiveButton("Next Stage", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
renderView.createStage(getAssets(), stageNumber);
renderView.pauseGame();
}
});
renderView.setWinningDialog(builder.create());
builder = new AlertDialog.Builder(this);
builder.setTitle("Game Paused!");
builder.setPositiveButton("Back to Game", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
renderView.unpauseGame();
}
});
builder.setNeutralButton("Restart", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
renderView.resetGame();
}
});
builder.setNegativeButton("Main Menu", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO: Will probably improve some more on this.
PlayActivity.this.finish();
}
});
renderView.setPausingDialog(builder.create());
}
This isn't what I wanted. I tried placing them in a new thread to run, but it leaks memory, so it didn't work. Also, due to issues (Static AlertDialog methods will leak memory, etc.), I just don't have any other ideas on fixing this.
I don't know what to do next. So, may I ask, who else have a better way of initializing AlertDialogs without sacrificing performance speeds? Thanks in advance.
First thing I would do is to add some performance analysis instrumentation (measurements) to determine where the code is spending its time. Nothing is more painful than spending time trying to optimize something that doesn't need optimization ;-)
From looking at this I can see at least one simple optimization: This code creates 6 instances of 6 different anonymous classes just to handle the onClick() callbacks. IMHO that isn't necessary. You could just use this as the callback interface and make sure that your activity implements DialogInterface.OnClickListener. Then write a single method in your activity that handles all the click events:
public void onClick(DialogInterface dialog, int which) {
if (dialog == renderView.getLosingDialog()) {
if (which == DialogInterface.BUTTON_POSITIVE) {
// TODO: Polish the dialog.
// TODO: Add a method of obtaining the score from RenderView.
renderView.getStage().reset();
renderView.setDialogFlag(false);
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
PlayActivity.this.onBackPressed();
}
} else if dialog == renderView.getWinningDialog()) {
// etc...
} else if dialog == renderView.getPausingDialog()) {
// etc...
}
}
I can't guarantee that this will improve performance, but it will definitely make the garbage collector very happy :-)