Практика разработки Flutter: реализация обратного вызова завершения макета кадра в первую очередь

Практика разработки Flutter — реализация обратного вызова завершения макета первого кадра
Вставьте сюда описание изображения
. Во время разработки нам иногда приходится вызывать некоторые связанные методы после завершения макета первого кадра. Здесь записан процесс реализации.

Во Flutter много разных привязок, каждая привязка отвечает за разные функции. Ниже приведены распространенные привязки во Flutter:
вот краткое объяснение WidgetsBinding.

一、Привязка виджетов

WidgetsBinding: отвечает за управление жизненным циклом приложений Flutter, включая запуск, приостановку, возобновление и остановку.
WidgetsBinding Используется для отслеживания изменений пользовательских настроек, таких как изменения языка. Мало того, WidgetsBinding — это мост для связи между виджетами и движком Flutter. Он имеет две основные функции:
  * 1 отвечает за обработку процесса изменения структуры виджетов;
  * 2 ​​Вторая — запускать события рендеринга.
Некоторые структурные изменения виджетов выполняются BuildOwner, который отслеживает виджеты, которые необходимо перестроить, и выполняет другие задачи, применимые к общей структуре виджетов.

2. Вызовите соответствующие методы после завершения макета первого кадра.

В WidgetsBinding мы видим метод endOfFrame, исходный код следующий:

/// Returns a Future that completes after the frame completes.
  ///
  /// If this is called between frames, a frame is immediately scheduled if
  /// necessary. If this is called during a frame, the Future completes after
  /// the current frame.
  ///
  /// If the device's screen is currently turned off, this may wait a very long
  /// time, since frames are not scheduled while the device's screen is turned
  /// off.
  Future<void> get endOfFrame {
    if (_nextFrameCompleter == null) {
      if (schedulerPhase == SchedulerPhase.idle) {
        scheduleFrame();
      }
      _nextFrameCompleter = Completer<void>();
      addPostFrameCallback((Duration timeStamp) {
        _nextFrameCompleter!.complete();
        _nextFrameCompleter = null;
      });
    }
    return _nextFrameCompleter!.future;
  }
    

Метод описан ниже

该方法返回在帧完成后完成的Future。
如果在帧之前调用的时候,则会立即调度帧。如果在帧期间调用此操作,则Future将在当前帧完成后调用。
如果设备的屏幕当前已关闭,这可能会等待很长时间。

Поэтому нам нужно вызвать соответствующие методы в initState.

WidgetsBinding.instance.endOfFrame.then(
          (value) {
        if (mounted) {
           // TODO调用相关方法
        }
      },
    );

После завершения макета первого кадра код завершения вызывается следующим образом:

class AfterLayoutPage extends StatefulWidget {
  const AfterLayoutPage({super.key});

  @override
  State<AfterLayoutPage> createState() => _AfterLayoutPageState();
}

class _AfterLayoutPageState extends State<AfterLayoutPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AfterLayoutPage'),
      ),
      body: Container(
        color: Colors.blueGrey,
      ),
    );
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    WidgetsBinding.instance.endOfFrame.then(
          (value) {
        if (mounted) {
          showHelloWorld();
        }
      },
    );
  }

  void showHelloWorld() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: const Text('Hello World'),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: const Text('DISMISS'),
            )
          ],
        );
      },
    );
  }
}

    

Эту реализацию можно обернуть в Mixin

import 'dart:async';

import 'package:flutter/widgets.dart';

mixin AfterLayoutMixin<T extends StatefulWidget> on State<T> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.endOfFrame.then(
      (_) {
        if (mounted) afterFirstLayout(context);
      },
    );
  }

  FutureOr<void> afterFirstLayout(BuildContext context);
}


Скорректированный код выглядит следующим образом

class AfterLayoutPage extends StatefulWidget {
  const AfterLayoutPage({super.key});

  @override
  State<AfterLayoutPage> createState() => _AfterLayoutPageState();
}

class _AfterLayoutPageState extends State<AfterLayoutPage> with AfterLayoutMixin<AfterLayoutPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AfterLayoutPage'),
      ),
      body: Container(
        color: Colors.blueGrey,
      ),
    );
  }

  @override
  void afterFirstLayout(BuildContext context) {
    // Calling the same function "after layout" to resolve the issue.
    showHelloWorld();
  }

  void showHelloWorld() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: const Text('Hello World'),
          actions: <Widget>[
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: const Text('DISMISS'),
            )
          ],
        );
      },
    );
  }
}

3. Резюме

Практика разработки Flutter: реализация обратного вызова завершения макета кадра в первую очередь

Изучайте и записывайте, совершенствуйтесь каждый день.

Supongo que te gusta

Origin blog.csdn.net/gloryFlow/article/details/135127060
Recomendado
Clasificación