Reputation: 2461
i have this small app that chooses values in a number picker and is supposed to dynamically change the background color. through log messages i have seen that the hex color value is generated correctly, but when i call set background color an error pops up and the program crashes. the error java.lang.NumberFormatException: Invalid int: "0xFF010000"....
the issue (i think) is in the setBackground() call at the bottom of ActivityMain.
here is my code:
package com.example.android.test;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.NumberPicker;
import android.widget.NumberPicker.OnValueChangeListener;
public class MainActivity extends Activity {
static final int MIN_VAL = 0;
static final int MAX_VAL = 255;
NumberPicker alphaPicker, redPicker, greenPicker, bluePicker;
View colorView;
Color bgColor = new Color();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alphaPicker = (NumberPicker) findViewById(R.id.alphaPicker);
redPicker = (NumberPicker) findViewById(R.id.redPicker);
greenPicker = (NumberPicker) findViewById(R.id.greenPicker);
bluePicker = (NumberPicker) findViewById(R.id.bluePicker);
alphaPicker.setMinValue(MIN_VAL);
alphaPicker.setMaxValue(MAX_VAL);
alphaPicker.setWrapSelectorWheel(false);
redPicker.setMinValue(MIN_VAL);
redPicker.setMaxValue(MAX_VAL);
redPicker.setWrapSelectorWheel(false);
greenPicker.setMinValue(MIN_VAL);
greenPicker.setMaxValue(MAX_VAL);
greenPicker.setWrapSelectorWheel(false);
bluePicker.setMinValue(MIN_VAL);
bluePicker.setMaxValue(MAX_VAL);
bluePicker.setWrapSelectorWheel(false);
colorView = findViewById(R.id.color_box);
colorView.setBackgroundColor(0xFF000000);
redPicker.setOnValueChangedListener(new OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
bgColor.setRedVal(newVal);
Log.v(bgColor.getRedVal(), " = redVal");
Log.v(bgColor.getColorCode(), " = color code");
colorView.setBackgroundColor(bgColor.getColorCodeAsInt());
}
});
}
}
and the color class incase you are wondering how i generated the hex value:
package com.example.android.test;
public class Color {
private String redVal;
private String blueVal;
private String greenVal;
private String alphaVal;
private String colorCode;
public Color (){
alphaVal = "FF";
redVal = "00";
greenVal = "00";
blueVal = "00";
colorCode = "0xFF000000";
}
public void generateColorCode() {
StringBuilder theColor = new StringBuilder("0x")
.append(this.alphaVal)
.append(this.redVal)
.append(this.greenVal)
.append(this.blueVal);
colorCode = theColor.toString();
}
public String getRedVal() {
return redVal;
}
public void setRedVal(Integer redVal) {
this.redVal = String.format("%02x", redVal);
generateColorCode();
}
public String getBlueVal() {
return blueVal;
}
public void setBlueVal(Integer blueVal) {
this.blueVal = String.format("%02x", blueVal);
}
public String getGreenVal() {
return greenVal;
}
public void setGreenVal(Integer greenVal) {
this.greenVal = String.format("%02x", greenVal);
}
public String getAlphaVal() {
return alphaVal;
}
public void setAlphaVal(Integer alphaVal) {
this.alphaVal = String.format("%02x", alphaVal);
}
public String getColorCode() {
return colorCode;
}
public Integer getColorCodeAsInt() {
return Integer.parseInt(colorCode, 16);
}
}
Upvotes: 1
Views: 238
Reputation: 104
1) Your int is too big, because the Integer.parseInt() function only takes a signed int as an argument.
0xFF010000 == 4294901760 // your number
0x7FFFFFFF == 2147483647 // maximum signed Integer Value
You can fix this easily by using parseLong instead
0xFFFFFFFF == 4294967295 // RGBA color format maximum
Long.MAX_VALUE == 9223372036854775807L // maximum signed Long value
Implemented in your code it would look like this:
public int getColorCodeAsInt() {
return (int)Long.parseLong(colorCode, 16);
}
2) As Alexander pointed out in his answer, don't include the "0x"-bit, the 'x' will mess up the parser.
---EDIT---
Thanks to Alexander I came up with another solution, you could always do this:
public int getColorCodeAsInt() {
// this would return hex value 0xFFFFFFF8;
return (Integer.parseInt("FFFFFFF", 16) * 16) // first 7 digits
+ Integer.parseInt("8", 16); // last digit
}
This works because the datatype int itself actually can contain RGBA data.
Upvotes: 1
Reputation: 18725
I would actually use the standard Android Color API to get the color.
Color.parseColor(colorCode);
http://developer.android.com/reference/android/graphics/Color.html#parseColor%28java.lang.String%29
Upvotes: 2