skip to Main Content

I need to create ElevatedButton that uses SvgPicture for displaying icon inside of it. I have defined foregroundColor inside ButtonStyle to resolve color in accordance with current MaterialStates. However, this foregroundColor is being applied only to Text and Icon widgets. How can I resolve this color the same way for my SvgPicture widget? Or atleast have an access to set of MaterialState of my ElevatedButton?

I tried to research the way Flutter stores set of MaterialState for ElevatedButton, but still haven’t found out it yet. Also, I came across MaterialStateMixin and as I understand its purpose is solely dedicated to create custom buttons in Flutter with the help of GestureDetector, InkWell, etc.

2

Answers


  1. To access the set of MaterialState in Flutter, you can use the MaterialStateColor class. However, it’s important to note that SvgPicture may not automatically respond to changes in MaterialState like Icon does. In such cases, you may need to manually manage the color changes for your SvgPicture.

    Here’s an example of how you can achieve this:

    ElevatedButton(
      onPressed: () {
        // Your button's onPressed logic
      },
      style: ButtonStyle(
        foregroundColor: MaterialStateColor.resolveWith((Set<MaterialState> states) {
          // Resolve color based on MaterialState
          if (states.contains(MaterialState.pressed)) {
            return Colors.red; // Change to the desired color
          }
          return Colors.blue; // Default color
        }),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          SvgPicture.asset(
            'assets/your_icon.svg',
            // Set the color manually based on MaterialState
            color: MaterialStateColor.resolveWith((Set<MaterialState> states) {
              if (states.contains(MaterialState.pressed)) {
                return Colors.red; // Change to the desired color
              }
              return Colors.blue; // Default color
            }),
          ),
          SizedBox(width: 8), // Adjust as needed
          Text('Button Text'),
        ],
      ),
    )
    

    In this example, both the foregroundColor of the ElevatedButton and the color of the SvgPicture are manually managed based on the MaterialState. Adjust the colors and conditions as needed for your specific use case. Keep in mind that SVG rendering might not fully support dynamic color changes based on MaterialState, and you may need to use alternative approaches or packages for more complex scenarios.

    Login or Signup to reply.
  2. I believe what you are looking for is MaterialStatesController which exposes the widget’s material states Set<MaterialState>.

    https://api.flutter.dev/flutter/material/MaterialStatesController-class.html

    class _SvgButtonState extends State<SvgButton> {
      late final _statesController = MaterialStatesController();
    
      @override
      void dispose() {
        _statesController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return ElevatedButton.icon(
          label: const Text('Button'),
          statesController: _statesController,
          style: ...,
          icon: ValueListenableBuilder(
            valueListenable: _statesController,
            builder: (context, value, child) { // value is Set<MaterialState>
              return SvgPicture.asset(
                'assets/...',
                colorFilter: value.contains(...) ? ... : ...,
              );
            },
          ),
          onPressed: () {},
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search