I'm writing a quiz application which presents the user with a question and 4 choices. When the user clicks on a choice, the app should change the colour of the correct choice to green and the colour of the incorrect choice to red. It should then wait a second before displaying the next question.
The problem is that it doesn't do the colour changes (except for the last question) and I don't understand why. I know that my android.os.SystemClock.sleep(1000) has something to do with it.
I'd appreciate it if you could tell me where I've gone wrong or if I'm going about this an incorrect way. Thanks :)
public void onClick(View v) {
setButtonsEnabled(false);
int answer = Integer.parseInt(v.getTag().toString());
int correct = question.getCorrectAnswer();
if(answer == correct)
numCorrect++;
highlightAnswer(answer,correct,false);
android.os.SystemClock.sleep(1000);
MCQuestion next = getRandomQuestion();
if(next != null) {
question = next;
highlightAnswer(answer,correct,true);
displayQuestion();
setButtonsEnabled(true);
}
else {
float percentage = 100*(numCorrect/questionsList.size());
QuizTimeApplication.setScore(percentage);
Intent scoreIntent = new Intent(QuestionActivity.this,ScoreActivity.class);
startActivity(scoreIntent);
}
}
private void setButtonsEnabled(boolean enable) {
for(Button b: buttons)
b.setEnabled(enable);
}
private void highlightAnswer(int answer, int correct, boolean undo) {
if(undo) {
for(Button button : buttons) {
button.setTextColor(getResources().getColor(R.color.white));
button.setTextSize(FONT_SIZE_NORMAL);
}
return;
}
buttons[correct].setTextColor(getResources().getColor(R.color.green));
buttons[correct].setTextSize(FONT_SIZE_BIG);
if(answer!=correct) {
buttons[answer].setTextColor(getResources().getColor(R.color.red));
buttons[answer].setTextSize(FONT_SIZE_BIG);
}
}
SystemClock.sleep(1000);
will give unexpected behaviour and may not work good for your requirement. It is better you use Handler with a delay like below.
Handler h = new Handler();
h.postDelayed(new Runnable(){
#Override
public void run()
{
//your code that has to be run after a delay of time. in your case the code after SystemClock.sleep(1000);
},YOUR_DELAY_IN_MILLISECONDS
);
Related
So I have a question, and if it's a stupid one I do apologize up front, I have tried to search for it but not sure what to search for exactly. I am trying to run a delayed task, but only if my int = 0, would this work correctly like I am wanting it to?
public static void runTask(String p)
{
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run()
{
pendingRequest = pendingRequest - 1;
if (pendingRequest == 0)
{
context.startActivity(p);
}
}
}, 4000);
}
}
What I want it to do is only run if pendingRequest is 0, but I have other activities that add to pending request after the runTask() is called. If this doesn't make any sense please let me know and I will try to reword it.
This is a bit of an obscure way to do things so seeing just this snippet I cant tell exactly what the desired behavior is, however, it should work if you make the parameter "p" final. Im also not familiar with a startActivity method that takes a string instead of an intent, but I cant tell if "context" is actually an Android Context object, but I'm assuming it is.
What I'm not sure about is why you would wait 4 seconds BEFORE decrementing pendingRequest. I would think you want to decrement, allow 4 seconds for someone else to add a pending request, and if it's still 0 after the wait start the Activity... but, again, I cant tell from the snippet.
Try this:
private static Object requestLock = new Object();
public static void runTask(final String p)
{
synchronized(requestLock)
{
if (--pendingRequest > 0) // Decrement first
{
// There are more requests
return;
}
}
// Wait 4 sec and if there are still no requests start the activity.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run()
{
synchronized(requestLock)
{
if (pendingRequest == 0)
{
context.startActivity(p);
}
}
}
}, 4000);
}
}
Note: You will also need to add a synchronized block where you increment the pendingRequests.
could anyone explain, what i'm doing wrong?
in this case below, "tt" is my TexView.
On my Oncreate() method, I have:
tt = (TextView) findViewById(R.id.ni);
tt.setText("This is a try");
and then
tt.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
String vi = tt.getText().toString().substring(tt.getSelectionStart(),tt.getSelectionEnd());
Toast.makeText(getApplicationContext(), vi,Toast.LENGTH_LONG).show();
}
});
Nothing is Shown at Onclick.
thanks.
I encountered the same problem a few days ago and I could find the following solution in the end. Delaying the process even 10 milliseconds could help interestingly. Put this in your onClick/onLongClick method, wherever you want to fetch the selected text.
For the original answer: textView.getSelectionEnd() returning start index value on Samsung Marshmallow 6.0 devices
I hope this helps those who have similar problem in the future.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
int startIndex = textView.getSelectionStart();
int endIndex = textView.getSelectionEnd();
if ((endIndex - startIndex) <= 0) {
return;
}
// UI related code here
}
}, TIME_IN_MS_TO_DELAY);
return false;
I am making an Android game modeled after the old Simon game. It is a little different in the layout as it is using a 3x3 layout of buttons. I am trying to get the buttons to light up one at a time inside the loop that randomly selects a button. The trouble I have is that all of the buttons light up at once and only the last (or first, not sure) changes back to the original color. I have tried very thoroughly to find an appropriate answer to my situation but have had no luck here or elsewhere. The button id(s) are in the butts[]. butts[0] is button 1, butts[2] ... Below is my attempt.
public void play()
{
for(int x = 0; x <= numButtons; ++x)
{
spot = randomGenerator.nextInt(9);
playMe[x] = spot;
//butts[spot].setBackgroundColor(Color.parseColor("#540115"));
handler.postDelayed(new Runna(spot), (x+1)*1000);
}
}
class Runna implements Runnable
{
public Runna(int j2)
{
butts[j2].setBackgroundColor(Color.parseColor("#540115"));
}
public void run()
{
butts[spot].setBackgroundColor(Color.LTGRAY);
}
}
I think it has to do with the value of spot. It is global to the functions and you change it every time. It runs, but at the end there is still only one spot and EVERY runnable is trying to change that same spot.
Perhaps save spot in your runnable?
class Runna implements Runnable
{
int s;
public Runna(int j2)
{
s = j2;
butts[s].setBackgroundColor(Color.parseColor("#540115"));
}
public void run()
{
butts[s].setBackgroundColor(Color.LTGRAY);
}
}
Have you tried to invalidate the button each time?
public Runna(int j2)
{
butts[j2].setBackgroundColor(Color.parseColor("#540115"));
butts[j2].invalidate();
}
I am typing a program where I need to change the background of a button for a certain amount of time, say 1 second and then it change back to the original state. I know how to set a background, I just don't know how to get it to update the UI. I am pretty sure I need to use a Handler, but even after doing research I am hazy on how they should be implemented. Please enlighten me.
i Think this is simple and will work
private void startthread() {
anihandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
updatestatusalternate();
}
};
aniThread = new Thread() {
public void run() {
sleep(1000);
anihandler.sendMessage(anihandler
.obtainMessage());
}
};
aniThread.start();
}
private void updatestatusalternate() {
if(updatestatusflag)
{
//chnge your background resource here
updatestatusflag=false;
}
else
{
//chnge your background resource here
updatestatusflag=true;
}
}
How can I highlight a button for just a certain amount of time (e.g., 1 or 2 seconds) without actually pressing it?
I assume you want to set focus for a certain period of time....
here's how you can do it:
button01.setFocusableInTouchMode(true);
button01.requestFocus();
In some htc handsets this highlights the button as green in some LG phones Yellow. The focus color is basically the device property.
After this you can apply your logic to set focus to some other object after appropriate time, so button01 will lose focus and be its normal self again.
someOtherView.setFocusableInTouchMode(true)
someOtherView.RequestFocus();
I found the solution to make it works. If someone is interested in creating a sort of karaoke, here is my code:
public void playKaraoke(final FlowLayout fl) {
//KARAOKE
mTts.setLanguage(Locale.FRENCH);
// Do something long
Runnable runnable = new Runnable() {
#Override
public void run() {
for (int i = 1;i<fl.getChildCount();++i) {
final Button btn = (Button) fl.getChildAt(i);
btn.setFocusableInTouchMode(true);
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
//progress.setProgress(value);
btn.requestFocus();
mTts.speak((String) btn.getText(),
TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue.
null);
}
});
}
}
};
new Thread(runnable).start();
}