Extensão de tema em Flutter

Tempo de leitura: 2 minutes

Hoje quero compartilhar sobre a extensão Theme que vem com o Flutter v3.

O que é extensão de tema?

Se o estilo/cor personalizado desejado não couber no objeto Default ThemeData, é uma classe abstrata feita para que estilos adicionais possam ser feitos.

Assim como a classe abstrata, você pode estender a classe e criar estilos personalizados como desejar

Onde devo usá-lo?

Por exemplo, você não pode adicionar a cor desejada ao esquema de cores do ThemeData (é uma cor personalizada que precisa ser usada em um só lugar).

class CustomColorUtil {
    static Color incrementColor = Colors.green;
    static Color decrementColor = Color.red;
}

floatingActionButton: Row(
    mainAxisAlignment: MainAxisAligment.end,
    children: [
        FlottingActionButton(
            onPressed: _incrementCounter,
            background: CustomColorUtil.incrementColor,
            tooltiip: 'Increment',
            child: const Icon(Icons.add),
        ),
        const SizedBox(widht: 5),
        FlottingActionButton(
            onPressed: _decrementCounter,
            background: CustomColorUtil.decrementColor,
            tooltiip: 'Decrement',
            child: const Icon(Icons.remove),
        ),
    ],
)

Você não pode usar uma variável estática como mostrado? Por que extensão de tema?

Tudo bem se houver apenas um estilo no aplicativo, mas se você quiser mudanças dinâmicas de cores dependendo do tema claro/escuro, é mais conveniente usar o método ThemeExtension.

class CustomThemeExt extends ThemeExtension<CustomThemeExt>{
    final Color? incrementColor;
    final Color? decrementColor;
    
    CustomThemeExt({this.incrementColor, this.decrementColor});
    
    @override
    CustomThemeExt copyWith({
      Color? incColor,
      Color? decColor,
    }) {
      return CustomThemeExt(
        incrementColor: incrementColor ?? incColor,
        decrementColor: decrementColor ?? decColor,
    }
    
    @override
    CustomThemeExt lerp(ThemeExtension<CustomThemeExt>? other, double t) {
        if (other is! CustomThemeExt) {
            return this;
        }
        return CustomThemeExt(
            incrementColor: Color.lerp(incrementColor, other.incrementColor, t),
            decrementColor: Color.lerp(decrementColor, other.decrementColor, t),
        );
    }
}

Conforme mostrado na imagem, construa uma classe personalizada e declare as propriedades que deseja usar como variáveis. Aqui, você pode definir não apenas a cor, mas também o valor de preenchimento, textStyle conforme desejar.

void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
 const MyApp({super.key});  
 @override
 Widget build(BuildContext context) {
   return const MaterialApp(
     home: MyHomePage(),
     darkTheme: ThemeData.dark().copyWith(
     extensions: [
      CustomThemeExt(
       incrementColor: Colors.redAccent,
       decrementColor: Colors.green
      )
     ]),
     theme: ThemeData.light().copyWith(
      extensions: [
       CustomThemeExt(
        incrementColor: Colors.green,
        decrementColor: Colors.redAccent
       )
     ])
  );
 }
}

Quando você chegar ao local que deseja usar

Theme.of(context).extension<CustomThemeExt>()!.decrementColor

Por ser uma extensão, pode ser chamado a partir do tema.