from what I've read so far, it's bad practice/impossible to loop and have an AlertDialog pop up each time. But I haven't found anything alternatives to satisfy that functionality.
The example is: get a cursor from a DB and loop through each item. while looping through do a comparison on a text field. If they don't equal each other, show an alert to decide what to do ie. append, overwrite or skip the text.
thanks
You could also collect the information and use a list view instead that offers options per conflict. The popup way will drive people mad and nobody is going to use it more than once.
Loop through the cursor to read each element (Here I am considering it to be a list). If the trigger condition is met, set boolean WAITING to true, call showDialog() and finally call a waiting loop. This waiting loop will ensure that the parent for loop waits untill the user responds to the inflated dialog from the showDialog().
for(int count =0 ; count<100 ; count ++)
{
if(List.get(count).ID != InputValue)
{
WAITING=true;
showDialog(List.get(count).ID , InputValue);
while(WAITING);
}
}
In showDialog() first create the Dialog and setCancelable() to false so that user has to click on one of the three buttons(append, overwrite or skip) to disable the dialog. Then handle click events for these three, do the required DB operation and finally set WAITING=false and Hide the dialog. This will resume the parent for loop.
showDialog(String DB_Value, Input)
{
Show Dialog with option Buttons and Set dialog.setCancelable(false);
On click of any of one of the three buttons(append, overwrite or skip)
1. do the required DB action
2. hide the dialog
3. WAITING= false
}
Hope this helps you!
Related
I have a classic implementation of a recycler view that, when I click on an item inside the recycler view, that item gets deleted.
The problem is that, when I successively click twice one after another (without any noticeable delay between the clicks) on an item in that recycler view, then the second click on that same item is registered at a different position.
The way I identify the item that received the click is by holder.adapterPosition (where holder is an instantiation of ViewHolder class). I wonder if I'm doing wrong by relying on this.
To further troubleshoot, I added the following println statement to troubleshoot:
println("layoutpos ${holder.layoutPosition} adapterpos ${holder.adapterPosition} oldpos ${holder.oldPosition}")
Then, as I repeated those successive clicks, I got the following output in Android Studio's Run tab:
[Galaxy_Nexus_API_22 [emulator-5554]]: I/System.out: layoutpos 1 adapterpos 1 oldpos -1
[Galaxy_Nexus_API_22 [emulator-5554]]: I/System.out: layoutpos 0 adapterpos -1 oldpos -1
Right now, my thoughts are: use adapterPosition, and ignore it when its value is -1 (assume that -1 means a declaration of a racing condition). But I feel that I might be missing something deeper.
How should I handle this situation?
Show the user that the system is refreshing while you're disabling the user from deleting a new object until the previous transaction is completed.
I found two solutions:
if (holder.adapterPosition == -1) return // Race condition; do nothing
// else, do stuff
This does the trick. However, it is not elegant in my view, as: why receive clicking events to begin with if we are not supposed to? It doesn't seem to be solving the problem from its roots.
To solve it more elegantly (from its roots), I did this in the setOnClickListener:
holder.item.setOnClickListener {
// we don't want 2nd click right? so let's delete the listener
holder.item.setOnClickListener{}
/* then, do the stuff for this listener. this stuff
will be done once, as we deleted its listener earlier,
so, subsequent clicks are not possible. */
}
This way, the item with that listener is clicked on once, and a second click does not happen to begin with, hence a racing condition is not possible from its roots. Because the clicking listener is deleted right when the first click is received. Should I want to allow the item to get clicks again, I can redefine a listener for it again.
My app consists of multiple spinners to allow users to quickly fill out a form. I am trying to add a feature where if the user cannot find the best answer in a spinner, there is option at the bottom of the spinner labeled "add answer".
I understand how to register when "add answer" is clicked, and open a AlertDialog with a TextView entry:
case R.id.C1Lspin:
if(C1LSpin.getSelectedItem() == "Add Option..."){
addOption(C1LAdapter); //call AlertDialog
}
break;
My issue is on return from the AlertDialog I am struggling to notify which list of spinner options should be updated. My instinct is to bundle the specific spinner's arrayAdapter so that when I override the AlertDialog positive button it can use the arrayAdapter that had been bundled.
Is there any way to bundle an arrayAdapter to be passed through an AlertDialog. I am also wondering if there is any other way to notify the override function of the AlertDialog so it know which Spinner arrayAdapter to update. I am planning on having about 10 spinners so I really don't want to create a specific AlertDialog for each spinner.
I ended up using a class reference variable.
I set the reference before I start the asynchronous process, then on return from the process the reference variable is grabbed, then used, and set to null to avoid any data leak.
Not fancy or sleek but for now it works.
I have a kind of form with 3 Spinners. The content of 2 Spinners (minorSpinner) depends on the selection of the first one (mainSpinner). To be more precise, I set the content of those 2 minorSpinner in the mainSpinner's onItemSelected listener.
The form can be saved and load back again.
The problem is:
When I am trying to load the form, first I set the mainSpinner and then minerSpinners.
Like:
mainSpinner.setSelection(value);
minorSpinner1.setSelection(value1);
minorSpinner2.setSelection(value2);
Unfortunatelly the minorSpinners are not ready in time. Maybe because their values are set in the UI Thread?
Question:
how to wait until they are ready?
What I tried:
runOnUIThread(){
mainSpinner.setSelection(value);
minorSpinner1.setSelection(value1);
minorSpinner2.setSelection(value2);
}
but ti does not work:(
Any idea?
how to wait until they are ready?
So my first idea is to register OnItemSelectedListener() for all Spinners.
Then create two boolean variables for example isSpinnerOneSelected, isSpinnerTwoSelected and when you'll select item from Spinner, assign variable to true.
Then create some Thread (with Handler) that will control your states. If both variables are assigned to true, just make action with third Spinner.
If you don't know how to use Handler, look at:
How to run a Runnable thread in Android?
In my application I have a list of questions stored in an ArrayList, and I want to display a dialog that shows one question, and then continues to the next one after the question is answered. The way that I'm currently doing it (iterating through a loop) hasn't been working because it just layers all of the dialogs on top of one another all at once which causes a host of other issues. What I'm looking for is a way to still iterate through the questions, but just change the layout of the dialog each time until it has finished each question in the list. Can anyone give me a good pointer for how to get this going?
You can make a function that takes title and message as parameters and shows a dialog.
showDialog(String title, String message){ // Show dialog code here}
Within that dialog's answer button's listener call another function (showQuestion(currentQuestion)) that iterates the arrayList till it is over
int currentQuestion=0;
ArrayList<QuestionObject> questionList;
showQuestion(int i){
if(i<questionList.size()){
showDialog(questionList.get(i).getTitle,questionList.get(i).getMessage);
currentQuestion++;
}else{
//quiz is over
}
}
I assume you mean that you just want to change 1 single layout(created within XML i.e main.xml). In order to do this, make sure that the class your working on is pointing to that layout. From there (assuming your using an Event listener for when the user submits an answer) you can change do as you want by the following:
TextView txt = (TextView) findViewById(R.id.textView); // references the txt XML element
and in your Event listener, if the answer is correct then change(Have i be a global variable thats initially set to 0).
if(i<arrayList.size()){
txt.setText(arrayList.get(++i));
}else{
txt.setText("You Finished");
}
From there, in the else statement, you can change arrayLists and reset i to 0;
If you are trying to use the positive, neutral, and negative buttons; then you may have problems with multiple dialogs. Try defining a customized layout with your own TextViews, ListViews, and Buttons. You can implement listeners and everything else like a regular layout. Then just pass your customized layout to the dialog through AlertDialog.Builder.setView().
PS If you include code examples of what you are currently doing we can provided answers that are less vague.
I want my application can get user's input of time (HH:mm) from EditText widget.
Based on this time value my app needs to show a dialog when current time matches entered time.
Gaauwe
*Edit*
I want to place an EditText widget in my app.
A user will fill it with some time value (e.g. 10:30).
Then when real time (10:30) come up a dialog will be shown.
I think you can use the AlarmManager for this.
I d suggest you have a look at some tutorials like these to help you get started
http://michael.theirwinfamily.net/articles/android/android-creating-alarm-alarmmanager
http://android.arnodenhond.com/tutorials/alarm-notification
That is not too difficult. When user finished editing you EditText, read the time value and create instance of AlarmManager with start time calculated as difference between current time and whatever user wrote in the EditText. Better to use TimePicker to avoid parsing user`s input. Add receiver for you AlarmManager, receiver will start Service which will show dialog or do anything you want. You need to use AlarmManager because if your device is sleeping nothing will wake it up except system call like AlarmManager. #Zortkun 's post with links will help you to figure out how manage AlarmManager.
try this :
use the service : then when user enter time starts a service when system time and user entered time match the shows..
You can pull the data out of the EditText with:
findViewById(R.id.yourEditText).getText().toString();
The rest of your question I didn't understand.
RAW WAY!
So when user put text inside edittext and click button, you could save text in this way:
String time = findViewById(R.id.yourEditText).getText().toString();
and start a thread that check for time, and when time is equal to user's string time, you can show a dialog :)
Thread t = new Thread(new Runnable(){
public void run(){
while(new Date().getLocalTime()!=usersTime){ // is just pseudocode
Dialog.show();
}
}
});
I'll try to understand...
Seeing as you know how to pull the text from an EditText, you'll need an if statement.
Something that compares that time to the current time.
if (editTime == realTime) {
Toast.makeText(getApplicationContext(), "RING RING RING",
Toast.LENGTH_SHORT).show();
}
Use something like this:
Read this to figure out how to get a string of current time.