Google decided to make a single-threaded user interface that doesn't have modal dialogs. I'm sure most of you have found that nothing updates until your function returns because everything is event driven on a single thread (by "law").
If I have a simple alert-box, such as "Are You Sure?" (example only), with a Yes and No button, then I have to assign callbacks to the buttons rather than having a simple return value (no modal dialogs). That's fine, even though a return value would vastly simplify my problem (arguments stay local to the caller), although this would stop the calling activity from responding (modal).
Imagine now if I have a list of items and the user attempts to perform some operation. The dialog must now have some way to pass WHICH item I want to perform the operation on to the button's callback, but I can't seem to find any mechanism in the API for passing this along to the onclick handler. Using non-local variables is a work-around, but messy.
How can I pass this information along cleanly? Does anyone have some sort of hack that would somehow "fake" a modal dialog that can return a value (I'm not seeing how).
Create a custom dialog that extends the default android Dialog and add the information you need and pass on the constructor.
See more here: How can I pass values between a Dialog and an Activity?
I am not sure what exactly what do you want to achieve. Not sure if your problems is in the communication between the activity to the dialog or dialog to the activity or both.
Anyway, I have some experience on Android and I really recommend you to achieve the communication between activities, fragments, even dialog (DialogFragments) to use one of these libraries. At the beggining could be a little bit hard to understand how work, but the result is faster and cleaner code, of course offers you more flexibility.
Take a look to:
https://github.com/beworker/tinybus --> less used but it is awesome
https://github.com/greenrobot/EventBus --> more extended and used for the community
Hope to help you!
In a situation like this, I Created a new string array entry in the strings.xml in values folder like this:
<string-array name="array">
<item>1</item>
<item>2</item>
</string-array>
And then create a dialog using Dialog builder like this:
AlertDialog.Builder dialog=new AlertDialog.Builder(this);
LayoutInflater infl=this.getLayoutInflater();
Resources res=getResources();
dialog.setSingleChoiceItems(R.array.alphabets, 0,new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mReturnVariable=which;
}
});
dialog.create().show();
So the mReturnVariable contains the user selected item index .Hope that solves the problem
I passed the required arguments to the Alert Dialog using View Binding in Android Latest version.
private ConnectDialogBinding connectDialogBinding;
private String chargerID;
private void connectDialog() {
// Create the object of
// AlertDialog Builder class
AlertDialog.Builder builder = new AlertDialog.Builder(ConnectActivity.this);
connectDialogBinding = ConnectDialogBinding.inflate(getLayoutInflater());
builder.setView(connectDialogBinding.getRoot());
connectDialogBinding.txtID.setText(chargerID);
builder.setCancelable(false);
// Create the Alert dialog
AlertDialog alertDialog = builder.create();
// Show the Alert Dialog box
alertDialog.show();
connectDialogBinding.cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alertDialog.cancel();
}
});
}
enter image description here
Related
I repair big android app and I have many custom dialogs which inherit from various types of standard android dialogs (AlertDialog, ProgressDialog, ...).
I have to add option "setCanceledOnTouchOutside(false)" for all dialogs in app, because in ICS we have this option set on true by default android 4.0 Dialog gets canceled when touched outside of dialog window
I can add line "*dialog.setCanceledOnTouchOutside(false)" for every dialog in my project, but this is hard to maintanence solution.
I can't inherit from MyDialog which inherit from Dialog, because I inherit from AlertDialog, ProgressDialog,... too.
Probably the best solution would be set all dialogs option for whole project in one place or make any hack that give us by default behavior from older android version than ICS, but I don't know if it is possible and how to do this?
Can You advise me?
have all the dialogs implement a common interface, like this,
interface DialogSettings {
void setCancelOnTouchOutside(boolean cancel);
}
now implement a stand-alone version of this,
class VersionAwareDialogSettings implements DialogSettings {
private final Dialog d;
DialogSettingsImpl(Dialog d) {
this.d = d;
}
#Override
void setCancelOnTouchOutside(boolean cancel) {
if (Build.Version.SDK_INT ...) {
d.setCancelOnTouchOutside(cancel);
}
}
}
now, in all your dialog classes, implement this interface, like this,
class MyDialog extends AlertDialog implement DialogSettings {
...
#Override
public void setCancelOnTouchOutside(boolean cancel) {
new VersionAwareDialogSettings(this).setCancelOnTouchOutside(cancel);
}
}
this can seem like a lof of cruft, but it's a nice separation of concerns. if you want to add a version-aware dialog setting, change the interface, and all parts of your code that you need to modify are flagged. if you need to change the impl of a verison-aware dialog setting, just change it in one place: VersionAwareDialogSettings.
you should be more concerned with writing correct code than trying to cut down on the number of lines you write. i don't know about you, but i can type much faster than i think. my brain is the bottleneck.
I want to show a dialog when the user clicks on an option menu inside an Activity. I first wanted to do this using the Dialog class. The code is something similar to the one below.
final Dialog d = new Dialog(this);
d.setContentView(R.layout.customDialog);
d.setTitle("Sample title");
data = (EditText) d.findViewById(R.id.data);
button = (Button) d.findViewById(R.id.aButton);
d.show();
button.setOnClickListner(new View.OnClickListner() {
// grab data from edittext and save it to some var
d.dismiss();
});
Something like that. The dev guide suggests I not instantiate directly a Dialog class. Is there something particularly bad about this approach ?
The android dev guide adds a lot of extra info to help developers avoid tasks which take up a lot of processing time. Instantiating a Dialog class directly probably takes up a lot more processing time.
The system keeps a cache of dialogs, so you don't have to manage it yourself. Each dialog is created only once and stored somewhere so it can be reused later. That's because creating a dialog is computationally expensive, I guess. The system gives you the hooks to create the dialog the first time it's needed and to prepare it just before showing
I am using the android dateslider custom dialog class in order to let the user edit the date for several different rows of a table.
The dateslider lets you limit the user to only select dates between a minimum date and maximum date that you can specify.
Each table row requires the dateslider to limit the user to a different minimum date and maximum date, however because you specify the min and max dates inside the onCreateDialog method, I need to be able to dynamically modify these dates when the user clicks the row.
I have tried calling the onCreateDialog method again when the user clicks the dialog, and it is ran, however the new limits are not taken into account, suggesting that the originally created dialog is still used instead.
How would I go about achieving my goal?
Thanks,
Max.
If you need to change dialogs before you use them, you need to use onPrepareDialog.
Update:
The dialog that is passed in to onPrepareDialog is the dialog that was created in onCreateDialog. Modify it however you like (don't create a new one). You might have to add some setters to your custom dialog class:
protected void onPrepareDialog(int id, Dialog dialog) {
switch(id) {
case YOUR_DIALOG_ID:
YearMonthDayHourMinute myDialog = (YearMonthDayHourMinute) dialog;
myDialog.setInitialTime(initialTime);
myDialog.setMinTime(minTime);
myDialog.setMaxTime(maxTime);
break;
}
}
I've built a dialog that asks the user to pick a city from the list provided when the application first opens. The dialog works perfectly, however I want to store the user's choice so that when the app is opened a second time, it checks to see if the user has already made a selection previously. If they have, it doesn't display the dialog and defines the city variable as their previously chosen preference. And obviously, if they haven't made a selection previously (because its their first time opening the app or for some reason the app couldn't read the stored preference), it displays the dialog.
Here's my dialog in case this helps:
final CharSequence[] CityChoice = {"Austin", "Dallas/Fort Worth", "Houston", "San Antonio"};
AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
alt_bld.setIcon(R.drawable.icon);
alt_bld.setTitle("Select your city");
alt_bld.setSingleChoiceItems(CityChoice, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), "Your city is now set to "+CityChoice[item]+". To change this, go to Menu -> Preferences.", Toast.LENGTH_LONG).show();
dialog.dismiss();
}
});
AlertDialog alert = alt_bld.create();
alert.show();
edit: Oh, and by the way, although I'm picking up android programming fairly quickly (at least I think I am haha) I have to admit I'm quite new to it. So the more detailed your response the better. Thanks a ton in advance.
You could use SharedPreferences to store and retrieve the setting, which is pretty straightforward as shown here http://developer.android.com/guide/topics/data/data-storage.html
Launching the dialog based on the setting should be trivial. The setting can then be saved in the dialog's listener.
I'm trying to port one of my iPhone apps over to the Android. It was all going along swimmingly until I came to AlertDialogs. In the iPhone app, sometimes there will be more than one alert to pass to the user. When this happens, the first alert dialog will come up, and when they click it away the next one will come up.
I can't seem to get more than one dialog box to come up like that in Android. Is it possible to display back to back AlertDialogs where a second one pops up as soon as the first is finished?
You execute 2 consecutive call to 'showDialog()' after eachother and the second will show after the 1st was dismissed:
showDialog(FIRST_DIALOG_ID);
showDialog(SECOND_DIALOG_ID);
Ofcourse you also have to implement onCreateDialog().
If you feel that you will be having multiple dialogs, one after another, you could create a custom class that holds all of the information for the alert, such as the title, text, icon, etc. From there, create an arraylist to store the custom class objects. When you are done with your first dialog, remove it from the arraylist, then check to see if there are any remaining dialogs that need to be presented.
The only issue you'll run into is that it will be much more difficult if you want to have different conditions in your Confirm and Cancel options.
public class DialogObject(){
String title;
String body;
String iconName; // or just an Image asset
}
ArrayList<DialogObject> dialogList = new ArrayList<>();
When a dialog is required, add it to the list if there is a dialog already on screen
dialogList.add(new DialogObject(param1, param2, param3));
This may not be the best way, but it is an option. The ArrayList will need to be in a separate class itself so you don't lose the data when moving from screen to screen.
For example - Note the "static" keyword.
public class DialogHolder(){
public static ArrayList<DialogObject> = new ArrayList<>();
}