返回

Flutter 开发中的 98 个不容忽视的小技巧(六)

Android

导读:

对于 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 (