2017-11-02 8 views
1

플러터 앱이 서랍을 사용하여 탐색 할 수있는 서랍과 두 개의 "페이지"(발판)로 구성이 예 : 위젯이 보이지 않더라도 State의 build() 메서드가 계속 호출되는 이유는 무엇입니까?

import 'package:flutter/material.dart'; 

class MyTestDrawer extends StatefulWidget { 
    @override 
    _MyTestDrawerState createState() => new _MyTestDrawerState(); 
} 

class _MyTestDrawerState extends State<MyTestDrawer> { 
    @override 
    Widget build(BuildContext context) { 

    return new Drawer(child: new ListView(
     children: <Widget>[ 

      new ListTile(
       leading: new Icon(Icons.pregnant_woman), 
       title: new Text('Homepage'), 
       onTap:() { 
       Navigator.of(context).pushNamed('/'); 
       } 
     ), 
      new ListTile(
       leading: new Icon(Icons.group), 
       title: new Text('Second page'), 
       onTap:() { 
       Navigator.of(context).pushNamed('/second'); 
       } 
     ), 
      new AboutListTile(
       icon: new Icon(Icons.help) 
     ) 
     ] 
    ) 
    ); 

    } 
} 

final MyTestDrawer _drawer = new MyTestDrawer(); 


class FlutterTestApp extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 

    return new MaterialApp(
     title: 'Flutter Test', 
     theme: new ThemeData(
      primarySwatch: Colors.blue, 
     ), 
     home: new HomepageWidget(), 
     routes: <String, WidgetBuilder> { 
      '/second': (BuildContext context) => new SecondPage(), 
     } 
    ); 


    } 
} 


class HomepageWidget extends StatefulWidget { 
    @override 
    _HomepageWidgetState createState() => new _HomepageWidgetState(); 
} 

class _HomepageWidgetState extends State<HomepageWidget> { 
    @override 
    Widget build(BuildContext context) { 
    print('build: ' + this.toString()); 

    return new Scaffold(
     drawer: _drawer, 
     appBar: new AppBar(title: new Text('Homepage')), 
     body: new Container(
      child: new Center(child: new Text('Homepage')) 
    ) 
    ); 
    } 
} 


class SecondPage extends StatefulWidget { 
    @override 
    _SecondPageState createState() => new _SecondPageState(); 
} 

class _SecondPageState extends State<SecondPage> { 
    @override 
    Widget build(BuildContext context) { 

    print('build: '+ this.toString()); 

    return new Scaffold(
     drawer: _drawer, 
     appBar: new AppBar(title: new Text('Second page')), 
     body: new Container(
      child: new Center(child: new Text('Second page')) 
     ) 
    ); 
    } 
} 



void main() { 
    runApp(new FlutterTestApp()); 
} 

내가 HomepageState 및 SecondPageState 빌드() 메소드 모두에서 print 디버그 문을 가지고있다.

나는이 응용 프로그램을 실행하고 홈페이지두 번째 페이지 사이를 이동할 때 나는 결국 내 로그에이 얻을 :

build: _HomepageWidgetState#e0d4a 
build: _SecondPageState#06d69 
build: _SecondPageState#9c9f7 
build: _SecondPageState#db373 
build: _SecondPageState#4d4ca 
build: _SecondPageState#15247 
build: _SecondPageState#06d69 
build: _SecondPageState#9c9f7 
build: _SecondPageState#db373 
build: _SecondPageState#4d4ca 
build: _HomepageWidgetState#0d598 
build: _HomepageWidgetState#3bb96 
build: _HomepageWidgetState#09270 
build: _HomepageWidgetState#640bb 
build: _HomepageWidgetState#6385a 
build: _HomepageWidgetState#ed720 
build: _HomepageWidgetState#f45da 

새로운 상태 객체가 나는 사이를 이동할 때마다 생성됩니다 보인다 위젯이 현재 보이지 않는 경우에도 두 페이지와 build() 메소드가 계속 호출됩니다.

분명히 뭔가 잘못되었습니다 (?) - 여기서 무슨 일이 일어나고 있습니까?

답변

1

Navigator.of(context).pushNamed('/');과 같은 메소드는 일반적으로 새 위젯을 만들고 "푸시"합니다. 그것은 당신이 새로운 국가를 가지고있는 이유 일 수 있습니다.

당신은 Stocks app

+0

그래, 새 위젯은 괜찮지 만 왜 이전 참조를 유지하고 build()를 계속 실행합니까? –

+0

감사합니다. 올바른 방향으로 나를 가리키는 것처럼 정확한 것으로 표시했습니다. 두 가지 이유가 있습니다. 1. 두 위젯 모두 동일한 서랍 인스턴스를 공유합니다 (서랍이 참조 서적을 영원히 유지하고 있다고 생각합니까?). 2. 현재 페이지를 탐색하다가 서랍을 열어야합니다 (2 차 참조를 얻지 못하게). 하지만 여기서 가장 중요한 문제는 내가 언급 한 첫 번째 문제라고 생각합니다. –

1

떨림에 서랍의 예를 찾을 수 있습니다 당신이 밀어 각 경로에 대한 State 객체를 생성하고, 그 build() 방법은 네비게이터 스택에 새로운 경로를 밀어 때마다 호출된다. 현재 스택에서 아무것도 팝하는 방법을 제공하지 않습니다.

SecondPage에 서랍을 지정하지 말고 대신 뒤로 버튼을 사용하여 사용자가 홈 페이지로 돌아가도록합니다. 이렇게하면 Navigator 기록 스택이 임의로 커지는 것을 막을 수 있습니다.

+0

콜린에게 감사 드려요. 서랍이있는 메인 페이지와 뒤로 버튼이있는 나머지 페이지가 있습니다. 귀하의 설명이 이치에 맞습니다. 그래서 서랍으로 여러 경로를 갖고 싶다면 네비게이션 전에 서랍이 있으면 현재 경로를 팝업해야합니다. –