mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 22:09:06 +00:00
Update experimental demo app (#1427)
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This sample Flutter app showcases Material 3 features in the Flutter Material library. These features include updated components, typography, color system and elevation support. The app supports light and dark themes, different color palettes, as well as the ability to switch between Material 2 and Material 3. For more information about Material 3, the guidance is now live at https://m3.material.io/.
|
This sample Flutter app showcases Material 3 features in the Flutter Material library. These features include updated components, typography, color system and elevation support. The app supports light and dark themes, different color palettes, as well as the ability to switch between Material 2 and Material 3. For more information about Material 3, the guidance is now live at https://m3.material.io/.
|
||||||
|
|
||||||
This app also includes new M3 components that haven't landed in the Flutter stable channel, such as IconButtons, Chips and TestFields. The app will be migrated to the non-experimental directory in the samples repo once all the components land in the stable branch. For more information about the components in the stable channel, please check the "material_3_demo" in the non-experimental directory.
|
This app also includes new M3 components that haven't landed in the Flutter stable channel, such as IconButtons, Chips, TextFields, Switches and Checkboxes. The app will be migrated to the non-experimental directory in the samples repo once all the components land in the stable branch. For more information about the components in the stable channel, please check the "material_3_demo" in the non-experimental directory.
|
||||||
|
|
||||||
# Preview
|
# Preview
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ This app also includes new M3 components that haven't landed in the Flutter stab
|
|||||||
<img src="https://user-images.githubusercontent.com/36861262/166511137-85dea8df-0017-4649-b913-14d4b7a17c2f.png" width="25" /> This button will bring up a pop-up menu that allows the user to change the base color used for the light and dark themes. This uses a new color seed feature to generate entire color schemes from a single color.
|
<img src="https://user-images.githubusercontent.com/36861262/166511137-85dea8df-0017-4649-b913-14d4b7a17c2f.png" width="25" /> This button will bring up a pop-up menu that allows the user to change the base color used for the light and dark themes. This uses a new color seed feature to generate entire color schemes from a single color.
|
||||||
|
|
||||||
## Component Screen
|
## Component Screen
|
||||||
The default screen displays all the updated components in Material 3: AppBar, common Buttons, Floating Action Button(FAB), Chips, Card, Dialog, NavigationBar, and NavigationRail.
|
The default screen displays all the updated components in Material 3: AppBar, common Buttons, Floating Action Button(FAB), Chips, Card, Checkbox, Dialog, NavigationBar, NavigationRail, TextFields and Switch.
|
||||||
|
|
||||||
### Adaptive Layout
|
### Adaptive Layout
|
||||||
Based on the fact that NavigationRail is not recommended on a small screen, the app changes its layout based on the screen width. If it's played on iOS or Android devices which have a narrow screen, a Navigation Bar will show at the bottom and will be used to navigate. But if it's played as a desktop or a web app, a Navigation Rail will show on the left side and at the same time, a Navigation Bar will show as an example but will not have any functionality.
|
Based on the fact that NavigationRail is not recommended on a small screen, the app changes its layout based on the screen width. If it's played on iOS or Android devices which have a narrow screen, a Navigation Bar will show at the bottom and will be used to navigate. But if it's played as a desktop or a web app, a Navigation Rail will show on the left side and at the same time, a Navigation Bar will show as an example but will not have any functionality.
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ class ComponentScreen extends StatelessWidget {
|
|||||||
colDivider,
|
colDivider,
|
||||||
const Dialogs(),
|
const Dialogs(),
|
||||||
colDivider,
|
colDivider,
|
||||||
|
const Switches(),
|
||||||
|
colDivider,
|
||||||
|
const Checkboxes(),
|
||||||
|
colDivider,
|
||||||
showNavBottomBar
|
showNavBottomBar
|
||||||
? const NavigationBars(
|
? const NavigationBars(
|
||||||
selectedIndex: 0,
|
selectedIndex: 0,
|
||||||
@@ -481,6 +485,150 @@ class _DialogsState extends State<Dialogs> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Switches extends StatelessWidget {
|
||||||
|
const Switches({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
children: const <Widget>[
|
||||||
|
SwitchRow(isEnabled: true),
|
||||||
|
SwitchRow(isEnabled: false),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SwitchRow extends StatefulWidget {
|
||||||
|
const SwitchRow({super.key, required this.isEnabled});
|
||||||
|
|
||||||
|
final bool isEnabled;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SwitchRow> createState() => _SwitchRowState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SwitchRowState extends State<SwitchRow> {
|
||||||
|
bool value0 = false;
|
||||||
|
bool value1 = true;
|
||||||
|
|
||||||
|
final MaterialStateProperty<Icon?> thumbIcon =
|
||||||
|
MaterialStateProperty.resolveWith<Icon?>((states) {
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return const Icon(Icons.check);
|
||||||
|
}
|
||||||
|
return const Icon(Icons.close);
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: <Widget>[
|
||||||
|
Switch(
|
||||||
|
value: value0,
|
||||||
|
onChanged: widget.isEnabled
|
||||||
|
? (value) {
|
||||||
|
setState(() {
|
||||||
|
value0 = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
Switch(
|
||||||
|
thumbIcon: thumbIcon,
|
||||||
|
value: value1,
|
||||||
|
onChanged: widget.isEnabled
|
||||||
|
? (value) {
|
||||||
|
setState(() {
|
||||||
|
value1 = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Checkboxes extends StatelessWidget {
|
||||||
|
const Checkboxes({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
children: const <Widget>[
|
||||||
|
CheckboxRow(
|
||||||
|
isError: false,
|
||||||
|
),
|
||||||
|
CheckboxRow(
|
||||||
|
isError: true,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CheckboxRow extends StatefulWidget {
|
||||||
|
const CheckboxRow({super.key, required this.isError});
|
||||||
|
|
||||||
|
final bool isError;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CheckboxRow> createState() => _CheckboxRowState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CheckboxRowState extends State<CheckboxRow> {
|
||||||
|
bool? isChecked0 = true;
|
||||||
|
bool? isChecked1;
|
||||||
|
bool? isChecked2 = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: <Widget>[
|
||||||
|
Checkbox(
|
||||||
|
isError: widget.isError,
|
||||||
|
tristate: true,
|
||||||
|
value: isChecked0,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
isChecked0 = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Checkbox(
|
||||||
|
isError: widget.isError,
|
||||||
|
tristate: true,
|
||||||
|
value: isChecked1,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
isChecked1 = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Checkbox(
|
||||||
|
isError: widget.isError,
|
||||||
|
tristate: true,
|
||||||
|
value: isChecked2,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
isChecked2 = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Checkbox(
|
||||||
|
isError: widget.isError,
|
||||||
|
tristate: true,
|
||||||
|
value: true,
|
||||||
|
onChanged: null,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const List<NavigationDestination> appBarDestinations = [
|
const List<NavigationDestination> appBarDestinations = [
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
tooltip: 'Updated component list',
|
tooltip: 'Updated component list',
|
||||||
|
|||||||
@@ -55,6 +55,14 @@ void main() {
|
|||||||
// Alert Dialog
|
// Alert Dialog
|
||||||
Finder dialogExample = find.widgetWithText(TextButton, 'Open Dialog');
|
Finder dialogExample = find.widgetWithText(TextButton, 'Open Dialog');
|
||||||
expect(dialogExample, findsOneWidget);
|
expect(dialogExample, findsOneWidget);
|
||||||
|
|
||||||
|
// Switches
|
||||||
|
Finder switchExample = find.byType(Switch);
|
||||||
|
expect(switchExample, findsNWidgets(4));
|
||||||
|
|
||||||
|
// Checkboxes
|
||||||
|
Finder checkboxExample = find.byType(Checkbox);
|
||||||
|
expect(checkboxExample, findsNWidgets(8));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
|
|||||||
Reference in New Issue
Block a user