I want the output to be green if the counter is 20 or above and red if it is below 20. this is the code I have so far and it isnt working.
add1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
counter = counter += 1;
if (counter >= 20) {
display.setText(Color.GREEN);
//display.setText("" + counter);
}
else if (counter < 20) {
display.setTextColor(Color.RED);
//display.setText("" + counter);
}
display.setText("" + counter);
}
});
sub1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
counter = counter -= 1;
if (counter >= 20) {
display.setText(Color.GREEN);
//display.setText("" + counter);
}
else if (counter < 20){
display.setTextColor(Color.RED);
//display.setText("" + counter);
}
display.setText("" + counter);
}
});
Couple of issues with your code:
use counter += 1 instead of counter = counter += 1. Same for subtraction.
avoid duplicating code
use setTextColor() instead of setText().
add1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counter += 1;
updateDisplay();
}
});
sub1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counter -= 1;
updateDisplay();
}
});
And have this method somewhere:
void updateDisplay () {
display.setTextColor(counter < 20 ? Color.RED : Color.GREEN);
display.setText("" + counter);
}
If you're trying to change the color of the textview called display you need to switch:
display.setText(Color.GREEN);
to
display.setTextColor(Color.GREEN);
Also you can probably make your else if just an else.
Well,
As mentioned in the comments, you are trying to set the text to Color.GREEN which is a constant integer representing the green color, while you should be doing like you did in the RED case
display.setTextColor(Color.GREEN);
On a different matter, You shouldn't be using else if in that statement.
Since your first if asks, is my counter 20 or more, change color to green, and if it's under, change to red.
You only have 2 cases which overlaps the entire "spectrum" of your variable if you will.
You should use if and else in that case
counter = counter += 1;
if (counter >= 20) {
display.setTextColor(Color.GREEN);
//display.setText("" + counter);
}
else { // not 20 or above, meaning < 20
display.setTextColor(Color.RED);
//display.setText("" + counter);
}
display.setText("" + counter);
else if would be useful if you had more cases, for example
counter = counter += 1;
if (counter >= 20) {
display.setText(Color.GREEN);
//display.setText("" + counter);
}
else if (counter < 20 && counter >= 10) { // counter is between 10 and 20, not including 20
display.setTextColor(Color.RED);
//display.setText("" + counter);
}
else { // under 10, not including 10
display.setTextColor(Color.WHITE);
//display.setText("" + counter);
display.setText("" + counter);
It might be good practice to try and always have an else statement to check for an illegal value (especially if it's an input from the user). even only for a sanity check, or error handling and printing.
Related
I am developing a quiz app and i ran into an my Countdowntimer keeps showing random values in the textView i assigned to it and the Option Buttons does not revert to the color i assigned to it after it was clicked here is my code
public void selectEasy(View view){
if (view.getTag().toString().equals(Integer.toString(locationOfCorrectAnswer))){
view.setBackgroundResource(R.drawable.button_right);
score++;
} else{
view.setBackgroundResource(R.drawable.button_wrong);
if (button0.getTag().toString().equals(Integer.toString(locationOfCorrectAnswer))){
button0.setBackgroundResource(R.drawable.button_right);
}else if (button1.getTag().toString().equals(Integer.toString(locationOfCorrectAnswer))){
button1.setBackgroundResource(R.drawable.button_right);
}else if (button2.getTag().toString().equals(Integer.toString(locationOfCorrectAnswer))){
button2.setBackgroundResource(R.drawable.button_right);
}else if (button3.getTag().toString().equals(Integer.toString(locationOfCorrectAnswer))){
button3.setBackgroundResource(R.drawable.button_right);
}
}
GenerateQuestion();
}
the second method to generate random question
public void GenerateQuestion(){
question++;
Easy_score.setText(Integer.toString(score));
Easy_question.setText(Integer.toString(question) + "/"+ 10);
Easy_time.setText(10 + "s");
button0.setBackgroundResource(R.drawable.button_style);
button1.setBackgroundResource(R.drawable.button_style);
button2.setBackgroundResource(R.drawable.button_style);
button3.setBackgroundResource(R.drawable.button_style);
new CountDownTimer(10100, 1000){
#Override
public void onTick(long millinseconds) {
Easy_time.setText(String.valueOf(millinseconds / 1000) + "s");
}
#Override
public void onFinish() {
GenerateQuestion();
}
}.start();
int[] picture = {};
String[] incorrectOption = {};
Random random = new Random();
displayPicture = random.nextInt(21);
display.setImageResource(picture[displayPicture]);
answers.clear();
locationOfCorrectAnswer = random.nextInt(4);
for (int i = 0; i < 4; i++){
if (i == locationOfCorrectAnswer){
answers.add(getResources().getResourceEntryName(picture[displayPicture]));
} else {
LocationOfWrongAnswer = random.nextInt(36);
while (LocationOfWrongAnswer == displayPicture) {
LocationOfWrongAnswer = random.nextInt(36);
}
answers.add(incorrectOption[LocationOfWrongAnswer]);
}
}
button0.setText(" A. " + answers.get(0).substring(4).replace("_"," ").replace("1", "-"));
button1.setText(" B. " + answers.get(1).substring(4).replace("_"," ").replace("1", "-"));
button2.setText(" C. " + answers.get(2).substring(4).replace("_"," ").replace("1", "-"));
button3.setText(" D. " + answers.get(3).substring(4).replace("_"," ").replace("1", "-"));
}
the Countdowntimer is displaying random values when a click the button and the button does not revert to the initial color
I´m using a Chronometer in my Android App. I can start it, stop it and continue counting after pushing the start button again:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_projektbeschreibung, container, false);
if (savedInstanceState != null){
stoppedmillis = savedInstanceState.getLong(STATE_TIME);
hh = savedInstanceState.getString(STATE_HH);
mm = savedInstanceState.getString(STATE_MM);
ss = savedInstanceState.getString(STATE_SS);
}
mChronometer = (Chronometer) rootView.findViewById(R.id.chronometer2);
mChronometer.setText(hh + ":" + mm + ":" + ss);
mChronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer cArg) {
long time = SystemClock.elapsedRealtime() - cArg.getBase() ;
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
hh = h < 10 ? "0" + h : h + "";
mm = m < 10 ? "0" + m : m + "";
ss = s < 10 ? "0" + s : s + "";
cArg.setText(hh + ":" + mm + ":" + ss);
}
});
((Button) rootView.findViewById(R.id.startbutton)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//if first start
if(stoppedmillis == 0) {
mChronometer.setBase(SystemClock.elapsedRealtime());
} else {//Point A
long pausetime = (SystemClock.elapsedRealtime() - stoppedmillis);
mChronometer.setBase(mChronometer.getBase() + pausetime);
}
mChronometer.start();
}
});
((Button) rootView.findViewById(R.id.stopbutton)).setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
mChronometer.stop();
stoppedmillis = SystemClock.elapsedRealtime();
}
});
After a screen rotation (so the Activity restarts) the chronometer starts counting from the point of 00:00:00 again. My first try was to save the stoppedmillis with a onSaveInstanceState method like the following:
public void onSaveInstanceState(Bundle savedInstanceState){
savedInstanceState.putLong(STATE_TIME, stoppedmillis);
savedInstanceState.putString(STATE_HH, hh);
savedInstanceState.putString(STATE_MM, mm);
savedInstanceState.putString(STATE_SS,ss);
super.onSaveInstanceState(savedInstanceState);
}
Now, I can get the value of the stoppedmillis after a restart, but I don't know how to set the Base for the Chronometer with the help of the stoppedmillis. At Point A in the Code you can see how it works with stopping the Chronometer with a button but this part of code does not working after a screen rotation.
I know that this is old. Although, I have created a simple application using a chronometer and done the following and it has kept counting across screen rotation. It is spot on with Andrew's original answer. Here is how I outlined it:
Chronometer mChronometer; // this is a global variable
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mChronometer = (Chronometer)findViewById(R.id.chronometer);
if(savedInstanceState != null){
mChronometer.setBase(savedInstanceState.getLong("ChronoTime"));
mChronometer.start();
}
}
Now set up onSaveInstanceState:
#Override
public void onSaveInstanceState (Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putLong("ChronoTime", mChronometer.getBase());
}
Fast solution, using this class:
https://github.com/ahmedrizwan/ChronometerPersist/blob/master/chronometerpersist/src/main/java/library/minimize/com/chronometerpersist/ChronometerPersist.java
ChronometerPersist chronometerPersist = ChronometerPersist.getInstance(chronometer, sharedPreferences);
//Starting the chronometer
startChronometer();
//Stoping the chronometer
stopChronometer();
//Pausing the chronometer
pauseChronometer();
I have lost much time trying to restore the current time with the android chronometer widget.
This is how i solved saving the state of the Chronometer.
private static final int TIME_MULTIPLIER = 60;
Step 1: Convert time to Seconds:
NOTE: If you don't like my method of converting time to second you could do your ways.
private static int convertTimeToSeconds(Long... time) {
int seconds = 0;
if (time.length == 2) {
seconds += time[0] * TIME_MULTIPLIER + time[1];
} else if (time.length == 3) {
seconds += (time[0] * TIME_MULTIPLIER) + (time[1] * TIME_MULTIPLIER) + (time[2]);
}
return seconds;
}
Step 2: Setting and starting time of Chronometer
NOTE: I'm saving the data in a custom object persist that object with any database / SharedPreference / your wish.
public static void setAndStartTime(final Chronometer chronometer) {
long second = 0;
// i have multiple time saved into map. You could save just 1 time and reuse that time.
for (DailyData data : DailyData.DailyDataHolder.getDailyDataMap().values()) {
second += data.getDailyTimeSpent();
}
chronometer.setBase(SystemClock.elapsedRealtime() - (second * 1000));
chronometer.start();
}
Step 3: Saving Time:
public static void saveTime(String timeText) {
String[] timeParts = timeText.split("[:]");
long savedTime = 0;
if (timeParts.length == 2) {
savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]));
} else if (timeParts.length == 3) {
savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]), Long.parseLong(timeParts[2]));
}
DailyData.DailyDataHolder.getDailyData().setDailyTimeSpent(savedTime);
}
Calling the saved method:
ChronoHelper.saveTime(chronometer.getText().toString());
COMPLETE CLASS:
public class ChronoHelper {
private static final int TIME_MULTIPLIER = 60;
public static void setAndStartTime(final Chronometer chronometer) {
long second = 0;
for (DailyData data : DailyData.DailyDataHolder.getDailyDataMap().values()) {
second += data.getDailyTimeSpent();
}
chronometer.setBase(SystemClock.elapsedRealtime() - (second * 1000));
chronometer.start();
}
public static void saveTime(String timeText) {
String[] timeParts = timeText.split("[:]");
long savedTime = 0;
if (timeParts.length == 2) {
savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]));
} else if (timeParts.length == 3) {
savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]), Long.parseLong(timeParts[2]));
}
DailyData.DailyDataHolder.getDailyData().setDailyTimeSpent(savedTime);
}
private static int convertTimeToSeconds(Long... time) {
int seconds = 0;
if (time.length == 2) {
seconds += time[0] * TIME_MULTIPLIER + time[1];
} else if (time.length == 3) {
seconds += (time[0] * TIME_MULTIPLIER) + (time[1] * TIME_MULTIPLIER) + (time[2]);
}
return seconds;
}
public static String secondsToTimeText(DailyData dailyData) {
long savedSeconds = dailyData.getDailyTimeSpent();
long minutes = savedSeconds / TIME_MULTIPLIER;
long seconds = savedSeconds % TIME_MULTIPLIER;
long hours = minutes / TIME_MULTIPLIER;
return hours + ":" + minutes + ":" + seconds;
}
}
Save the base time of the chronometer in onSaveInstanceState and set it back in onRestoreInstanceState like this:
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putLong("ChronoTime", mChronometer.getBase());
super.onSaveInstanceState(savedInstanceState);
}
public void onRestoreInstanceState(Bundle savedInstanceState){
if((savedInstanceState !=null) && savedInstanceState.containsKey("ChronoTime"))
mChronometer.setBase(savedInstanceState.getLong("ChronoTime"));
super.onRestoreInstanceState(savedInstanceState);
}
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
A.setBackgroundColor(123455+TimeCounter*100000);
}
});
}
}, 0, 1000);
I have created a timer that his role to count the running time of the application, and i want to change the background color as long as the timer goes up. what is wrong with my script?
I think the problem comes from the value that you are passing to the setBackgroundColor method.
From the doc of the class Color we can see that:
The components are stored as follows (alpha << 24) | (red << 16) |
(green << 8) | blue.
In your code, the first value that you are passing (supposing the TimeCounter starts from 0) is 123455 which corresponds to 0x0001E23F in hexadecimal.
By decomposing it, we have:
alpha=0x00
red=0x01
green=0xE2
blue=0x3F
It gives you 0% for the alpha value which means that the color is transparent.
You are adding 100000 to this value every second. So it will take you about 166 seconds (almost 3 minutes) to have a color with an alpha value greater than 0 (but it will still be invisble as the percentage of alpha will be lower than 1%).
To fix it, you can use an offset to each color to set the alpha value to 100%. For that you just have to add 0xff000000 (4 278 190 080) to the color value.
Finally, just be sure that the color value is always lower than the maximum value 0xffffffff (4 294 967 295) and it should work.
Here is a sample code:
private int offsetColor = 0xFF000000; //offset to have 100% in alpha value
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
if (TimeCounter < 167) {
A.setBackgroundColor(offsetColor+TimeCounter*100000);
} else {
/* You just reach the limit: 0xFFFFFFFF which is White */
}
}
});
}
}, 0, 1000);
With this example you can do 166 iterations (166 seconds). You can change the value that you are adding each second to adjust the duration of your animation.
Problem is the color code set in the A.setBackgroundColor();
I have simple and logical solution of this:
1.make color array like this
int[] colors=new int[]{Color.BLACK,Color.BLUE,Color.GREEN,Color.RED,Color.YELLOW};
int i=0;
set color of array by its index as i increments in Runnable:
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
A.setBackgroundColor(colors[i]);
i++;
if(i==5){
i=0;
}
}
});
}
}, 0, 1000);
See I have create new application for your color change as you required.:
public class MainActivity extends Activity {
ImageView iv;
int red = 255, green = 0, blue = 0;
int i = 0;
int a = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.imageView1);
// m.postScale(2f, 2f);
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
iv.setBackgroundColor(Color.argb(a, red, green, blue));
Log.d("main", "i: " + i + " a:+ " + a + " red: " + red
+ " green: " + green + " Blue: " + blue);
a = a + 30;
// set 30 to 60 for more difference
if (a > 250) {
a = 30;
i++;
if (i == 1) {
red = 0;
green = 255;
blue = 0;
} else if (i == 2) {
red = 0;
green = 0;
blue = 255;
} else if (i == 3) {
red = 255;
green = 0;
blue = 0;
}
if (i == 3) {
i = 1;
}
}
}
});
}
}, 0, 1000);
}
}
Now Enjoy Good Luck ..
I am making a math app. I have two arrays with two sets of numbers. I make the app choose a random number from each array. The app displays that two numbers in a TextView. It asks the user to type in a EditText what the addition of the numbers is. Then when the user presses "Submit", the app will then tell the user if they are right or wrong.
The app works, but I have one main problem. If the user does not type anything in the EditText and presses "Submit", the app force closes. I have looked at other questions asking how to check if a EditText is empty. I tried different methods but it still does not work.
public class MainActivity extends Activity {
Button submitb, startb, idkb;
EditText et;
TextView tv, rig, wron;
int arrone[] = { 24, 54, 78, 96, 48, 65, 32, 45, 95, 13, 41, 55, 33, 22,
71, 5, 22, 17, 13, 29, 63, 72, 14, 81, 7 }; // One Set of Numbers//
int arrtwo[] = { 121, 132, 147, 79, 82, 723, 324, 751, 423, 454, 448,
524, 512, 852, 845, 485, 775, 186, 99 }; // Another set of Numbers//
int random1, random2, add;
int wrong = 0;
int right = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list();
startb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int num = (int) (Math.random() * 25);
int mun = (int) (Math.random() * 19);
random1 = arrone[num];
random2 = arrtwo[mun];
String yu = (random1 + " + " + random2 + " =");
tv.setText(yu);
et.setHint("");
idkb.setVisibility(0);
startb.setText("Next Question");
}
});
startb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int bread2 = 0;
if (bread2 == 0) {
Toast.makeText(getApplicationContext(),
"You didn't answer the question!",
Toast.LENGTH_LONG).show();
}
int swag = random1 + random2;
String bread = et.getText().toString();
bread2 = Integer.parseInt(bread);
if (bread2 == swag) {
startb.setText("Next Question");
tv.setText("Correct");
et.setText("");
et.setHint("Click Next Question");
right++;
rig.setText("Right:" + right);
rig.setTextColor(Color.parseColor("#14df11"));
bread2 = 0;
}
else if (bread2 == 0) {
tv.setText("Wrong, the correct answer is " + swag + ".");
startb.setText("Next Question");
et.setText("");
tv.setHint("Click Next Question");
wrong++;
wron.setText("Wrong:" + wrong);
wron.setTextColor(Color.parseColor("#ff0000"));
bread2 = 0;
}
else {
tv.setText("Wrong, the correct answer is " + swag + ".");
startb.setText("Next Question");
et.setText("");
et.setHint("Click Next Question");
wrong++;
wron.setText("Wrong:" + wrong);
wron.setTextColor(Color.parseColor("#ff0000"));
bread2 = 0;
}
}
});
idkb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int swag = random1 + random2;
tv.setText("The Correct Answer is " + swag + ".");
et.setText("");
tv.setHint("Click Next Question");
wrong++;
wron.setText("Wrong:" + wrong);
wron.setTextColor(Color.parseColor("#ff0000"));
}
});
}
private void list() {
submitb = (Button) findViewById(R.id.b1);
startb = (Button) findViewById(R.id.b2);
et = (EditText) findViewById(R.id.et1);
tv = (TextView) findViewById(R.id.tv1);
rig = (TextView) findViewById(R.id.rtv);
wron = (TextView) findViewById(R.id.wtv);
idkb = (Button) findViewById(R.id.idk);
}
Few points to consider:
you are setting OnClickListener on startb twice, is it just a typo?
in the second onClick(), you have a condition:
int bread2 = 0;
if (bread2 == 0) {
//rest of code
}
This condition will ALWAYS be satisfied, is that what you want?
you can check if there's nothing entered by use with the following:
String bread = et.getText().toString();
// check if there is any text entered by user
if (bread.length() > 0) {
bread2 = Integer.parseInt(bread);
if (bread2 == swag) {
startb.setText("Next Question");
//the rest of the code
}
Not sure I'm understanding you correctly, but it should be easy as:
et = (EditText) findViewById(R.id.et1);
String bread = et.getText().toString();
if (bread.length() == 0){
// raise error dialogue
} else {
// continue to check the parsed integer
}
This should all be done within your click listener.
You need to use findViewById on the et before gets its value.
By the way, you are setting bread2 value to 0, and on the next line verifying if it's 0, i suppose it's just a test, isn't it?
#Override
public void onClick(View v) {
int bread2 = 0;
if (bread2 == 0) {
Toast.makeText(getApplicationContext(),
"You didn't answer the question!",
Toast.LENGTH_LONG).show();
}
int swag = random1 + random2;
et = findViewById(R.id.yourEditText);
String bread = et.getText().toString();
bread2 = Integer.parseInt(bread);
//...
Hope it helps!
I think it good practice to check text length, for example this function can help you..
public boolean isEditTextEmpty(EditText input){
if(input.getText().length() == 0)
return true;
else
return false;
}
if (et.getText().length == 0 || et.gettext == null ){
// do nothing
} else {
// do whatever here
}
this should works fine
for (int i=0; i<HisXArray.size(); i++) {
ycoord2 = HisYArray.get(i);
major2 = HisMajorArray.get(i);
xcoord2 = HisXArray.get(i);
minor2 = HisMinorArray.get(i);
time3 = TimeArray.get(i);
timer = new CountDownTimer(time3, 1000) {
#Override
public void onFinish() {
Log.e("Timer", xcoord2 + " " + ycoord2 + " " + time3);
mView.mFadePaint.setColor(Color.BLACK);
mView.drawOval(mView.mCanvas, xcoord2, ycoord2, 2*major2, 2*minor2, mView.mFadePaint);
mView.invalidate();
}
#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
}
}.start();
When I'm trying to draw something using timer, onFinish called only when time3 = 0 and when i = HisXArray.size() - 1, i.e. the last.
Implement any intermediate steps in onTick(). By design, onFinish() is only called when the countdown is complete.