3

I have a simple question, but I wasn't able to find an answer to this. Note, that I'm almost a complete beginner.

So I have an app (it's not mine, but I'm contributing to it), and in there is writing on a color background, which can be changed by the user. The writing should appear black if the background is bright enough but stay white if it isn't.

The application is a school diary app for elementary and high-school students that connects to the state-wide school diary service in Hungary. Here, the best note is 5, the worst is 1. The user can set the colors of each grade in the settings. Right now, only the code for the note "4" is hard-coded to have black text (because the background is yellow by default on "4" notes), all others have white. This is what I want to automate.

Example of white text

Example of black text

This is the main screen of the app for reference

Page where user can change color for a kind of note

Code right now:

switch (evaluation.NumberValue) {
    case 1:
      bColor = globals.color1;
      fColor = Colors.white;
      break;
    case 2:
      bColor = globals.color2;
      fColor = Colors.white;
      break;
    case 3:
      bColor = globals.color3;
      fColor = Colors.white;
      break;
    case 4:
      bColor = globals.color4;
      fColor = Colors.black; //This should be white if color4 is dark enough. Same applies to all of them.
      break;
    case 5: //I'm looking for something like this:
      bColor = globals.color5;
      fColor = (lightLevel(globals.color5) > 50) ? Colors.black : Colors.white;
      break;
    default:
      bColor = Colors.black;
      fColor = Colors.white;
      break;
  }

I'm looking for something like this:

 case 5: //I'm looking for something like this:
  bColor = globals.color5;
  fColor = (lightLevel(globals.color5) > 50) ? Colors.black : Colors.white;
  break;

Thank you for any help!

RedyAu
  • 67
  • 1
  • 9

2 Answers2

10

I can suggest 2 options:

  1. ThemeData.estimateBrightnessForColor method e.g.
Color calculateTextColor(Color background) {
  return ThemeData.estimateBrightnessForColor(background) == Brightness.light ? Colors.black : Colors.white;
}

  1. Color.computeLuminance method e.g.
Color calculateTextColor(Color background) {
  return background.computeLuminance() >= 0.5 ? Colors.black : Colors.white;
}

Keep in mind that both are computationally expensive to calculate. The former uses the latter one under the hood. The difference is in how to compute the threshold between light and dark.

PrzemekTom
  • 1,328
  • 1
  • 13
  • 34
George Zvonov
  • 9,401
  • 5
  • 33
  • 37
  • Thank you so much! I wasn't able to get to work the first one, but it's no problem if the method is slow, it only gets called one, when the user changes the color. – RedyAu Jan 25 '20 at 23:45
  • The first one is expensive as well, cause it uses `computeLuminance` under the hood. To keep in mind. – PrzemekTom Dec 29 '21 at 11:56
  • @Przemo good point. Thank you for your contribution to the answer! – George Zvonov Dec 29 '21 at 14:16
2
Brightness.estimateBrightnessForColor method e.g.
Color calculateTextColor(Color background) {
  return Brightness.estimateBrightnessForColor(background) == Brightness.light ? Colors.black : Colors.white;
}

I found that the method estimateBrightnessForColor is now part of the class ThemeData, so need to be called like this now:

ThemeData.estimateBrightnessForColor(background)
Jorge Vieira
  • 2,784
  • 3
  • 24
  • 34