flutternavigationbarthemedata

How to use Theme.of(context) to add color to labelTextStyle


In the general ThemeData of my flutter app, I have the following code to give a general style to the NavigationBar. This is the way to style the label under the icon within NavigationBarTheme, based on the doc.

In the class that handles the Navigation, so elsewhere in the app, I need to add color property to the TextStyle, maintaining the other properties via Theme.of(context).

But how can I do this with WidgetStateProperty.all?

Thanks in advance!

@override
Widget build(BuildContext context) {
  return MaterialApp(
    theme: ThemeData(
      navigationBarTheme: NavigationBarThemeData(
        labelTextStyle: WidgetStateProperty.all(
          const TextStyle(
            fontSize: 16.0,
            fontWeight: FontWeight.w700,
            letterSpacing: 1.0,
          ),
        ),
      ),
    ),
  );
}

Solution

  • You can resolve the WidgetStateProperty for all the possible states (since you're applying the same style to every states anyway) to get the underlying TextStyle and use copyWith on that resolved value.

    final theme = Theme.of(context);
    
    final navigationBarTheme = theme.navigationBarTheme;
    
    // Resolve the WidgetStateProperty for all possible states to get the underlying TextStyle
    final labelTextStyle = navigationBarTheme.labelTextStyle!.resolve({...WidgetState.values})!;
    
    final newTheme = theme.copyWith(
      navigationBarTheme: navigationBarTheme.copyWith(
        labelTextStyle: WidgetStatePropertyAll(
          labelTextStyle.copyWith(color: Colors.green),
        ),
      ),
    );
    

    You can also make extension methods to help with these tasks:

    extension WidgetStatePropertyX<T> on WidgetStateProperty<T> {
      T resolveAll() => resolve({...WidgetState.values});
    
      WidgetStatePropertyAll<T> copyAll(T Function(T) transformer) {
        final newValue = transformer(resolveAll());
        return WidgetStatePropertyAll(newValue);
      }
    }
    

    And the usage is now much simpler:

    final theme = Theme.of(context);
    
    final navigationBarTheme = theme.navigationBarTheme;
    
    final newTheme = theme.copyWith(
      navigationBarTheme: navigationBarTheme.copyWith(
        labelTextStyle: navigationBarTheme.labelTextStyle!
            .copyAll((textStyle) => (textStyle!.copyWith(color: Colors.green))),
      ),
    );