Tag: Color

Flutter: How to Create a Color from a Hexadecimal Color String

colored pencils

In Flutter, you can create a color from a hexadecimal color string value using the Color class. The Color class takes a 32-bit integer value as an argument, where the first 8 bits represent the alpha channel (transparency) and the remaining 24 bits represent the red, green, and blue channels.

To create a color object from a hexadecimal color string value, you need to pass the value to the Color() constructor. For example, to create the color red, you can use the following code:

Color color = Color(0xFFFF0000);

To create a color from a hexadecimal string value, you need to convert the string to a 32-bit integer value first. Here’s an example of how to do it:

String hexColor = "#FF0000"; // red color
Color color = Color(int.parse(hexColor.substring(1, 7), radix: 16) + 0xFF000000);

In the above code, the substring(1, 7) method is used to remove the “#” character from the hexadecimal color string. The int.parse() method converts the remaining string into a 32-bit integer value using the radix argument, which specifies that the string is in base 16 (hexadecimal). The + 0xFF000000 part adds the alpha channel value of 255 (fully opaque) to the color value.

Colors with Transparency

You can also create colors with transparency using an eight-digit hexadecimal color string value. The first two digits represent the alpha channel, which controls the opacity of the color. For example, to create a semi-transparent red color, you can use the following code:

Color semiTransparentColor = Color(0x80FF0000);

Or for a given string value:

String hexColor = "#FF0000"; // red color
Color semiTransparentColor = Color(int.parse(hexColor.substring(1, 7), radix: 16) + 0x80000000);

Here, 0x80FF0000 is the hexadecimal color value for red with 50% transparency. The first two digits “80” represent the alpha channel, and the remaining six digits represent the color components.

Usage in Widgets

You can now use the color object to set the color of any widget in your Flutter application:

Container(
  color: color,
  child: ...
)

You can also use the color object as a parameter in some widgets, such as the IconButton widget. Here’s an example:

IconButton(
  icon: Icon(Icons.add),
  color: color, 
  onPressed: () {}, 
)

Foto von Ramakant Sharda auf Unsplash

 

Flutter: how to create a better MaterialColor from Color

toucan

In Flutter, MaterialColor is a class that defines a color palette to be used within a Material Design app. It creates a set of shades for a given primary color, which can be used in various components of the UI, such as buttons, text fields, and navigation bars. MaterialColor objects can be created from a single color value and then generate shades based on a specified brightness factor. This allows for a consistent and harmonious color scheme throughout the app.

To create a MaterialColor from a Color, you can use the MaterialColor class in Dart. The MaterialColor constructor takes two arguments:

  • The value of the color in RGB.
  • A map of shades of the color with keys representing the shade level and values representing the Color of that shade.

Let’s say we want to create a MaterialColor from the RGB color 176 / 255 / 38:

color palette

To use an implementation, let’s create a static method in a MaterialColorGenerator class and call:

Color color = Color.fromARGB(255, 176, 255, 38);
MaterialColor material = MaterialColorGenerator.from(color);

Now there are different ways to define the shades. Most tutorials propose to change the opacity for each shade, which will result in such a code:

import 'package:flutter/material.dart';

class MaterialColorGenerator{
  static MaterialColor from(Color color) {
    return MaterialColor(color.value, <int, Color>{
      50: color.withOpacity(0.1),
      100: color.withOpacity(0.2),
      200: color.withOpacity(0.3),
      300: color.withOpacity(0.4),
      400: color.withOpacity(0.5),
      500: color.withOpacity(0.6),
      600: color.withOpacity(0.7),
      700: color.withOpacity(0.8),
      800: color.withOpacity(0.9),
      900: color.withOpacity(1.0),
    });
  }
}

Let’s take our color example and look at the result:

color palette
Color values from shade50 (top) to shade900 (bottom).

This is a good result for lighter colors, but results in very similar colors for the “darker” shades. To create some real color variations, it’s better to adjust the color values itself by using:

import 'package:flutter/material.dart';

class MaterialColorGenerator{
  static MaterialColor from(Color color) {
    List strengths = <double>[.05];
    final swatch = <int, Color>{};
    final int r = color.red, g = color.green, b = color.blue;

    for (int i = 1; i < 10; i++) {
      strengths.add(0.1 * i);
    }
    for (var strength in strengths) {
      final double ds = 0.5 - strength;
      swatch[(strength * 1000).round()] = Color.fromRGBO(
        r + ((ds < 0 ? r : (255 - r)) * ds).round(),
        g + ((ds < 0 ? g : (255 - g)) * ds).round(),
        b + ((ds < 0 ? b : (255 - b)) * ds).round(),
        1,
      );
    }
    return MaterialColor(color.value, swatch);
  }
}

Let’s take our color example and look at the result:

color palette
Color values from shade50 (top) to shade900 (bottom).

Now the result is good for “darker” shades (> 500), but there is less variation for the “lighter” colors. Let’s find a version that combines both of the advantages:

import 'dart:math';
import 'package:flutter/material.dart';

class MaterialColorGenerator{
  static MaterialColor from(Color color) {
    return MaterialColor(color.value, {
      50: tintColor(color, 0.9),
      100: tintColor(color, 0.8),
      200: tintColor(color, 0.6),
      300: tintColor(color, 0.4),
      400: tintColor(color, 0.2),
      500: color,
      600: shadeColor(color, 0.1),
      700: shadeColor(color, 0.2),
      800: shadeColor(color, 0.3),
      900: shadeColor(color, 0.4),
    });
  }

  static int tintValue(int value, double factor) =>
      max(0, min((value + ((255 - value) * factor)).round(), 255));

  static Color tintColor(Color color, double factor) => Color.fromRGBO(
      tintValue(color.red, factor),
      tintValue(color.green, factor),
      tintValue(color.blue, factor),
      1);

  static int shadeValue(int value, double factor) =>
      max(0, min(value - (value * factor).round(), 255));

  static Color shadeColor(Color color, double factor) => Color.fromRGBO(
      shadeValue(color.red, factor),
      shadeValue(color.green, factor),
      shadeValue(color.blue, factor),
      1);
}

Let’s take our color example and look at the result:

color palette
Color values from shade50 (top) to shade900 (bottom).

This is a much better result, which corelates with the color palettes of the Material Design. This implementation is also used by the material_color_generator package.

Foto von Zden?k Machá?ek auf Unsplash.