【问题标题】:Flutter: initState in custom state full widget not triggered for second timeFlutter:自定义状态完整小部件中的 initState 未第二次触发
【发布时间】:2023-04-03 20:24:01
【问题描述】:

我有一个具有 id 的数据列表:

 [
        {
            "id": 1,
            "title": "close",
        },
        {
            "id": 2,
            "title": "car",
        },

我在列表视图中用水平轴显示这个列表:

Column(
              children: <Widget>[
                Container(
                  height: 50.0,
                  color: Colors.white,
                  child: ListView.builder(
                    scrollDirection: Axis.horizontal,
                    itemCount: _categories.data.length,
                    itemBuilder: (_, index) {
                      return Container(
                        child: InkWell(
                          onTap: () {
                            setState(() {
                              _selectedCat = _categories.data[index].id;
                            });
                          },
                          child: Container(
                            color: (index + 1) ==
                                    _categories.pagination.currentPage
                                ? Colors.red
                                : Colors.white,
                            margin: EdgeInsets.all(8.0),
                            child: Text(
                              _categories.data[index].title,
                              style: TextStyle(
                                  fontSize: 16.0, fontWeight: FontWeight.bold),
                            ),
                          ),
                        ),
                      );
                    },
                  ),
                ),
                Expanded(child: CategoryWidget(selectedCat: _selectedCat))
              ],
            ),

在 CategoryWidget 中,我显示了与上述数据相关的项目:

class CategoryWidget extends StatefulWidget {
  final int id;
  const CategoryWidget({@required this.id});

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

class _CategoryWidgetState extends State<CategoryWidget> {
  Future _future;

  @override
  void initState() {
    _future = HomeProvider().getItems(widget.id); // not triggered 
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: FutureBuilder<ItemModel>(
        future: _futureCategory,
        builder: (context, snapshot) {
         if (snapshot.hasData) {
            return ListView.builder(
                itemCount: snapshot.data.data.length,
                itemBuilder: (_, index) {
                  return Text(snapshot.data.data[index].name);
                });
        },
      ),
    );
  }
}

但是当我在每个水平项目上录音时:

  onTap: () {
    setState(() {
      _selectedCat = _categories.data[index].id;
    });
  }

并且设置状态已完成,CategoryWidget 中的initState 未触发?

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    initState() 不会在您重新构建状态时被触发,它只会被触发一次,那就是在加载小部件时,build 方法是在您重新构建状态时触发的。

    将您的代码更改为:

     @override
      Widget build(BuildContext context) {
       _future = HomeProvider().getItems(widget.id);
        return Container(
          child: FutureBuilder<ItemModel>(
            future: _futureCategory,
            builder: (context, snapshot) {
             if (snapshot.hasData) {
                return ListView.builder(
                    itemCount: snapshot.data.data.length,
                    itemBuilder: (_, index) {
                      return Text(snapshot.data.data[index].name);
                    });
            },
          ),
        );
      }
    }
    

    【讨论】:

    • 我该如何解决我的问题? @hiwajalal
    • 你的意思是我覆盖了孩子的 setState 方法? @hiwajalal
    • 你的意思是我把未来传给孩子? ` CategoryWidget({@required this.selectedCat, this.future});` @hiwajalal
    【解决方案2】:

    State 类中明确提到了'docs

    我认为正确的做法是重写 State 子类中的 didUpdateWidget 方法。

    @override
      void initState() {
        _getItem();
        super.initState();
      }
    
      @override
      void didUpdateWidget(CategoryWidget oldWidget) {
        _getItem();
        super.didUpdateWidget(oldWidget);
      }
    
      void _getItem() async {
        _future = HomeProvider().getItems(widget.id);
      }
    

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 2021-12-09
      • 1970-01-01
      • 2021-10-22
      • 2021-09-04
      • 1970-01-01
      • 2021-11-27
      • 2021-03-10
      • 2019-04-01
      相关资源
      最近更新 更多