StillLearningToCode
StillLearningToCode

Reputation: 2461

setting the background color of a view dynamically

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

Answers (3)

Arnold de Roij
Arnold de Roij

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

Booger
Booger

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

Alexander Zhak
Alexander Zhak

Reputation: 9282

Exclude "0x" part from your number string

Upvotes: 0

Related Questions