Created
October 4, 2023 17:31
-
-
Save codesxt/33cb79bdedcf15b39231d9d89d8c8be8 to your computer and use it in GitHub Desktop.
Flutter Themes and State Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'dart:async'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
colorScheme: ColorScheme.fromSeed( | |
seedColor: Colors.deepOrange, | |
), | |
textTheme: const TextTheme( | |
displayLarge: TextStyle(), | |
), | |
useMaterial3: true, | |
), | |
darkTheme: ThemeData( | |
colorScheme: ColorScheme.fromSeed( | |
seedColor: Colors.deepOrange, | |
brightness: Brightness.dark, | |
), | |
textTheme: const TextTheme( | |
displayLarge: TextStyle(), | |
), | |
useMaterial3: true, | |
brightness: Brightness.dark, | |
), | |
themeMode: ThemeMode.dark, | |
home: const MyHomePage(title: 'Flutter Demo Home Page'), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
const MyHomePage({super.key, required this.title}); | |
final String title; | |
@override | |
State<MyHomePage> createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
int _counter = 0; | |
void _incrementCounter() { | |
setState(() { | |
_counter++; | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
backgroundColor: Theme.of(context).colorScheme.inversePrimary, | |
title: Text(widget.title), | |
), | |
body: Center( | |
child: Theme( | |
data: ThemeData( | |
brightness: Brightness.light, | |
), | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
CardCount( | |
text: 'El valor de la variable es', | |
count: _counter, | |
), | |
const TimerCard(), | |
], | |
), | |
), | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: _incrementCounter, | |
tooltip: 'Increment', | |
child: const Icon(Icons.add), | |
), | |
); | |
} | |
} | |
class CardCount extends StatelessWidget { | |
final String text; | |
final int count; | |
const CardCount({ | |
super.key, | |
required this.text, | |
required this.count, | |
}); | |
@override | |
Widget build(BuildContext context) { | |
return Card( | |
elevation: 20, | |
child: Container( | |
padding: const EdgeInsets.all(20), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
mainAxisSize: MainAxisSize.min, | |
children: <Widget>[ | |
Text( | |
text, | |
style: Theme.of(context) | |
.textTheme | |
.headlineLarge | |
?.copyWith(color: Colors.brown, fontWeight: FontWeight.w900), | |
), | |
Text( | |
count.toString(), | |
style: Theme.of(context).textTheme.headlineMedium, | |
), | |
], | |
), | |
), | |
); | |
} | |
} | |
class TimerCard extends StatefulWidget { | |
const TimerCard({super.key}); | |
@override | |
State<TimerCard> createState() => _TimerCardState(); | |
} | |
class _TimerCardState extends State<TimerCard> { | |
int count = 0; | |
@override | |
void initState() { | |
super.initState(); | |
Timer.periodic( | |
const Duration(seconds: 1), | |
(timer) { | |
count += 1; | |
setState(() {}); | |
}, | |
); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Card( | |
clipBehavior: Clip.antiAlias, | |
child: Container( | |
padding: const EdgeInsets.all(20), | |
color: Colors.green, | |
height: 50 + count * 5, | |
child: Text( | |
count.toString(), | |
style: Theme.of(context).textTheme.headlineLarge?.copyWith( | |
color: Colors.white, | |
fontWeight: FontWeight.w900, | |
), | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Este código ejemplifica la aplicación de temas globales y locales en la app. También ejemplifica el uso de Widgets tipo Stateless y Stateful en distintos contextos.
El Widget Stateless se llama CardCount. Este Widget recibe como parámetros una String y un int y los usa para mostrar el conteo de clicks realizado por el usuario al presionar el FAB (Floating Action Button). Cada vez que estos parámetros se modifican, el Widget CardCount es reemplazado rápidamente por otra instancia con los nuevos valores dando la ilusión de que sólo cambió el contador.
El Widget Stateful se llama TimerCard. Este Widget no recibe ningún parámetro, pero mantiene dentro de su estado un contador int que se inicializa en 0. En el método de ciclo de vida initState, que permite ejecutar código en la inicialización del Widget, se inicializa un Timer (de la biblioteca dart:async) que ejecuta una función una vez por segundo. En esta función se actualiza el valor de count y mediante el llamado a setState se notifica que el estado del Widget cambió. Esto hace que el Widget vuelva a llamar a la función build para redibujarse. En la función build se escribe el contador como String con counter.toString() pero también se usa para calcular la altura del Container que incluye esta variable para evidenciar que el estado puede usarse para modificar otras propiedades de los Widgets además del texto.