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.bottomCenterbottomLeft=>Alignment.bottomLeft- …
-
AutovalidateMode
always=>AutovalidateMode.alwaysdisabled=>AutovalidateMode.disabled- …
-
Axis
horizontal=>Axis.horizontalvertical=>Axis.vertical
-
BlendMode
clear=>BlendMode.clearcolor=>BlendMode.color- …
-
BorderRadius
all=>BorderRadius.allcircular=>BorderRadius.circular- …
-
BorderStyle
none=>BorderStyle.nonesolid=>BorderStyle.solid
-
BottomNavigationBarType
fixed=>BottomNavigationBarType.fixedshifting=>BottomNavigationBarType.shifting
-
BoxFit
contain=>BoxFit.containcover=>BoxFit.cover- …
-
ButtonBarLayoutBehavior
constrained=>ButtonBarLayoutBehavior.constrainedpadded=>ButtonBarLayoutBehavior.padded
-
ButtonTextTheme
accent=>ButtonTextTheme.accentnormal=>ButtonTextTheme.normal- …
-
Clip
antiAlias=>Clip.antiAliasantiAliasWithSaveLayer=>Clip.antiAliasWithSaveLayer- …
-
CrossAxisAlignment
baseline=>CrossAxisAlignment.baselinecenter=>CrossAxisAlignment.center- …
-
CrossFadeState
showFirst=>CrossFadeState.showFirstshowSecond=>CrossFadeState.showSecond
-
DecorationPosition
background=>DecorationPosition.backgroundforeground=>DecorationPosition.foreground
-
DragStartBehavior
down=>DragStartBehavior.downstart=>DragStartBehavior.start
-
FilterQuality
high=>FilterQuality.highlow=>FilterQuality.low- …
-
FlexFit
loose=>FlexFit.loosetight=>FlexFit.tight
-
FloatingActionButtonAnimator
scaling=>FloatingActionButtonAnimator.scaling
-
FloatingActionButtonLocation
centerDocked=>FloatingActionButtonLocation.centerDockedcenterFloat=>FloatingActionButtonLocation.centerFloat- …
-
FloatingLabelBehavior
always=>FloatingLabelBehavior.alwaysauto=>FloatingLabelBehavior.auto- …
-
FontWeight
bold=>FontWeight.boldnormal=>FontWeight.normal- …
-
FontStyle
italic=>FontStyle.italicnormal=>FontStyle.normal
-
Gradient
linear=>LinearGradientradial=>RadialGradient- …
-
HitTestBehavior
deferToChild=>HitTestBehavior.deferToChildopaque=>HitTestBehavior.opaque- …
-
ImageProvider
asset=>AssetImagememory=>MemoryImage- …
-
ImageRepeat
noRepeat=>ImageRepeat.noRepeatrepeat=>ImageRepeat.repeat- …
-
InputBorder
outline=>OutlineInputBorderunderline=>UnderlineInputBorder
-
InteractiveInkFeatureFactory
splash=>InkSplash.splashFactoryripple=>InkRipple.splashFactory
-
MainAxisAlignment
center=>MainAxisAlignment.centerend=>MainAxisAlignment.end- …
-
MainAxisSize
min=>MainAxisSize.minmax=>MainAxisSize.max
-
MaterialTapTargetSize
padded=>MaterialTapTargetSize.paddedshrinkWrap=>MaterialTapTargetSize.shrinkWrap
-
MaterialType
button=>MaterialType.buttoncanvas=>MaterialType.canvas- …
-
MaxLengthEnforcement
enforced=>MaxLengthEnforcement.enforcednone=>MaxLengthEnforcement.none- …
-
MouseCursor
defer=>MouseCursor.defermaterial=>MouseCursor.material- …
-
NavigationRailLabelType
all=>NavigationRailLabelType.allnone=>NavigationRailLabelType.none- …
-
NotchedShape
circular=>CircularNotchedRectangle
-
OutlinedBorder
stadium=>BeveledRectangleBordercircle=>CircleBorder- …
-
PageTransitionsBuilder
clip=>Overflow.clipvisible=>Overflow.visible
-
Radius
circular=>Radius.circularelliptical=>Radius.elliptical- …
-
RangeSliderThumbShape
round=>RoundRangeSliderThumbShape
-
RangeSliderTickMarkShape
round=>RoundRangeSliderTickMarkShape
-
RangeSliderTrackShape
rectangular=>RectangularRangeSliderTrackShaperounded=>RoundedRectRangeSliderTrackShape
-
RangeSliderValueIndicatorShape
paddle=>PaddleRangeSliderValueIndicatorShaperectangular=>RectangularRangeSliderValueIndicatorShape
-
Rect
center=>Rect.fromCentercircle=>Rect.fromCircle- …
-
ScrollPhysics
always=>AlwaysScrollableScrollPhysicsbouncing=>BouncingScrollPhysics- …
-
ScrollViewKeyboardDismissBehavior
manual=>ScrollViewKeyboardDismissBehavior.manualonDrag=>ScrollViewKeyboardDismissBehavior.onDrag
-
ShapeBorder
circle=>CircleBorderrectangle=>ContinuousRectangleBorder- …
-
ShowValueIndicator
always=>ShowValueIndicator.alwaysnever=>ShowValueIndicator.never- …
-
SliderComponentShape
noOverlay=>SliderComponentShape.noOverlay
-
SliderTickMarkShape
noTickMark=>SliderTickMarkShape.noTickMark
-
SliderTrackShape
rectangular=>RectangularSliderTrackShaperounded=>RoundedRectSliderTrackShape
-
SmartDashesType
disabled=>SmartDashesType.disabledenabled=>SmartDashesType.enabled
-
SmartQuotesType
disabled=>SmartQuotesType.disabledenabled=>SmartQuotesType.enabled
-
SnackBarBehavior
fixed=>SnackBarBehavior.fixedfloating=>SnackBarBehavior.floating
-
StackFit
expand=>StackFit.expandloose=>StackFit.loose- …
-
TabBarIndicatorSize
label=>ButtonTextTheme.labeltab=>ButtonTextTheme.tab
-
TargetPlatform
android=>TargetPlatform.androidfuchsia=>TargetPlatform.fuchsia- …
-
TextAlign
center=>TextAlign.centerend=>TextAlign.end- …
-
TextAlignVertical
bottom=>TextAlignVertical.bottomcenter=>TextAlignVertical.center- …
-
TextBaseline
alphabetic=>TextBaseline.alphabeticideographic=>TextBaseline.ideographic
-
TextCapitalization
characters=>TextCapitalization.charactersnone=>TextCapitalization.none- …
-
TextDecoration
lineThrough=>TextDecoration.lineThroughnone=>TextDecoration.none- …
-
TextDecorationStyle
dashed=>TextDecorationStyle.dasheddotted=>TextDecorationStyle.dotted- …
-
TextDirection
ltr=>TextDirection.ltrrtl=>TextDirection.rtl
-
TextInputAction
continueAction=>TextInputAction.continueActiondone=>TextInputAction.done- …
-
TextInputType
datetime=>TextInputType.datetimeemailAddress=>TextInputType.emailAddress- …
-
TextOverflow
clip=>TextOverflow.clipellipsis=>TextOverflow.ellipsis- …
-
TextWidthBasis
longestLine=>TextWidthBasis.longestLineparent=>TextWidthBasis.parent
-
TileMode
clamp=>TileMode.clampdecal=>TileMode.decal- …
-
VerticalDirection
down=>VerticalDirection.downup=>VerticalDirection.up
-
VisualDensity
adaptivePlatformDensity=>VisualDensity.adaptivePlatformDensitycomfortable=>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


