Flutter JSON主题管理插件json_theme的使用
Flutter JSON主题管理插件json_theme的使用
目录
json_theme
json_theme
是一个用于将Flutter中的 ThemeData
和相关对象编码和解码为JSON格式的库。这目前是该库的早期版本。
这个库主要提供了两个类:
- ThemeDecoder:提供从JSON映射中解码主题相关对象的功能。
- ThemeEncoder:提供将主题相关对象编码为JSON映射的功能。
注意事项
- 编码和解码在大多数情况下是双向兼容的,但不是完全双向兼容的。这是因为主题对象中的一些属性只存在于构造函数中,并没有重新暴露为属性,而是一些动态计算的值。
- 一些自定义类(如
Shape
、Slider
和Decoration
)无法有意义地编码为JSON或从JSON解码。 - 解码器利用JSON Schema验证器确保JSON格式正确。默认情况下,在调试模式下启用此验证,而在发布模式下出于性能原因禁用此验证。
Live Example
你可以通过以下链接查看在线示例:
Decoding
框架接受JSON兼容的对象以及实际的具体实例传递给 decode
函数。例如:
var appBarTheme = ThemeDecoder.decodeAppBarTheme({
'brightness': Brightness.dark,
'color': '#ffdddddd'
}, validate: false);
Schema Validation
框架内置了一个JSON Schema验证器,默认情况下在调试模式下启用,但在发布和配置模式下禁用。你可以通过以下方式全局禁用验证:
import 'package:json_theme/json_theme_schemas.dart';
void main() {
SchemaValidator.enabled = false;
/// 应用程序初始化代码
}
Class Selection
尽可能地复制Dart API中的名称。然而,对于某些类(如 Shape
对象)或枚举(如 VerticalDirection
),它们的表示方式有所不同。以下是部分类的选择规则:
-
Alignment
bottomCenter
=>Alignment.bottomCenter
bottomLeft
=>Alignment.bottomLeft
- …
-
AutovalidateMode
always
=>AutovalidateMode.always
disabled
=>AutovalidateMode.disabled
- …
-
Axis
horizontal
=>Axis.horizontal
vertical
=>Axis.vertical
-
BlendMode
clear
=>BlendMode.clear
color
=>BlendMode.color
- …
-
BorderRadius
all
=>BorderRadius.all
circular
=>BorderRadius.circular
- …
-
BorderStyle
none
=>BorderStyle.none
solid
=>BorderStyle.solid
-
BottomNavigationBarType
fixed
=>BottomNavigationBarType.fixed
shifting
=>BottomNavigationBarType.shifting
-
BoxFit
contain
=>BoxFit.contain
cover
=>BoxFit.cover
- …
-
ButtonBarLayoutBehavior
constrained
=>ButtonBarLayoutBehavior.constrained
padded
=>ButtonBarLayoutBehavior.padded
-
ButtonTextTheme
accent
=>ButtonTextTheme.accent
normal
=>ButtonTextTheme.normal
- …
-
Clip
antiAlias
=>Clip.antiAlias
antiAliasWithSaveLayer
=>Clip.antiAliasWithSaveLayer
- …
-
CrossAxisAlignment
baseline
=>CrossAxisAlignment.baseline
center
=>CrossAxisAlignment.center
- …
-
CrossFadeState
showFirst
=>CrossFadeState.showFirst
showSecond
=>CrossFadeState.showSecond
-
DecorationPosition
background
=>DecorationPosition.background
foreground
=>DecorationPosition.foreground
-
DragStartBehavior
down
=>DragStartBehavior.down
start
=>DragStartBehavior.start
-
FilterQuality
high
=>FilterQuality.high
low
=>FilterQuality.low
- …
-
FlexFit
loose
=>FlexFit.loose
tight
=>FlexFit.tight
-
FloatingActionButtonAnimator
scaling
=>FloatingActionButtonAnimator.scaling
-
FloatingActionButtonLocation
centerDocked
=>FloatingActionButtonLocation.centerDocked
centerFloat
=>FloatingActionButtonLocation.centerFloat
- …
-
FloatingLabelBehavior
always
=>FloatingLabelBehavior.always
auto
=>FloatingLabelBehavior.auto
- …
-
FontWeight
bold
=>FontWeight.bold
normal
=>FontWeight.normal
- …
-
FontStyle
italic
=>FontStyle.italic
normal
=>FontStyle.normal
-
Gradient
linear
=>LinearGradient
radial
=>RadialGradient
- …
-
HitTestBehavior
deferToChild
=>HitTestBehavior.deferToChild
opaque
=>HitTestBehavior.opaque
- …
-
ImageProvider
asset
=>AssetImage
memory
=>MemoryImage
- …
-
ImageRepeat
noRepeat
=>ImageRepeat.noRepeat
repeat
=>ImageRepeat.repeat
- …
-
InputBorder
outline
=>OutlineInputBorder
underline
=>UnderlineInputBorder
-
InteractiveInkFeatureFactory
splash
=>InkSplash.splashFactory
ripple
=>InkRipple.splashFactory
-
MainAxisAlignment
center
=>MainAxisAlignment.center
end
=>MainAxisAlignment.end
- …
-
MainAxisSize
min
=>MainAxisSize.min
max
=>MainAxisSize.max
-
MaterialTapTargetSize
padded
=>MaterialTapTargetSize.padded
shrinkWrap
=>MaterialTapTargetSize.shrinkWrap
-
MaterialType
button
=>MaterialType.button
canvas
=>MaterialType.canvas
- …
-
MaxLengthEnforcement
enforced
=>MaxLengthEnforcement.enforced
none
=>MaxLengthEnforcement.none
- …
-
MouseCursor
defer
=>MouseCursor.defer
material
=>MouseCursor.material
- …
-
NavigationRailLabelType
all
=>NavigationRailLabelType.all
none
=>NavigationRailLabelType.none
- …
-
NotchedShape
circular
=>CircularNotchedRectangle
-
OutlinedBorder
stadium
=>BeveledRectangleBorder
circle
=>CircleBorder
- …
-
PageTransitionsBuilder
clip
=>Overflow.clip
visible
=>Overflow.visible
-
Radius
circular
=>Radius.circular
elliptical
=>Radius.elliptical
- …
-
RangeSliderThumbShape
round
=>RoundRangeSliderThumbShape
-
RangeSliderTickMarkShape
round
=>RoundRangeSliderTickMarkShape
-
RangeSliderTrackShape
rectangular
=>RectangularRangeSliderTrackShape
rounded
=>RoundedRectRangeSliderTrackShape
-
RangeSliderValueIndicatorShape
paddle
=>PaddleRangeSliderValueIndicatorShape
rectangular
=>RectangularRangeSliderValueIndicatorShape
-
Rect
center
=>Rect.fromCenter
circle
=>Rect.fromCircle
- …
-
ScrollPhysics
always
=>AlwaysScrollableScrollPhysics
bouncing
=>BouncingScrollPhysics
- …
-
ScrollViewKeyboardDismissBehavior
manual
=>ScrollViewKeyboardDismissBehavior.manual
onDrag
=>ScrollViewKeyboardDismissBehavior.onDrag
-
ShapeBorder
circle
=>CircleBorder
rectangle
=>ContinuousRectangleBorder
- …
-
ShowValueIndicator
always
=>ShowValueIndicator.always
never
=>ShowValueIndicator.never
- …
-
SliderComponentShape
noOverlay
=>SliderComponentShape.noOverlay
-
SliderTickMarkShape
noTickMark
=>SliderTickMarkShape.noTickMark
-
SliderTrackShape
rectangular
=>RectangularSliderTrackShape
rounded
=>RoundedRectSliderTrackShape
-
SmartDashesType
disabled
=>SmartDashesType.disabled
enabled
=>SmartDashesType.enabled
-
SmartQuotesType
disabled
=>SmartQuotesType.disabled
enabled
=>SmartQuotesType.enabled
-
SnackBarBehavior
fixed
=>SnackBarBehavior.fixed
floating
=>SnackBarBehavior.floating
-
StackFit
expand
=>StackFit.expand
loose
=>StackFit.loose
- …
-
TabBarIndicatorSize
label
=>ButtonTextTheme.label
tab
=>ButtonTextTheme.tab
-
TargetPlatform
android
=>TargetPlatform.android
fuchsia
=>TargetPlatform.fuchsia
- …
-
TextAlign
center
=>TextAlign.center
end
=>TextAlign.end
- …
-
TextAlignVertical
bottom
=>TextAlignVertical.bottom
center
=>TextAlignVertical.center
- …
-
TextBaseline
alphabetic
=>TextBaseline.alphabetic
ideographic
=>TextBaseline.ideographic
-
TextCapitalization
characters
=>TextCapitalization.characters
none
=>TextCapitalization.none
- …
-
TextDecoration
lineThrough
=>TextDecoration.lineThrough
none
=>TextDecoration.none
- …
-
TextDecorationStyle
dashed
=>TextDecorationStyle.dashed
dotted
=>TextDecorationStyle.dotted
- …
-
TextDirection
ltr
=>TextDirection.ltr
rtl
=>TextDirection.rtl
-
TextInputAction
continueAction
=>TextInputAction.continueAction
done
=>TextInputAction.done
- …
-
TextInputType
datetime
=>TextInputType.datetime
emailAddress
=>TextInputType.emailAddress
- …
-
TextOverflow
clip
=>TextOverflow.clip
ellipsis
=>TextOverflow.ellipsis
- …
-
TextWidthBasis
longestLine
=>TextWidthBasis.longestLine
parent
=>TextWidthBasis.parent
-
TileMode
clamp
=>TileMode.clamp
decal
=>TileMode.decal
- …
-
VerticalDirection
down
=>VerticalDirection.down
up
=>VerticalDirection.up
-
VisualDensity
adaptivePlatformDensity
=>VisualDensity.adaptivePlatformDensity
comfortable
=>VisualDensity.comfortable
- …
示例代码
下面是一个完整的示例代码,展示了如何使用 json_theme
插件来实现主题切换功能:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:json_theme/json_theme.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: RootPage(),
);
}
}
class RootPage extends StatefulWidget {
const RootPage({super.key});
@override
State createState() => _RootPageState();
}
class _RootPageState extends State<RootPage> {
static const _themes = [
'default',
'big_red',
'calm_blue',
];
Future<void> _onThemeSelected(BuildContext context, String themeId) async {
final navigator = Navigator.of(context);
final themeStr = await rootBundle.loadString('assets/themes/$themeId.json');
final themeJson = json.decode(themeStr);
final theme = ThemeDecoder.decodeThemeData(
themeJson,
validate: true,
) ??
ThemeData();
if (mounted) {
await navigator.push(
MaterialPageRoute(
builder: (BuildContext context) => ThemePage(
theme: theme,
),
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Select Theme'),
),
body: ListView.builder(
itemCount: _themes.length,
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text(_themes[index]),
onTap: () => _onThemeSelected(context, _themes[index]),
),
),
);
}
}
class ThemePage extends StatelessWidget {
final ThemeData theme;
const ThemePage({super.key, required this.theme});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: theme,
home: Scaffold(
appBar: AppBar(
title: const Text('Theme Page'),
),
body: Center(
child: Text(
'This page is using the selected theme!',
style: TextStyle(fontSize: 20),
),
),
),
);
}
}
在这个示例中,我们创建了一个简单的应用,允许用户从几个预定义的主题中选择一个。每个主题存储在一个JSON文件中,并通过 json_theme
插件进行加载和应用。用户选择主题后,导航到一个新的页面,该页面使用所选主题进行渲染。
更多关于Flutter JSON主题管理插件json_theme的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html