Flutter:从子窗口小部件设置父窗口小部件状态

Raf*_*fff 5 dart flutter

我对 Flutter 和 Dart 非常初学者。所以我试图更新父小部件的状态,但说实话,在尝试了许多不同的解决方案后,没有一个对我有用,或者我做错了什么?

我想做的是当 _Books() 类中的页面更改时更新 _BooksState() 中的_title 。

如何从子 (_Books()) 小部件设置 _title 状态?

class Books extends StatefulWidget {
  @override
  _BooksState createState() {
    return _BooksState();
  }
}

class _BooksState extends State<Books> {
  String _title = 'Books';

  _setTitle(String newTitle) {
    setState(() {
      _title = newTitle;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_title),
      ),
      body: _Books(),
    );
  }
}

class _Books extends StatelessWidget {
  final PageController _controller = PageController();
  final Stream<QuerySnapshot> _stream =
      Firestore.instance.collection('Books').orderBy('title').snapshots();

  _setAppBarTitle(String newTitle) {
    print(newTitle);
    // how do I set _title from here?
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: _stream,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        final books = snapshot.data.documents;
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return Center(child: CircularProgressIndicator());
          default:
            return PageView.builder(
              controller: _controller,
              scrollDirection: Axis.horizontal,
              itemCount: books.length,
              itemBuilder: (context, index) {
                final book = books[index];
                return ListTile(
                  title: Text(book['title']),
                  subtitle: Text(book['author']),
                );
              },
              onPageChanged: (index) {
                _setAppBarTitle(books[index].data['title']);
              },
            );
        }
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Ami*_*gid 0

您可以做的是将您的_Books类移动到类内部。您可以将其用作内部类_BooksState,而不是用作类,以便您可以访问您创建的内部方法。_BooksWidget_BooksStatesetStateStatefulWidgetWidget

我这样做,即使我是 Flutter 和 Dart 的新手......即使在进行 API 调用之后,这在任何情况下都对我有用......我能够使用setState和设置 API 的响应。

例子:

class Books extends StatefulWidget {
  @override
  _BooksState createState() {
    return _BooksState();
  }
}

class _BooksState extends State<Books> {
  String _title = 'Books';

  _setTitle(String newTitle) {
    setState(() {
      _title = newTitle;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_title),
      ),
      body: _books(), // Using the Widget here
    );
  }

  // Your `_Books` class created as `Widget` for setting state and new title.
  Widget _books() {
    final PageController _controller = PageController();
    final Stream<QuerySnapshot> _stream =
    Firestore.instance.collection('Books').orderBy('title').snapshots();

    _setAppBarTitle(String newTitle) {
      print(newTitle);
      // how do I set _title from here?

      // Since you created this method and setting the _title in this method 
      // itself using setstate you can directly pass the new title in this method..
      _setTitle(newTitle);
    }

    return StreamBuilder<QuerySnapshot>(
      stream: _stream,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        final books = snapshot.data.documents;
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return Center(child: CircularProgressIndicator());
          default:
            return PageView.builder(
              controller: _controller,
              scrollDirection: Axis.horizontal,
              itemCount: books.length,
              itemBuilder: (context, index) {
                final book = books[index];
                return ListTile(
                  title: Text(book['title']),
                  subtitle: Text(book['author']),
                );
              },
              onPageChanged: (index) {
                _setAppBarTitle(books[index].data['title']);
              },
            );
        }
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)