Last active
March 23, 2022 19:54
-
-
Save craiglabenz/cec99089cdba23c8b8f31fd9005fb821 to your computer and use it in GitHub Desktop.
Demonstrates use of MaterialStateProperty API
This file contains hidden or 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'; | |
const Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData.dark().copyWith( | |
scaffoldBackgroundColor: darkBlue, | |
), | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
appBar: AppBar( | |
// If an attribute is of type MaterialStateColor, you can supply either | |
// a regular color, or a MaterialStateProperty-style resolver. | |
// backgroundColor: Colors.blueAccent, | |
backgroundColor: MaterialStateColor.resolveWith((states) => Colors.blueAccent), | |
title: const Text('Material State Properties', style: TextStyle(color: Colors.white)), | |
), | |
body: const Center( | |
child: MyWidget(), | |
), | |
), | |
); | |
} | |
} | |
class MyWidget extends StatefulWidget { | |
const MyWidget({Key? key}) : super(key: key); | |
@override | |
State<MyWidget> createState() => _MyWidgetState(); | |
} | |
class _MyWidgetState extends State<MyWidget> { | |
// Create a few FocusNodes to simulate tab-traversal, which is a bit | |
// finicky in DartPad. | |
FocusNode focusNodeOne = FocusNode(); | |
FocusNode focusNodeTwo = FocusNode(); | |
@override | |
Widget build(BuildContext context) { | |
return Center( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.spaceEvenly, | |
children: <Widget>[ | |
TextButton( | |
// Clicking a button simulates tab-traversing to that button. | |
onPressed: () => focusNodeOne.requestFocus(), | |
focusNode: focusNodeOne, | |
// Delegate color selection to a MaterialStateProperty | |
style: const ButtonStyle( | |
backgroundColor: ButtonBackgroundColor(Colors.pink)), | |
child: | |
const Text('A Button', style: TextStyle(color: Colors.white)), | |
), | |
ElevatedButton( | |
// Clicking a button simulates tab-traversing to that button. | |
onPressed: () => focusNodeTwo.requestFocus(), | |
focusNode: focusNodeTwo, | |
// Delegate color selection to a MaterialStateProperty | |
style: const ButtonStyle( | |
backgroundColor: ButtonBackgroundColor(Colors.blue)), | |
child: const Text('Another Button', | |
style: TextStyle(color: Colors.white)), | |
), | |
OutlinedButton( | |
onPressed: () {}, | |
style: OutlinedButton.styleFrom( | |
primary: Colors.orange, | |
), | |
child: const Text('Custom styled button'), | |
), | |
], | |
), | |
); | |
} | |
} | |
/// Helper which creates a contained `MaterialStateProperty<Color?>` resolver. | |
/// | |
/// Credit to Nash (https://twitter.com/Nash0x7E2) for highlighting this | |
/// opportunity in his I/O Extended Montreal talk at: | |
/// https://www.youtube.com/watch?v=CrO7_qrL_f0 | |
class ButtonBackgroundColor implements MaterialStateProperty<Color?> { | |
const ButtonBackgroundColor(this.baseColor); | |
final Color baseColor; | |
@override | |
Color? resolve(Set<MaterialState> states) { | |
Color? color = states.isFocused ? Colors.orange : baseColor; | |
Color? darkerVersion = Color.lerp(color, Colors.black, 0.7); | |
// Darken our button color for each state we want to reflect. Buttons will | |
// incrementally darken as more states are applied. | |
if (states.isHovered) { | |
color = Color.lerp(color, darkerVersion, 0.3); | |
} | |
if (states.isPressed) { | |
color = Color.lerp(color, darkerVersion, 0.3); | |
} | |
return color; | |
} | |
} | |
extension MaterialStateSet on Set<MaterialState> { | |
bool get isHovered => contains(MaterialState.hovered); | |
bool get isFocused => contains(MaterialState.focused); | |
bool get isPressed => contains(MaterialState.pressed); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment