Ok,this is going to get a bit complicated, but hang with me. I have the following scenario that I cannot get to work:
Prompt the user to save (ok or cancel)
In onclick for "ok", do a Async task to get some data. Do this synchronously
Then create a custom dialog to display that data to prompt the user for more info [THIS PART DOES NOT WORK)
The do another Async task where I save the data.
So, is there an inherent problem with creating a custom Dialog inside of a AlertDialog?
The behavior that happens is that all operations run, and at the end the custom Dialog briefly appears and then disappears. It should show up before the last Async task and not let the Async task execute before it has gathered the data needed.
I have simplified the problem code to this:
AlertDialog.Builder submitDialog = new AlertDialog.Builder(this);
submitDialog.setMessage("Are you sure you want to end this Preview of the form? It will no longer be availabe for editing");
}
else {
submitDialog.setTitle("Submit?");
submitDialog.setMessage("Are you sure?");
}
submitDialog.setNegativeButton("Cancel", null);
submitDialog.setPositiveButton("OK", new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int arg1) {
// =============================
// 1st Async
// =============================
// Make synchronous since need data. Must be a task cause hitting server
Test test = null;
try {
test = new workflowTask().execute().get();
}
catch (Exception ex) {
// nothing
}
// =============================
// Customer Dialog Get more info
// =============================
// Prompt for data here...
String[] listContent = {"test1#test.com", "test2#test.com"};
// custom dialog
Dialog dialog = new Dialog(MyActivity.this);
dialog.setContentView(R.layout.dialog_email_picker);
dialog.setTitle("Select email and enter comments");
ListView emails = (ListView) dialog.findViewById(R.id.emaillist);
ArrayAdapter<String> adapter = new ArrayAdapter<String> (MyActivity.this, android.R.layout.simple_list_item_1, listContent);
emails.setAdapter(adapter);
emails.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), parent.getItemAtPosition(position).toString() + " clicked", Toast.LENGTH_LONG).show();
}
});
Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "ok clicked", Toast.LENGTH_LONG).show();
}
}
});
dialog.show();
// =============================
// 2nd Async
// =============================
new submitFormResultTask().execute();
}
}
});
submitDialog.show();
Why you don't use a viewflipper in your "unique" custom dialog? so after first click on OK you can check if first page is visible and then you can show second page and only from this moment if user press on OK you can recall the dismiss() method.
In this way, you can perform a sort of wizard with possibility to return on first view if user needs to change something. Make sense?
Just for future reference the way I solved this was to actually call the AsyncTask in the onClick of the 2nd Dialog. Kind of ugly, but I could not get anything else to work. I would have thought that so long as it was a modal dialog being run that Android would pause till its work was accomplished - it did not, it just ran the next line of code (2nd AsyncTask). So it looks something like:
AlertDialog ->
AsyncTask.get() (so synchronous)
Customer Dialog
onClick->
2nd AsyncTask
Related
So right now I have a custom listview adapter that adds another row when the user selects a item. The thing is, each item in the row should have a modification button where they can choose to add whatever modification it is (can choose more than one modification)
This is a food ordering app that when the item is selected, there should be another button in the list labeled "Modify", where a pop-up comes up and allows the user to choose what modification it wants by using checkbox. ("Less salt", "More sauce", etc). Each modification list is the same for each dish. When the user exits the popup and clicks on the same modify button, the checkboxes checked should stay there.
I originally created a Popup class where when the button is selected, there is an intent to jump to that Popup activity, but I couldn't find the relationship between the custom adapter and the Popup activity. I also tried using an AlertDialog to replace the Popup window, but could not find a way to save all the checked items and show which ones were selected before.
Here's my code
modifyBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Modification");
final CharSequence[] modify_items = orderClass.getModifyList()
.toArray(new CharSequence[orderClass.getModifyList().size()]);
builder.setMultiChoiceItems(modify_items, null, new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) {
if(isChecked){
selectedList.add(indexSelected);
selectedItems.set(position, selectedList);
}
else if(selectedList.contains(indexSelected)){
selectedList.remove(Integer.valueOf(indexSelected));
selectedItems.set(position, selectedList);
}
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
Log.d("dialog", "Showing dialog");
}
});
return view;
}
You need to put data in a holder structure(its kinda a class that holds variables)
then you can show data by index and theres is a relation between the list view index shown and the data index so when is a list view cell clicked you get the position then find it in the structure and post it to another activity or anything else to modify it remember you have to declare a flag to launch the activity else the app will crash i think its called activtyoutofbound index or something like this
I've tried to create a list view dialog to display a list of choose. My code is shown below:
LayoutInflater factory=LayoutInflater.from(this);
final View stuckLevelDialogView=factory.inflate(R.layout.report_stuck_dialog, null);
final ListView stuckLevelListViewForDialog=(ListView)stuckLevelDialogView.findViewById(R.id.report_stuck_dialog_listview);
final String[] stuckLevelList=new String[]{"1 - You can move freely","2 - You have to be aware of your movement","3 - You can move slowly","4 - There is a traffic jam","5 - There is a serious traffic jam"};
ArrayAdapter<String> adapterForDialog=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, stuckLevelList);
stuckLevelListViewForDialog.setAdapter(adapterForDialog);
final AlertDialog.Builder stuckLevelDialog=new AlertDialog.Builder(this);
stuckLevelDialog.setTitle("What stuck level is this point?");
stuckLevelDialog.setView(stuckLevelDialogView);
stuckLevelDialog.show();
However, when I choose an option, the onItemClick is executed, but the listview dialog doesn't disappear, I have to press back button manually. I've tried to debug the code for a whole day, but it has not been solved yet. Please help me. Thank in advanced!
I think you need to dismiss() the dialog in your onItemClick listener as below:
stuckLevelListViewForDialog.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> p_arg0, View p_arg1,
int p_arg2, long p_arg3) {
stuckLevelDialog.dismiss();
}
});
Use stuckLevelDialog.dismiss; at the end of onItemClick.
You can set setSingleChoiceItems in your alert dialog box with your items list, which will show a list with a radio buttons. If you want to add buttons you can else once user select any items you can dismiss the dialog.
new AlertDialog.Builder(this)
.setSingleChoiceItems(array, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// here you can do your functionality and can dismiss dialog as well
dialog.dismiss();
}
})
.show();
At the start of my Android app the user is required to choose from a list of alternatives. Here is why.
Let's assume I have a long list of items, and each item belongs to exactly one category. Each user is only interested in one specific category. Thus, when the app is started and the SharedPreferences don't contain any information about the selected category, a modal dialog should be displayed - here the user has to choose his or her category of interest. After having selected a category, only the items of that category are displayed.
So far, I tried to implement this behavior in the Activity's onCreate() method, which doesn't work obviously. The dialog is not shown or at least not long enough so that I could see it.
To be honest, I didn't expect the code to work by calling it from onCreate(). However, I was unable to find a suitable event handler in the Activity from where I could trigger the dialog.
Where should this dialog be triggered from in order to ensure the selection of a category (before any other data is loaded)?
Thanks in advance.
Here's the code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
setContentView(R.layout.activity_item_list);
...
ensureCategorySelected();
}
where the relevant method is
private void ensureCategorySelected() {
String chosenCategory = getCategoryFromSharedPreferences();
if (chosenCategory != null) {
final CharSequence[] items = getCategories();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose category");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
// handle the selection of the category
}
});
AlertDialog alert = builder.show();
}
}
You have a logic problem there. You want to show the dialog when there are still no preferences saved, and you are showing it when there are preferences saved. Change it to chosenCategory == null and it should work.
And why didn't you expect the code to work in onCreate()? I don't see a problem opening a dialog there.
Edit: I'm not quite sure if onCreate() is the correct place to show the dialog. Try putting ensureCategorySelected() in onStart() instead of onCreate().
You could also consider implementing an activity for this, which you could start with startActivityForResult().
Could someone point out a working example of a custom dialog that takes an ArrayAdapter as input and shows a selectable list.
I have tried to create a Dialog using an AlertDialog Builder as such...
final ArrayAdapter<MyObject> myAdapter = getMyobjects();
final AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle("Pick an item").setAdapter(myAdapter,
new android.content.DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int item) {
Toast.makeText(Islands.this, myAdapter.getItem(item).toString(), Toast.LENGTH_SHORT).show();
}
});
final AlertDialog alert = builder.create();
return alert;
My problem is that my dialog is not updating then i called
#Override
protected void onPrepareDialog(final int id, final Dialog dialog) {
switch (id) {
case DIALOG_GET_AVAIL_DESTS:
((AlertDialog) dialog).getListView().setAdapter( getDestinations());
break;
}
}
However the onClick listener listens to the initial set of items...
Indeed AlertDialog is implements Facade design pattern with this class behind :
http://www.netmite.com/android/mydroid/frameworks/base/core/java/com/android/internal/app/AlertController.java
And the whole code is such a mess...
I took 3 hours to try to do that, and I am going to build a dialog from scratch, using android.R.layout as a basis.
Steff
You have to make a call to
invalidateViews()
on your listview - that will cause it to redraw the view with the updates.
Since you are using onPrepareDialog(int id, Dialog dialog), I am guessing you're initially setting up the dialog in onCreateDialog(int id).
Doing so cause the system to save the dialog you initially create. In order to achieve the desired functionality, when the dialog is dismissed, tell the system to discard it by calling android.app.Activity.removeDialog(int id).
Any subsequent invocations will have your dialog regenerated through the onCreateDialog(int id) method, causing the set of items to be updated.
I'm using and ArrayAdapter to populate a ListView. After selecting and item, it displays a confirmation Y/N dialog. If the user's choice is negative, then he should be able to select another item showing the same dialog. And so on.
Here's my code:
lView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(final AdapterView<?> parent, final View v, final int index, final long id) {
Toast.makeText("Selected file"+ mFiles.get(index).getfileName(),
Toast.LENGTH_SHORT).show();
SelectedFile = mFiles.get(index);
showDialog(DIALOG_CONFIRMIMPORT_ID);
}
});
The weird thing is that while the "Toast" shows the clicked item every time, only the first selected item since the Activity is initiated is being passed to "SelectedFile". No matter how many times you click a diferent item, "SelectedFile" always assumes the same value, the value of the first clicked item, outside of this code.
Heres's my Dialog code:
Protected Dialog onCreateDialog(int id) {
switch(id) {
case DIALOG_CONFIRMIMPORT_ID:
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String message = String.format(getString(R.string.importstudentfileconfirm),SelectedFile.getfileName());
builder.setMessage(message)
.setCancelable(false)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Activity.this.finish();
// startActivity(new Intent(Activity.this, LOL.class));
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
SelectedFile = null;
dismissDialog(DIALOG_CONFIRMIMPORT_ID);
mFiles.notifyAll();
}
});
AlertDialog alert = builder.create();
return alert;
}
}
return null;
}
Thank you very much for any help!
I'm guessing this has something to do with the fact that the onCreateDialog method is only called the first time the dialog is created. So the first time you see the dialog it will have the correct filename.
After onCreateDialog is called, onPrepareDialog(...) is called. onPrepareDialog, allows you to change the dialog after it has been created, but before it gets displayed.
Remember that underneath everything, Android isn't creating a new Dialog for you every time you want to show the DIALOG_CONFIRMIMPORT_ID dialog. It is too computationally expensive to instantiate a new dialog every time. Instead, it creates it once, which causes onCreatDialog to be called, followed by the onPrepareDialog. Every other time the dialog is shown, it only calls onPrepareDialog.
Check out the following article on the Android Developer site. It explains things pretty clearly.
http://developer.android.com/guide/topics/ui/dialogs.html#ShowingADialog
So try using onCreateDialog just for initialization of stuff that won't change between showings of the dialog, then use the onPrepareDialog method to dynamically update the contents of the dialog (i.e. getting the new filename)
Cheers!