mirror of https://github.com/flutter/samples.git
216 lines
6.1 KiB
216 lines
6.1 KiB
// Copyright 2021 The Flutter team. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'color_palettes_screen.dart';
|
|
import 'component_screen.dart';
|
|
import 'elevation_screen.dart';
|
|
import 'typography_screen.dart';
|
|
|
|
void main() {
|
|
runApp(const Material3Demo());
|
|
}
|
|
|
|
class Material3Demo extends StatefulWidget {
|
|
const Material3Demo({super.key});
|
|
|
|
@override
|
|
State<Material3Demo> createState() => _Material3DemoState();
|
|
}
|
|
|
|
// NavigationRail shows if the screen width is greater or equal to
|
|
// screenWidthThreshold; otherwise, NavigationBar is used for navigation.
|
|
const double narrowScreenWidthThreshold = 450;
|
|
|
|
const Color m3BaseColor = Color(0xff6750a4);
|
|
const List<Color> colorOptions = [
|
|
m3BaseColor,
|
|
Colors.blue,
|
|
Colors.teal,
|
|
Colors.green,
|
|
Colors.yellow,
|
|
Colors.orange,
|
|
Colors.pink
|
|
];
|
|
const List<String> colorText = <String>[
|
|
'M3 Baseline',
|
|
'Blue',
|
|
'Teal',
|
|
'Green',
|
|
'Yellow',
|
|
'Orange',
|
|
'Pink',
|
|
];
|
|
|
|
enum ScreenSelected {
|
|
component(0),
|
|
color(1),
|
|
typography(2),
|
|
elevation(3);
|
|
|
|
const ScreenSelected(this.value);
|
|
final int value;
|
|
}
|
|
|
|
class _Material3DemoState extends State<Material3Demo> {
|
|
bool useMaterial3 = true;
|
|
bool useLightMode = true;
|
|
int colorSelected = 0;
|
|
int screenIndex = ScreenSelected.component.value;
|
|
|
|
late ThemeData themeData;
|
|
|
|
@override
|
|
initState() {
|
|
super.initState();
|
|
themeData = updateThemes(colorSelected, useMaterial3, useLightMode);
|
|
}
|
|
|
|
ThemeData updateThemes(int colorIndex, bool useMaterial3, bool useLightMode) {
|
|
return ThemeData(
|
|
colorSchemeSeed: colorOptions[colorSelected],
|
|
useMaterial3: useMaterial3,
|
|
brightness: useLightMode ? Brightness.light : Brightness.dark);
|
|
}
|
|
|
|
void handleScreenChanged(int screenSelected) {
|
|
setState(() {
|
|
screenIndex = screenSelected;
|
|
});
|
|
}
|
|
|
|
void handleBrightnessChange() {
|
|
setState(() {
|
|
useLightMode = !useLightMode;
|
|
themeData = updateThemes(colorSelected, useMaterial3, useLightMode);
|
|
});
|
|
}
|
|
|
|
void handleMaterialVersionChange() {
|
|
setState(() {
|
|
useMaterial3 = !useMaterial3;
|
|
themeData = updateThemes(colorSelected, useMaterial3, useLightMode);
|
|
});
|
|
}
|
|
|
|
void handleColorSelect(int value) {
|
|
setState(() {
|
|
colorSelected = value;
|
|
themeData = updateThemes(colorSelected, useMaterial3, useLightMode);
|
|
});
|
|
}
|
|
|
|
Widget createScreenFor(
|
|
ScreenSelected screenSelected, bool showNavBarExample) {
|
|
switch (screenSelected) {
|
|
case ScreenSelected.component:
|
|
return ComponentScreen(showNavBottomBar: showNavBarExample);
|
|
case ScreenSelected.color:
|
|
return const ColorPalettesScreen();
|
|
case ScreenSelected.typography:
|
|
return const TypographyScreen();
|
|
case ScreenSelected.elevation:
|
|
return const ElevationScreen();
|
|
default:
|
|
return ComponentScreen(showNavBottomBar: showNavBarExample);
|
|
}
|
|
}
|
|
|
|
PreferredSizeWidget createAppBar() {
|
|
return AppBar(
|
|
title: useMaterial3 ? const Text('Material 3') : const Text('Material 2'),
|
|
actions: [
|
|
IconButton(
|
|
icon: useLightMode
|
|
? const Icon(Icons.wb_sunny_outlined)
|
|
: const Icon(Icons.wb_sunny),
|
|
onPressed: handleBrightnessChange,
|
|
tooltip: 'Toggle brightness',
|
|
),
|
|
IconButton(
|
|
icon: useMaterial3
|
|
? const Icon(Icons.filter_3)
|
|
: const Icon(Icons.filter_2),
|
|
onPressed: handleMaterialVersionChange,
|
|
tooltip: 'Switch to Material ${useMaterial3 ? 2 : 3}',
|
|
),
|
|
PopupMenuButton(
|
|
icon: const Icon(Icons.more_vert),
|
|
shape:
|
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
|
itemBuilder: (context) {
|
|
return List.generate(colorOptions.length, (index) {
|
|
return PopupMenuItem(
|
|
value: index,
|
|
child: Wrap(
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 10),
|
|
child: Icon(
|
|
index == colorSelected
|
|
? Icons.color_lens
|
|
: Icons.color_lens_outlined,
|
|
color: colorOptions[index],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 20),
|
|
child: Text(colorText[index]),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
});
|
|
},
|
|
onSelected: handleColorSelect,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
debugShowCheckedModeBanner: false,
|
|
title: 'Material 3',
|
|
themeMode: useLightMode ? ThemeMode.light : ThemeMode.dark,
|
|
theme: themeData,
|
|
home: LayoutBuilder(builder: (context, constraints) {
|
|
if (constraints.maxWidth < narrowScreenWidthThreshold) {
|
|
return Scaffold(
|
|
appBar: createAppBar(),
|
|
body: Row(children: <Widget>[
|
|
createScreenFor(ScreenSelected.values[screenIndex], false),
|
|
]),
|
|
bottomNavigationBar: NavigationBars(
|
|
onSelectItem: handleScreenChanged,
|
|
selectedIndex: screenIndex,
|
|
isExampleBar: false,
|
|
),
|
|
);
|
|
} else {
|
|
return Scaffold(
|
|
appBar: createAppBar(),
|
|
body: SafeArea(
|
|
bottom: false,
|
|
top: false,
|
|
child: Row(
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
|
child: NavigationRailSection(
|
|
onSelectItem: handleScreenChanged,
|
|
selectedIndex: screenIndex)),
|
|
const VerticalDivider(thickness: 1, width: 1),
|
|
createScreenFor(ScreenSelected.values[screenIndex], true),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}),
|
|
);
|
|
}
|
|
}
|