Flutter-setState未更新内部自定义有状态小部件

时间:2019-08-19 08:12:10

标签: flutter dart cross-platform flutter-layout

我创建了一个“自定义细分”小部件,该小部件可根据列表创建多个TABS。我正在从selectionsList更新homepage.dart,但是我的段仍未根据更改的selectionsList

更新运行时

Segments.dart (用于创建Cupertino标签的自定义SegmentWidget)

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class SegmentsWidget extends StatefulWidget {
  @override
  _SegmentsWidgetState createState() => _SegmentsWidgetState();

  final List selectionsList;
  final ValueChanged<int> onSelectTab;
  final VoidCallback onTap;
  final int selectedValue;

  SegmentsWidget(
      {this.selectionsList, this.onSelectTab, this.onTap, this.selectedValue});
}

class _SegmentsWidgetState extends State<SegmentsWidget> {
  Map<int, Widget> tabWidget = Map<int, Widget>();
  int selectedTab = 0;


  @override
  void initState() {
    super.initState();
    print("INit State ${widget.selectionsList}");
    setState(() {
      widget.selectionsList.asMap().forEach((index, value) {
        tabWidget.addAll({
          index: Container(
              height: 40,
              child: Center(
                child: Text(
                  widget.selectionsList[index],
                  style: TextStyle(fontFamily: 'Exo2', fontSize: 12.0),
                ),
              ))
        });
      });
    });
  }

  @override
  void didUpdateWidget(SegmentsWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("Did update");
  }

  @override
  Widget build(BuildContext context) {

    return Container(
      child: Row(
        children: <Widget>[
          Expanded(
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              child: CupertinoSegmentedControl<int>(
                padding: EdgeInsets.symmetric(vertical: 8),
                children: tabWidget,
                onValueChanged: (int index) {
                  setState(() {
                    selectedTab = index;
                  });
                  widget.onSelectTab(index);
                },
                groupValue: widget.selectedValue ?? selectedTab,
              ),
            ),
          )
        ],
      ),
    );
  }
}

HomePage.dart

在主页上,我正在更新选择数组,但是我的细分仍然没有根据 selectionList 进行更新。

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  List<String> selection;
  int selectedTab = -1;

  @override
  void initState() {
    super.initState();
    selection = ["A", "B"];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Dynamic Segments")),
      body: Container(
        child: Column(
          children: <Widget>[

            SegmentsWidget(
              selectionsList: selection,
              onSelectTab: (selectTab) {
                setState(() {
                  selectedTab = selectTab;
                });
              },
            ),

            RaisedButton(child: Text("AB"),onPressed: (){
              setState(() {
                selection = ["A", "B"];
              });

            }),


            RaisedButton(child: Text("ABC"),onPressed: (){
              setState(() {
                selection = ["A", "B", "C"];
              });

            }),

          RaisedButton(child: Text("ABCD"),onPressed: (){
            setState(() {
              selection = ["A", "B", "C","D"];
            });

      })
          ],
        ),
      ),
    );
  }
}

我假设Segment Widget的 initState 仅调用了一次。我什至在 didUpdateWidget 中尝试过,但仍然无法获得更新的标签。

问题:如何从其他有状态窗口小部件更新自定义窗口小部件中提到的 tabWidgets

1 个答案:

答案 0 :(得分:1)

我更改了代码的某些部分。 不用在initState()函数中调用您的代码(需要在setState上再次调用),而是使用自己的方法在小部件内调用您的代码。

请参见下面的getTabChilds()函数。

class _SegmentsWidgetState extends State<SegmentsWidget> {
  Map<int, Widget> tabWidget = Map<int, Widget>();
  int selectedTab = 0;

  @override
  void initState() {
    super.initState();
    print("INit State ${widget.selectionsList}");
  }

  @override
  void didUpdateWidget(SegmentsWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("Did update");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        children: <Widget>[
          Expanded(
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              child: CupertinoSegmentedControl<int>(
                padding: EdgeInsets.symmetric(vertical: 8),
                children: getTabChilds(),
                onValueChanged: (int index) {
                  setState(() {
                    selectedTab = index;
                  });
                  widget.onSelectTab(index);
                },
                groupValue: widget.selectedValue ?? selectedTab,
              ),
            ),
          )
        ],
      ),
    );
  }

  Map<int, Widget> getTabChilds() {
    tabWidget = Map<int, Widget>();
    widget.selectionsList.asMap().forEach((index, value) {
      tabWidget.addAll({
        index: Container(
            height: 40,
            child: Center(
              child: Text(
                widget.selectionsList[index],
                style: TextStyle(fontFamily: 'Exo2', fontSize: 12.0),
              ),
            ))
      });
    });
    return tabWidget;
  }
}

它已经过测试并且可以正常工作。