我正在尝试让我的 Flutter 移动应用具有响应性和自适应性。
我正在使用这个小部件来完成此任务:
class ExamplePage extends StatelessWidget {
const ExamplePage({super.key});
@override
Widget build(BuildContext context) {
return DeviceSpecificLayout(
mobilePortrait: ExampleMobilePortrait(),
mobileLandscape: ExampleMobileLandscape(),
tabletPortrait: ExampleTabletPortrait(),
tabletLandscape: ExampleTabletLandscape(),
);
}
}
DeviceSpecificLayout 小部件:
class DeviceSpecificLayout extends StatelessWidget {
final Widget mobilePortrait;
final Widget mobileLandscape;
final Widget tabletPortrait;
final Widget tabletLandscape;
const DeviceSpecificLayout({
super.key,
required this.mobilePortrait,
required this.mobileLandscape,
required this.tabletPortrait,
required this.tabletLandscape,
});
@override
Widget build(BuildContext context) {
return ScreenTypeLayout.builder(
mobile: (context) => OrientationLayoutBuilder(
portrait: (context) => mobilePortrait,
landscape: (context) => mobileLandscape,
),
tablet: (context) => OrientationLayoutBuilder(
portrait: (context) => tabletPortrait,
landscape: (context) => tabletLandscape,
),
);
}
}
我遇到的问题是,每当应用程序更改方向时,由于应用程序切换方向时的构建,我的块的状态就会完全丢失。
这是我的main.dart,我正在使用MultiBlocProvider。
runApp(
MultiBlocProvider(
providers: [
BlocProvider(create: (_) => ExampleBloc1()),
BlocProvider(create: (_) => ExampleBloc2()),
],
child: ExamplePage(),
),
);
这是在方向改变时丢失其状态的小部件:
SafeArea(
child: BlocBuilder<ExampleBloc, ExampleState>(
builder: (context, state) {
return state.exampleVariable == false
? Padding(
padding: const EdgeInsets.all(3.0),
child: CountDownAnimatedText(
animation: StepTween(begin: 120, end: 0).animate(animationController),
countdownFontSize: 30.0,
instructionTextFontSize: 25.0,
),
)
: Container();
},
),
),
上面的小部件是一个倒计时,在状态方向上它会失去倒计时状态并在开始时重置。
我也在使用 https://pub.dev/packages/responsive_builder 包。
也许我对应用程序的响应能力和适应性的理解是错误的。
我希望对此有任何评论。
每当您的 UI 发生巨大变化时(例如方向,在移动设备中,屏幕的方向相当于更改其大小,就像在浏览器/桌面应用程序中您可以调整窗口大小一样),它会强制调用所有构建方法来更改任何不同的内容,这主要是您使用
ScreenTypeLayout
和 OrientationLayoutBuilder
的逻辑,也是在构建方法内创建的所有对象(如您的 StepTween
)。您可以尝试在 animationController
所在的外部创建它,然后使用 BlocListener
或 BlocConsumer
为控制器设置动画:
///在 initState 中或您使用控制器所做的任何地方创建补间,并将动画也保存为动画
BlocConsumer<BlocA, BlocAState>(
listener: (context, state) {
if (state.exampleVariable) {
animationController.forward(from: 0);
} else {
animationController.value = 0; ///reset
}
},
builder: (context, state) {
return state.exampleVariable == false
? Padding(
padding: const EdgeInsets.all(3.0),
child: CountDownAnimatedText(
animation: animation, /// your animation tween StepTween().animate(controller)
countdownFontSize: 30.0,
instructionTextFontSize: 25.0,
),
)
: Container();
}
)