1

I have an ElevatedButton, I give it a random color of 3 properties

    backgroundColor: MaterialStateProperty.all(Colors.primaries[Random().nextInt(Colors.primaries.length)],),
    overlayColor: MaterialStateProperty.all(Colors.primaries[Random().nextInt(Colors.primaries.length)],),
    shape: MaterialStateProperty.all<RoundedRectangleBorder>(
      RoundedRectangleBorder(
        side: BorderSide(Colors.primaries[Random().nextInt(Colors.primaries.length)], width: 3)),

I have two questions

  1. How do I make these 3 random colors not be the same (and if possible similar in color).

  2. Also in ElevatedButton I have a text to which I set the color.

      style: TextStyle(color: Colors.white),
    

Therefore, how do I make sure that the color I set to the text is not used in the backgroundColor (Preferably the color is the contrast of the text color)

Verc
  • 145
  • 1
  • 8
  • 1
    This is probably exactly what you are looking for: https://stackoverflow.com/questions/65937679/how-to-generate-3-unique-random-numbers-excluding-a-particular-no-in-dart – Colin Jul 13 '22 at 18:36

3 Answers3

1

The concept is getting a single random color and change hue to generate others based on this color. For this, we can use HSLColor system

/// return new [color] hue change by [increaseBy]
Color changeColorHue({
  required Color color,
  required double increaseBy,
}) {
  HSLColor hslColor = HSLColor.fromColor(color);
  final newHueValue = (increaseBy + hslColor.hue);

  return hslColor
      .withHue(
        newHueValue % 360 < 0 ? newHueValue : newHueValue % 360,
      )
      .toColor();
}

Now get a random from bellow and use pass color and hue like to increase.


The concept of using Set of 3 works perfectly in this case. Got idea from comment section.

Random color from original Question

Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0)

Or from primary colors

Colors.primaries[Random().nextInt(Colors.primaries.length)],

The method will return a color set.

Set<Color> getColorSet({int numberOfColor = 3}) {
  Set<Color> generatedColorSet = Set<Color>();
  while (generatedColorSet.length != numberOfColor) {
    generatedColorSet.add(
      Colors.primaries[Random().nextInt(Colors.primaries.length)],
    );

    ////* from primary colors
    // generatedColorSet.add(
    //   Colors.primaries[Random().nextInt(Colors.primaries.length)],
    // );
  }

  return generatedColorSet;
}

Get a random color

Test widget

class ColorTESt extends StatefulWidget {
  ColorTESt({Key? key}) : super(key: key);

  @override
  State<ColorTESt> createState() => _ColorTEStState();
}

class _ColorTEStState extends State<ColorTESt> {
  Set<Color> colorSet = Set<Color>();

  @override
  void initState() {
    super.initState();
    colorSet = getColorSet();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ElevatedButton(
        style: ButtonStyle(
          backgroundColor: MaterialStateProperty.all(colorSet.elementAt(0)),
          overlayColor: MaterialStateProperty.all(colorSet.elementAt(1)),
          shape: MaterialStateProperty.all<RoundedRectangleBorder>(
            RoundedRectangleBorder(
              side: BorderSide(
                color: colorSet.elementAt(2),
                width: 3,
              ),
            ),
          ),
        ),
        onPressed: () {
          setState(() {
            colorSet = getColorSet();
          });
        },
        child: Text(
          "generate New color Set",
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  }
}
Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
  • 1
    Color doesn't define deep equality, so a Set could potentially contain two items that have identical R G B values, because they would be different objects even though they have the same payloads. – Randal Schwartz Jul 13 '22 at 19:38
  • Is it set responsible to handle duplicate? How can we be sure of not having duplicate colors? – Md. Yeasin Sheikh Jul 13 '22 at 19:41
  • Also thinking about using `equatable` but how can be sure not having duplicate, seems like time-consuming operation – Md. Yeasin Sheikh Jul 13 '22 at 19:48
  • Thanks for the replay, I am checking [DeepCollectionEquality](https://api.flutter.dev/flutter/package-collection_collection/DeepCollectionEquality-class.html), can i get some reference – Md. Yeasin Sheikh Jul 13 '22 at 19:54
0
List colorsList=[Colors.blue,Colors.red,Colors.green]

Color color1= colorsList[Random().nextInt(colorsList.length) 

ColorsList.retainWhere((e) =>e! =color1) 
// this line will remove the color1 from the list. 

You can convert this as a function which returns fetched color and remove the fetched color from the list.

Lear more about retainWhere from https://api.flutter.dev/flutter/dart-core/List/retainWhere.html

Avnish Nishad
  • 1,634
  • 1
  • 17
  • 18
0

You could try something like this:

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

void main() {
  runApp(const MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Flutter Test"),
      ),
      body: Scaffold(
          body: ListView.builder(
              itemCount: 100,
              itemBuilder: (BuildContext ctxt, int index) {
                return Text(
                  "Flutter Text color example",
                  style: TextStyle(
                    color: getUniqueRandomColor(),
                  ),
                );
              })),
    );
  }
}

Map<int, bool> colorsUsed = {};
var rand = Random();

Color getUniqueRandomColor() {
  while (true) {
    //generate color
    int colorInt = rand.nextInt(8388608);

    if (!colorsUsed.containsKey(colorInt)) {
      colorsUsed[colorInt] = true;
      return Color(4294967295 - colorInt);
    }
  }
}
Erick Lanford Xenes
  • 1,467
  • 2
  • 20
  • 34