Flutter 开发中的 98 个不容忽视的小技巧(六)
2023-10-30 00:01:08
导读:
对于 Flutter 开发人员来说,掌握各种小技巧至关重要,这些技巧可以提升效率、增强应用性能并提升用户体验。我们精心挑选了 98 个鲜为人知的 Flutter 技巧,分为六部分,这篇文章将重点介绍其中的第六部分。
98 个 Flutter 小技巧:第六部分
51. 使用混合构建 SliverAppBar
使用 SliverAppBar
控件创建一个可滚动的应用程序栏。但是,当应用程序栏的背景与应用程序窗口小部件的背景不同时,可能会出现视觉问题。可以通过将 SliverAppBar
嵌套在 SliverPersistentHeader
中来解决此问题,如下所示:
SliverPersistentHeader(
pinned: true,
delegate: MySliverAppBarDelegate(),
)
52. 通过 Theme.of()
访问当前主题
避免使用 context.theme
访问当前主题,因为这可能会导致意外行为。相反,请使用 Theme.of()
方法,如下所示:
final ThemeData theme = Theme.of(context);
53. 使用 GestureDetector
拦截触摸事件
当需要在其他小部件后面拦截触摸事件时,可以使用 GestureDetector
小部件。例如,可以通过将 GestureDetector
放置在 Stack
小部件的顶部来拦截所有触摸事件,如下所示:
Stack(
children: [
GestureDetector(
onTap: () => print('Stack clicked!'),
child: Container(),
),
Container(),
],
)
54. 使用 ValueListenableBuilder
监听值的变化
ValueListenableBuilder
小部件提供了一种在值更改时重建小部件树的方法。这对于需要根据状态变化动态更新 UI 的情况非常有用,如下所示:
ValueListenableBuilder(
valueListenable: myValueListenable,
builder: (context, value, child) {
return Text(value);
},
)
55. 使用 FutureBuilder
异步加载数据
FutureBuilder
小部件提供了一种异步加载数据并在加载后更新 UI 的方法。这对于从网络获取数据或执行其他耗时的操作非常有用,如下所示:
FutureBuilder(
future: myFuture,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data);
} else if (snapshot.hasError) {
return Text('Error loading data');
}
return CircularProgressIndicator();
},
)
56. 使用 InheritedWidget
共享状态
InheritedWidget
类提供了一种跨小部件树共享状态的方法。这对于需要在不同部分的应用程序中访问状态的情况非常有用,如下所示:
class MyInheritedWidget extends InheritedWidget {
// ...
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final inheritedWidget = context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
// ...
}
}
57. 使用 KeepAlive
保持状态
KeepAlive
小部件可防止其子小部件在小部件树中重建时丢失状态。这对于需要保留状态以避免重新创建或重新加载数据的组件非常有用,如下所示:
KeepAlive(
child: MyWidget(),
)
58. 使用 AnimationController
控制动画
AnimationController
类提供了一种控制动画的方法。这对于需要创建自定义动画或与其他小部件同步动画的情况非常有用,如下所示:
final controller = AnimationController(
vsync: this,
duration: Duration(seconds: 1),
);
59. 使用 TickerProvider
提供动画更新
TickerProvider
接口提供了一种为动画提供更新的方法。这对于需要在不同的时间间隔更新动画或与其他动画同步的情况非常有用,如下所示:
class MyTickerProvider extends TickerProvider {
// ...
}
60. 使用 GestureDetector
识别手势
GestureDetector
小部件提供了一种识别手势的方法。这对于需要响应用户手势的应用程序非常有用,如下所示:
GestureDetector(
onTap: () => print('Tap!'),
onDoubleTap: () => print('Double tap!'),
onLongPress: () => print('Long press!'),
onPanStart: (details) => print('Pan start!'),
onPanEnd: (details) => print('Pan end!'),
)
61. 使用 Semantics
提高可访问性
Semantics
类提供了一种向辅助技术提供有关应用程序的信息的方法。这对于提高应用程序的可访问性非常有用,如下所示:
Semantics(
label: 'My button',
hint: 'This button opens the settings menu',
child: Button(),
)
62. 使用 GlobalKey
访问小部件
GlobalKey
类提供了一种在应用程序树的任何位置访问小部件的方法。这对于需要从代码的不同部分访问特定小部件的情况非常有用,如下所示:
final key = GlobalKey();
Widget myWidget() {
return Container(
key: key,
child: Text('My widget'),
);
}
void accessWidget() {
final widget = key.currentWidget;
// ...
}
63. 使用 BuildContext
访问上下文
BuildContext
类提供了一种访问应用程序上下文的信息的方法。这对于需要访问主题、媒体查询或导航数据的情况非常有用,如下所示:
final context = BuildContext;
final theme = Theme.of(context);
64. 使用 InheritedModel
共享数据
InheritedModel
类提供了一种跨小部件树共享数据的便捷方法。这对于需要在应用程序的不同部分访问数据的情况非常有用,如下所示:
class MyInheritedModel extends InheritedModel {
// ...
}
Widget myWidget() {
return InheritedModel.of<MyInheritedModel>(context).data;
}
65. 使用 ScopedModel
共享状态
ScopedModel
类提供了一种共享状态并在状态更改时重建 UI 的方法。这对于需要在一个位置管理应用程序状态并轻松访问它的情况非常有用,如下所示:
class MyScopedModel extends Model {
// ...
}
Widget myWidget() {
return ScopedModelDescendant<MyScopedModel>(
builder: (context, child, model) {
return Text(model.data);
},
);
}
66. 使用 Provider
共享状态
Provider
类提供了一种共享状态并在状态更改时重建 UI 的便捷方法。这对于需要在一个位置管理应用程序状态并轻松访问它的情况非常有用,如下所示:
Provider<MyModel>(
create: (_) => MyModel(),
child: myWidget(),
)
67. 使用 ChangeNotifier
监听状态变化
ChangeNotifier
类提供了一种监听状态变化并重建 UI 的方法。这对于需要在状态更改时动态更新 UI 的情况非常有用,如下所示:
class MyChangeNotifier extends ChangeNotifier {
// ...
}
Widget myWidget() {
return ChangeNotifierProvider<MyChangeNotifier>(
create: (_) => MyChangeNotifier(),
child: Consumer<MyChangeNotifier>(
builder: (context, model, child) {
return Text(model.data);
},
),
);
}
68. 使用 ValueNotifier
监听值的变化
ValueNotifier
类提供了一种监听值的变化并重建 UI 的方法。这对于需要在值更改时动态更新 UI 的情况非常有用,如下所示:
final valueNotifier = ValueNotifier<int>(0);
Widget myWidget() {
return ValueListenableBuilder(
valueListenable: valueNotifier,
builder: (context, value, child) {
return Text(value.toString());
},
);
}
69. 使用 StreamBuilder
监听异步事件流
StreamBuilder
小部件提供了一种监听异步事件流并在事件到达时更新 UI 的方法。这对于需要从流中接收和处理数据的情况非常有用,如下所示:
StreamBuilder(
stream: myStream,
builder: (context, snapshot) {
if (