Flutter : 위젯 빌드 완료시 메서드 실행


137

위젯 빌드 /로드가 완료되면 함수를 실행하고 싶지만 방법을 잘 모르겠습니다. 내 현재 사용 사례는 사용자가 인증되었는지 확인하고 그렇지 않은 경우 로그인보기로 리디렉션하는 것입니다. 로그인 뷰나 메인 뷰를 미리 확인하고 푸시하고 싶지 않습니다. 메인 뷰가로드 된 후에 발생해야합니다. 이 작업을 수행하는 데 사용할 수있는 것이 있습니까?


에서 로그인 프로세스를 시작하고 싶지 않을 것입니다 build. Build는 언제든지 여러 번 호출 할 수 있습니다.
Günter Zöchbauer

답변:


196

당신은 사용할 수 있습니다

https://github.com/slightfoot/flutter_after_layout

레이아웃이 완료된 후 한 번만 함수를 실행합니다. 또는 구현을 살펴보고 코드에 추가하십시오 :-)

기본적으로

  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => yourFunction(context));
  }

감사합니다 @thomas 귀하의 ans는 저에게 매우 도움이됩니다. 나는 이틀 전에 이것에 대해 일하고 지금 그들은 당신의 ans를 읽은 후에. 다시 당신에게 매우 썰매의 좋은 작업을 감사합니다
라빈 드라 Bhanderi

8
anmol.majhail 답변을 @ 참조 : WidgetsBinding.instance.addPostFrameCallback((_) => yourFunciton(context));더 이상 작동하지 않습니다
파블로 인수 아

안녕하세요 @Thomas, 그것은 나를 위해 작동하지 않습니다. 여전히 null 예외가 발생합니다. 어떤 생각?
zukijuki

1
@anunixercoder : 사용 사례에 따라 다릅니다. 때때로 initState, 예를 들어 이외의 다른 이름으로 호출해야합니다 . 에서 build.
Giraldi

2
작동하도록 메서드 setState내에서 호출해야합니다.yourFunction
Pars

92

업데이트 : Flutter v1.8.4

언급 된 두 코드 모두 현재 작동합니다.

일:

WidgetsBinding.instance
        .addPostFrameCallback((_) => yourFunction(context));

import 'package:flutter/scheduler.dart';

SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));

1
두 번째는 더 이상 작동하지 않습니다. NoSuchMethodError (NoSuchMethodError: The method 'addPostFrameCallback' was called on null. Receiver: null
Oliver Dixon 19 년

1
@EliaWeiss-사용 사례에 따라 다름-빌드 후 위젯에서 함수를 호출하는 방법입니다. 일반적인 사용에있을 것 초기화 ()
anmol.majhail

22

세 가지 방법이 있습니다.

1) WidgetsBinding.instance.addPostFrameCallback((_) => yourFunc(context));

2) Future.delayed(Duration.zero, () => yourFunc(context));

3) Timer.run(() => yourFunc(context));

의 경우 모든 위젯이 렌더링 된 후 context에서 사용하기 위해 필요했습니다 Scaffold.of(context).

그러나 내 겸손한 의견으로는 가장 좋은 방법은 다음과 같습니다.

void main() async {
  WidgetsFlutterBinding.ensureInitialized(); //all widgets are rendered here
  await yourFunc();
  runApp( MyApp() );
}

14

Flutter 1.2-다트 2.2

공식 지침 및 소스 에 따라 레이아웃의 마지막 프레임 도 그려 졌는지 확인하려면 다음 과 같이 작성할 수 있습니다.

import 'package:flutter/scheduler.dart';

void initState() {
   super.initState();
   if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
        SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));
   }
}

나를 위해이 initState () 시간에 내가 함께 schedulerPhase를 얻을 수 있기 때문에, 작동하지 않았다 SchedulerPhase.idle의 실제로 일을 어떤 값을 ... 빌드 내에서 그 검사 ()를 추가하는 것이 었습니다
알레

11

ReactNative componentDidMount와 동등한 것을 찾고 있다면 Flutter가 있습니다. 그렇게 간단하지는 않지만 똑같은 방식으로 작동합니다. Flutter에서 Widgets는 이벤트를 직접 처리하지 않습니다. 대신 그들은 State그것을하기 위해 그들의 물건을 사용 합니다.

class MyWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => MyState(this);

  Widget build(BuildContext context){...} //build layout here

  void onLoad(BuildContext context){...} //callback when layout build done
}

class MyState extends State<MyWidget>{

  MyWidget widget;

  MyState(this.widget);

  @override
  Widget build(BuildContext context) => widget.build(context);

  @override
  void initState() => widget.onLoad(context);
}

State.initState화면이 레이아웃 렌더링을 마치면 즉시 호출됩니다. 디버그 모드에있는 경우 핫 리로드시에도 명시 적으로 수행 할 시간에 도달 할 때까지 다시 호출되지 않습니다.


내 예에서 StatefulWidget클래스를 사용 하여 State객체를 a처럼 처리 할 수 StatelessWidget있지만 권장하지는 않습니다. 나는 아직 어떤 문제도 발견하지 못했지만 State먼저 객체 내부의 모든 것을 구현해보십시오
jerinho.com

2
flutter.dev/docs/cookbook/networking/fetch-data Google은 initState ()에서 데이터 가져 오기를 호출 할 것을 권장합니다. 따라서이 솔루션에는 문제가 없으며 실제로 이것이 허용되는 답변이어야합니다.
개발자

React Native에서 데이터 가져 오기는 componentWillMount레이아웃 렌더링 직전에 수행 할 수 있습니다 . Flutter는 더 간단한 솔루션을 제공합니다. initState우리가 얼마나 제대로 그 일을 알고있는 경우 모두 데이터 페치 및 렌더링 레이아웃에 충분하다
jerinho.com

1
componentWillMount는 곧 지원 중단됩니다. 따라서 구성 요소가 마운트되고 구성된 후에 가져 오기가 수행됩니다.
개발자

10

Flutter 버전 1.14.6, Dart 버전 28.

아래는 나를 위해 일한 것입니다. 빌드 메소드 후에 발생하려는 모든 것을 별도의 메소드 또는 함수로 묶기 만하면됩니다.

@override
void initState() {
super.initState();
print('hello girl');

WidgetsBinding.instance
    .addPostFrameCallback((_) => afterLayoutWidgetBuild());

}

5

가장 좋은 방법은

1. WidgetsBinding

WidgetsBinding.instance.addPostFrameCallback((_) {
      print("WidgetsBinding");
    });

2. WidgetsBinding

SchedulerBinding.instance.addPostFrameCallback((_) {
  print("SchedulerBinding");
});

내부 initState에서 호출 할 수 있으며 둘 다 빌드 위젯이 렌더링을 완료 한 후에 한 번만 호출됩니다.

@override
  void initState() {
    // TODO: implement initState
    super.initState();
    print("initState");
    WidgetsBinding.instance.addPostFrameCallback((_) {
      print("WidgetsBinding");
    });
    SchedulerBinding.instance.addPostFrameCallback((_) {
      print("SchedulerBinding");
    });
  }

위의 두 코드는 모두 유사한 바인딩 프레임 워크를 사용하므로 동일하게 작동합니다. 차이점은 아래 링크를 찾으십시오.

https://medium.com/flutterworld/flutter-schedulerbinding-vs-widgetsbinding-149c71cb607f


3

SchedulerBinding을 사용해보십시오.

 SchedulerBinding.instance
                .addPostFrameCallback((_) => setState(() {
              isDataFetched = true;
            }));

0

이 작업을 한 번만 수행하려면 프레임 워크가 initState()생성하는 각 State 개체에 대해 정확히 한 번 메서드 를 호출하기 때문에 수행합니다 .

 @override
  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => executeAfterBuildComplete(context));
  }

이 작업을 반복하거나 다음 화면 등으로 이동하려면 didChangeDependencies()이 상태 개체의 종속성이 변경 될 때 호출 되기 때문에 수행하십시오 .

예를 들어 이전 호출 이 나중에 변경된를 build참조하는 InheritedWidget경우 프레임 워크는이 메서드를 호출하여이 개체에 변경 사항을 알립니다.

이 메서드는 initState. BuildContext.dependOnInheritedWidgetOfExactType이 메서드에서 호출 하는 것이 안전합니다 .

 @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => executeAfterBuildComplete(context));
  }

이것이 당신의 콜백 기능입니다.

executeAfterBuildComplete([BuildContext context]){
    print("Build Process Complete");
  }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.