无法使用外部小部件设置状态

时间:2019-08-22 12:25:00

标签: flutter dart

我正在使用颤动,并尝试在点击它时更改图标的状态(切换图标)。如果所有内容都在同一个类上,则此方法很好。但是我在重复的页面中重复了窗口小部件的一部分,因此我已经将该窗口小部件移到了另一个类。现在,当我尝试根据调试步骤通过传递函数来设置状态时,看起来它工作正常,但状态保持不变(图标不变)。我能知道我在做什么错吗?谢谢。

这是我从另一个类调用小部件并传递函数以设置状态的类。

class _MyPageState extends State<MyPage> {
  IconData heartStatus = FontAwesomeIcons.heart;

  void setFav(){
    print('clicked');
    setState(() {
      if (heartStatus == FontAwesomeIcons.heart) {
        heartStatus = FontAwesomeIcons.solidHeart;
      } else {
        heartStatus = FontAwesomeIcons.heart;
      }
    });
  }

  @override
  Widget build(BuildContext context) {

    Page page = new Page();
    PageController controller = PageController();

    return Scaffold(
      backgroundColor: Colors.blue,
      body: SafeArea(
        child: PageView(
          children: <Widget>[
            // this is the external widget repeated 3 times. Each time passing in setFav which is the setState function. 
            page.getPageData("text 1", "", setFav),
            page.getPageData("text 2", "", setFav),
            page.getPageData("text 3", "", setFav),
          ],
        ),
      ),
    );
  }
}

这是通过page.getPageData提供窗口小部件的类(我已删除了许多嵌套窗口小部件,以专注于与此设置状态问题重要的图标,即Icon)。

class Page{

  Widget getPageData(String question, String answer, Function setFav){
    IconData heartStatus = FontAwesomeIcons.heart;
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              GestureDetector(
                child: Icon(heartStatus),
                onTap: () {
                  setFav();
                },
              ),
              GestureDetector(
                child: Icon(FontAwesomeIcons.shareAlt),
                onTap: () {
                  print('shared');
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:1)

您正在提供setFav方法,该方法调用setState来更改MyPage小部件中的图标。

我认为您的目标是更改从getPageData方法返回的小部件中的图标。

使用setFav方法更改MyPage中的图标后,您将不再使用此图标。您在PageView中的小部件未使用该图标。

我强烈建议您使用小部件,而不要使用功能。 https://iirokrankka.com/2018/12/11/splitting-widgets-to-methods-performance-antipattern/

class Page extends StatelessWidget {
  Page({this.changeIcon, this.heartStatus});

  Function changeIcon;
  IconData heartStatus;
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              GestureDetector(
                child: Icon(heartStatus),
                onTap: () {
                  changeIcon();
                },
              ),
              GestureDetector(
                child: Icon(FontAwesomeIcons.shareAlt),
                onTap: () {
                  print('shared');
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}

...

child: PageView(
          children: <Widget>[
            // this is the external widget repeated 3 times. Each time passing in setFav which is the setState function. 
            Page(heartStatus,setFav);
            Page(heartStatus,setFav);
            Page(heartStatus,setFav);
          ],
        ),