7

I am trying to achieve a custom design dynamically from my button. I have designed this button from a Container with InkWell. But I am not getting a correct way how I can set 2 different colours to this button based on received values from my API. For reference here is the button: enter image description here

In this button grey part is container background color. Then I added a image in this container. Now the red color should dynamic with height received from server. But I am not getting a correct way how I can do it.

Code Hunter
  • 10,075
  • 23
  • 72
  • 102
  • use `Stack` with 2 children: gray `Image` + `ClipRect` that clips red `Image` – pskink Jul 17 '19 at 05:16
  • take a color variable, change it's value as per the api results the setState – Fayaz Jul 17 '19 at 05:18
  • Actually I am asking different thing and you are proposing different solution. Let me tell you more specific, I need to use 2 different colors in Container as showing in image. The icon is different thing. – Code Hunter Jul 17 '19 at 05:19

2 Answers2

18

You can easily achieve this with container and linear gradient. Pass in the colors as gradient and define appropriate stops at the required percentages.

Example:

@override
Widget build(BuildContext context) {
  final Color background = Colors.grey;
  final Color fill = Colors.redAccent;
  final List<Color> gradient = [
    background,
    background,
    fill,
    fill,
  ];
  final double fillPercent = 56.23; // fills 56.23% for container from bottom
  final double fillStop = (100 - fillPercent) / 100;
  final List<double> stops = [0.0, fillStop, fillStop, 1.0];

  return Container(
    child: Icon(Icons.forward),
    decoration: BoxDecoration(
      gradient: LinearGradient(
        colors: gradient,
        stops: stops,
        end: Alignment.bottomCenter,
        begin: Alignment.topCenter,
      ),
    ),
  );
} 

Hope this helps!

Hemanth Raj
  • 32,555
  • 10
  • 92
  • 82
9

You can do it using gradient but in case you want to create your own Container to get more customization, here you have:

class MyCustomContainer extends StatelessWidget {
  final Color backgroundColor;
  final Color progressColor;
  final double progress;
  final double size;

  const MyCustomContainer({
    Key key,
    this.backgroundColor = Colors.grey,
    this.progressColor = Colors.red,
    @required this.progress,
    @required this.size,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(size / 2),
      child: SizedBox(
        height: size,
        width: size,
        child: Stack(
          children: [
            Container(
              color: backgroundColor,
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Container(
                height: size * progress,
                color: progressColor,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Usage

Center(
        child: MyCustomContainer(
          progress: 0.7,
          size: 100,
          backgroundColor: Colors.grey,
          progressColor: Colors.red,
        ),
      ),

Result

enter image description here

And of course you can customize that widget to receive a child and put it at the center.

diegoveloper
  • 93,875
  • 20
  • 236
  • 194