首页 > 解决方案 > 处理有状态小部件的变量

问题描述

我有ListView其内容是动态加载的小部件。

所以我决定制作 myStatelessWidget。

我的基本想法是

  1. 保持变量articles显示在 StatefulWidget 或 State 的 ListView 上。

  2. 从外面传递内容。

所以现在,我这样写,但它有错误。

我的基本想法是否正确?或者我应该在哪里修复?

//// to pass the argument from outside.
new BodyLayout(articles: myarticles),
////

class BodyLayout extends StatefulWidget {
  // List<Article> articles // ???I should put here/?
  BodyLayout({articles});
  @override
  _BodyLayoutState createState() => _BodyLayoutState();
}
class _BodyLayoutState extends State<BodyLayout>{
  // List<Article> articles // ???I should put here/?
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: widget.articles.length, // the getter 'articles' is not defined error....
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(widget.articles[index].title),
          onTap: () => onTapped(context,widget.articles[index].url),
        );
      },
    );
  }
}

标签: flutterdart

解决方案


如果您要调用 setState() 方法来重建具有一些新状态的小部件,则只需要使用有状态小部件。如果您需要从某个 api 或数据库调用中检索文章列表,您可能会这样做的一种情况是,如果文章列表为空,则让小部件返回加载指示符,进行异步调用以检索文章state 类的 initState() 方法,当它返回时,通过使用检索到的文章列表调用 setState() 来重建小部件。像这样,也许:

/// to pass the argument from outside.
new BodyLayout(),
///

class BodyLayout extends StatefulWidget {
  BodyLayout();

  @override
  _BodyLayoutState createState() => _BodyLayoutState();
}

class _BodyLayoutState extends State<BodyLayout>{

  List<Article> articles;
  bool loading = true;

  @override
  void initState(){
    _getArticles();
  }

  void getArticles() async {
    articles = await Repository.instance.getArticles(); //some async method to retrieve the articles
    setState((){
        loading = false;
    });    // after the articles are retrieved you can call setState to rebuild the widget
  }

  @override
  Widget build(BuildContext context) {
    if(loading) {
      return CircularProgressIndicator();
    }
    return ListView.builder(
      itemCount: articles.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(articles[index].title),
          onTap: () => onTapped(context, articles[index].url),
        );
      },
    );
  }
}

如果您有文章列表开始并且不需要重建列表,您可以将其设为无状态小部件并传入文章列表。

您指出的错误似乎是因为文章实际上并未定义为该类的变量。Dart 支持多种语法选项来传递这样的实例变量,但这是我定义该变量并确保在创建小部件时将其传入的方式(可以是无状态或有状态小部件):

//// to pass the argument from outside.
new BodyLayout(articles: myarticles),
////

class BodyLayout extends StatelessWidget {
  final List<Article> articles
  BodyLayout({this.articles}) : assert(articles != null);

  @override
  Widget build(BuildContext context){ ... };
}

推荐阅读