0

I am trying to change background color on start of app.

Here is the method called from onCreate():

private void setBackground() {
        String[] rColors = getRandomColors();
        int rColor = new Random().nextInt(rColors.length);
        ConstraintLayout constraintLayout = (ConstraintLayout) findViewById(R.id.mainLayout);
        constraintLayout.setBackgroundColor(Color.parseColor(rColors[rColor]));
    }

This method crashes the app when trying to start it. Is there another better way to change background color in code?

getRandonColors() returns a String[] with names of some colors I defined in colors.xml

EDIT:

String[] rColors = getRandomColors();
int rColor = new Random().nextInt(rColors.length);
ConstraintLayout constraintLayout = (ConstraintLayout) findViewById(R.id.mainLayout);
int i = MainActivityNew.this.getResources().getIdentifier(rColors[rColor],"color",MainActivityNew.this.getPackageName());
constraintLayout.setBackgroundColor(i);

EDIT2:

FATAL EXCEPTION: main
                                                   Process: com.asus.wetr, PID: 12941
                                                   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.asus.wetr/com.asus.wetr.activities.MainActivityNew}: java.lang.IllegalArgumentException: Unknown color
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                       at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:148)
                                                       at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                    Caused by: java.lang.IllegalArgumentException: Unknown color
                                                       at android.graphics.Color.parseColor(Color.java:235)
                                                       at com.asus.wetr.activities.MainActivityNew.setBackground(MainActivityNew.java:214)
                                                       at com.asus.wetr.activities.MainActivityNew.setUpUIComponents(MainActivityNew.java:143)
                                                       at com.asus.wetr.activities.MainActivityNew.onCreate(MainActivityNew.java:111)
                                                       at android.app.Activity.performCreate(Activity.java:6237)
                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                       at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:148) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
CJR
  • 3,174
  • 6
  • 34
  • 78
  • This line `constraintLayout.setBackgroundColor(Color.parseColor(rColors[rColor]));` isn't going to work. You should use reflection to get the id of your color given its name. Then properly get the color resource basing on that id. – Phantômaxx Dec 19 '16 at 18:32
  • @Rotwang Thanks for your comment. How does that work? Do you have any link on it? – CJR Dec 19 '16 at 18:36
  • The same way of when you want to show a random image given its name. But this time you use `"color"` instead of `"drawable"` as the type for `getIdentifier()`. And of course, you want to use `getResources().getColor()` instead of `getResources().getDrawable()` http://stackoverflow.com/a/20550354/2649012 – Phantômaxx Dec 19 '16 at 18:42
  • @Rotwang Oh I see. I did try (added it to my post under EDIT), but it displays the same color everytime. – CJR Dec 19 '16 at 18:57
  • Show your error log. – Bryan Dec 19 '16 at 19:12
  • This part "Color.parseColor(rColors‌​[rColor])" is causing the problems @Bryan – CJR Dec 19 '16 at 19:28
  • @Carlton Yes, but what problems is it causing? Copy and paste the error log into your question. It is difficult to debug an error without knowing what that error is... – Bryan Dec 19 '16 at 19:35
  • It's actually `getResources().getColor(getIdentifier(rColors[rColor], "color", ...` – Phantômaxx Dec 19 '16 at 20:25
  • @Rotwang getColor() is depreciated, I should use ContextCompat.getColor(this, R.color.someColor) but I cant figure out how to use that with my randomcolorness? – CJR Dec 19 '16 at 22:25
  • @Bryan I added it to my post under EDIT2. IF you look under EDIT1 youll see another try but also unsuccesful one. – CJR Dec 19 '16 at 22:35
  • I got it to work, but had to update to `minSdkVersion 23`. This is how it worked: `int i = MainActivityNew.this.getResources().getColor(MainActivityNew.this.getResources().getIdentifier(rColors[rColor],"color",MainActivityNew.this.getPackageName()),null);` – CJR Dec 19 '16 at 22:46
  • `MainActivityNew.this` (if it's really required - is it?) could be replaced by `getBaseContext()` or `getApplicationContext()` – Phantômaxx Dec 19 '16 at 22:58
  • @Rotwang It is [almost always wrong](http://stackoverflow.com/a/7298955/5115932) to use `getApplicationContext()` or `getBaseContext()` instead of the activity context. – Bryan Dec 20 '16 at 14:06
  • ... if you can use it. It depends. There are cases where you **need** to use `getApplicationContext()` or `getBaseContext()` – Phantômaxx Dec 20 '16 at 15:25

1 Answers1

1

You should use a TypedArray resource instead of a String[] to store an array of colors. This will provide auto-complete and error detection for the reference to your colors, making the process less error-prone. You can do this in your colors.xml file, or create a separate arrays.xml file:

<resources>

    <array name="colors">
        <item>@color/red</item>
        <item>@color/orange</item>
        <item>@color/yellow</item>
        <item>@color/green</item>
        <item>@color/blue</item>
        <item>@color/indigo</item>
        <item>@color/violet</item>
    </array>

</resources>

Then you can reference this array in your Activity code:

private int getRandomColor() {
    TypedArray a = getResources().obtainTypedArray(R.array.colors);

    int random = new Random().nextInt(a.length());
    int defValue = ContextCompat.getColor(this, R.color.red);
    int color = a.getColor(random, defValue);

    a.recycle();

    return color;
}

Then you can call this to set the background color for the entire Window (or a specific View if you prefer):

getWindow().getDecorView().setBackgroundColor(getRandomColor());
Bryan
  • 14,756
  • 10
  • 70
  • 125