|
|
|
// 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",
|
|
|
|
];
|
|
|
|
|
|
|
|
class _Material3DemoState extends State<Material3Demo> {
|
|
|
|
bool useMaterial3 = true;
|
|
|
|
bool useLightMode = true;
|
|
|
|
int colorSelected = 0;
|
|
|
|
int screenIndex = 0;
|
|
|
|
|
|
|
|
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 selectedScreen) {
|
|
|
|
setState(() {
|
|
|
|
screenIndex = selectedScreen;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
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(int screenIndex, bool showNavBarExample) {
|
|
|
|
switch (screenIndex) {
|
|
|
|
case 0:
|
|
|
|
return ComponentScreen(showNavBottomBar: showNavBarExample);
|
|
|
|
case 1:
|
|
|
|
return const ColorPalettesScreen();
|
|
|
|
case 2:
|
|
|
|
return const TypographyScreen();
|
|
|
|
case 3:
|
|
|
|
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(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(screenIndex, true),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|