Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dart 从StatefulWidget对象颤振更改状态_Dart_Flutter_State - Fatal编程技术网

Dart 从StatefulWidget对象颤振更改状态

Dart 从StatefulWidget对象颤振更改状态,dart,flutter,state,Dart,Flutter,State,与标题状态一样,如何从StatefulWidget访问StatefulWidget的状态 背景: 我有一个星级小工具,由5个“星级小工具”组成。StarWidget类只是一个带有检测器的图标(不使用IconButton,因为它的大小非常大)。StarWidget在相应的状态对象中存储它是否被选中,并相应地显示实心或轮廓图标 在我的主窗口小部件中,我可以访问StatefulWidget对象,并希望配置它们的状态 import 'package:flutter/material.dart'; im

与标题状态一样,如何从StatefulWidget访问StatefulWidget的状态

背景: 我有一个星级小工具,由5个“星级小工具”组成。StarWidget类只是一个带有检测器的图标(不使用IconButton,因为它的大小非常大)。StarWidget在相应的状态对象中存储它是否被选中,并相应地显示实心或轮廓图标

在我的主窗口小部件中,我可以访问StatefulWidget对象,并希望配置它们的状态

import 'package:flutter/material.dart';

import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class StarRatingWidget extends StatefulWidget {
  @override
  _StarRatingWidgetState createState() {
    return _StarRatingWidgetState();
  }
}

class _StarRatingWidgetState extends State<StarRatingWidget>
    implements StarSelectionInterface {
  //Properties
  int _currentRating = 0;
  List<RatingStarWidget> starWidgets = [];

  //Methods
  @override
  void initState() {
    super.initState();
    starWidgets.add(
      RatingStarWidget(
        starSelectionInterface: this,
        starPosition: 0,
      ),
    );
    starWidgets.add(
      RatingStarWidget(
        starSelectionInterface: this,
        starPosition: 1,
      ),
    );
    starWidgets.add(
      RatingStarWidget(
        starSelectionInterface: this,
        starPosition: 2,
      ),
    );
    starWidgets.add(
      RatingStarWidget(
        starSelectionInterface: this,
        starPosition: 3,
      ),
    );
    starWidgets.add(
      RatingStarWidget(
        starSelectionInterface: this,
        starPosition: 4,
      ),
    );
  }

  @override
  Widget build(BuildContext buildContext) {
    return Row(
      children: starWidgets,
    );
  }

  //Star Selection Interface Methods
  void onStarSelected(_RatingStarWidgetState starWidgetState) {
    print("listener: star selected ${starWidgetState._starPosition}");

    //a new, rating has been selected, update rating
    if (_currentRating != starWidgetState._starPosition) {
      _currentRating = (starWidgetState._starPosition + 1);
    }

    //same star as rating has been selected, set rating to 0
    else {
      _currentRating = 0;
    }

    //update stars according to rating
    for(int i = 1; i <= 5; i++) {
      //what should I do here?!
    }
  }
}

class RatingStarWidget extends StatefulWidget {
  //Properties
  final int starPosition;
  final StarSelectionInterface starSelectionInterface;

  //Constructors
  RatingStarWidget({this.starSelectionInterface, this.starPosition});

  //Methods
  @override
  _RatingStarWidgetState createState() {
    return _RatingStarWidgetState(starSelectionInterface, starPosition);
  }
}

class _RatingStarWidgetState extends State<RatingStarWidget> {
  //Properties
  int _starPosition;
  bool _isSelected = false;
  StarSelectionInterface selectionListener;

  //Constructors
  _RatingStarWidgetState(this.selectionListener, this._starPosition);

  //Methods
  @override
  Widget build(BuildContext buildContext) {
    return AnimatedCrossFade(
      firstChild: GestureDetector(
        child: Icon(
          FontAwesomeIcons.star,
          size: 14,
        ),
        onTap: () {
          print("star: selected");
          selectionListener.onStarSelected(this);
        },
      ),
      secondChild: GestureDetector(
        child: Icon(
          FontAwesomeIcons.solidStar,
          size: 14,
        ),
        onTap: () {
          selectionListener.onStarSelected(this);
        },
      ),
      duration: Duration(milliseconds: 300),
      crossFadeState:
          _isSelected ? CrossFadeState.showSecond : CrossFadeState.showFirst,
    );
  }
}

class StarSelectionInterface {
  void onStarSelected(_RatingStarWidgetState starWidgetState) {}
}
导入“包装:颤振/材料.省道”;
导入“package:font_awesome_flatter/font_awesome_flatter.dart”;
类StarRatingWidget扩展StatefulWidget{
@凌驾
_StarRatingWidgetState createState(){
返回_startingwidgetstate();
}
}
类_startingwidgetstate扩展状态
实现StarSelectionInterface{
//性质
int _额定电流=0;
列出starWidgets=[];
//方法
@凌驾
void initState(){
super.initState();
starWidgets.add(
RatingStarWidget(
starSelectionInterface:这个,
起始位置:0,
),
);
starWidgets.add(
RatingStarWidget(
starSelectionInterface:这个,
星位:1,
),
);
starWidgets.add(
RatingStarWidget(
starSelectionInterface:这个,
星位:2,
),
);
starWidgets.add(
RatingStarWidget(
starSelectionInterface:这个,
星位:3,
),
);
starWidgets.add(
RatingStarWidget(
starSelectionInterface:这个,
起始位置:4,
),
);
}
@凌驾
小部件构建(构建上下文构建上下文){
返回行(
孩子们:星际精灵,
);
}
//星选择接口方法
已选择starWidgetState(\u评级starWidgetState starWidgetState){
打印(“侦听器:星型选定${starWidgetState._starPosition}”);
//已选择新的评级,更新评级
如果(_currentRating!=starWidgetState._starPosition){
_额定电流=(starWidgetState.\u starPosition+1);
}
//已选择与评级相同的星星,将评级设置为0
否则{
_额定电流=0;
}
//根据评级更新星号

对于(int i=1;i我写了一个与您类似的示例。我在这里做的是:

初始星号速率为-1,因为数组从0开始;),我使用位置、当前星号速率和回调函数创建星号。我们将使用此回调函数更新
屏幕一中的值

Star
小部件中,我们选择了一个本地bool
和一个默认值false,并根据Star的位置和当前速率在构建函数中为其分配一个值
函数,该函数运行回调函数并用星号位置值更新
当前速率

检查视频示例

class ScreenOne扩展StatefulWidget{
@凌驾
_ScreenOneState createState()=>\u ScreenOneState();
}
类_ScreenOneState扩展状态{
int currentRate=-1;//由于数组从0开始,所以将non-selected设置为-1
List starList=[];//空列表
@凌驾
void initState(){
super.initState();
buildStars();//初始加载时在此处开始生成
}
Widget buildStars(){
星表=[];
对于(变量i=0;i<5;i++){
星号列表。添加(星号)(
职位:我,
当前:当前速率,
updateParent:refresh,//这是回调
));
}
}
刷新(整型索引){
设置状态(){
currentRate=index;//更新currentRate
});
buildStars();//再次构建stars
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
背景颜色:Colors.white,
appBar:appBar(
标题:文本(“测试页1”),
),
主体:容器(
儿童:中心(
孩子:排(
mainAxisAlignment:mainAxisAlignment.center,
孩子们:星际名单,
),
),
),
);
}
}
类Star扩展StatefulWidget{
final函数(int index)updateParent;//回调
最终int位置;//星的位置
final int current;//当前从父级选择的星号
常量星({Key Key,this.position,this.updateParent,this.current})
:super(key:key);
@凌驾
_StarState createState();
}
类_StarState扩展状态{
bool selected=false;
无效{
widget.updateParent(widget.position);
}
@凌驾
小部件构建(构建上下文){
if(widget.current>=widget.position){
所选=真;
}否则{
所选=假;
}
返回手势检测器(
子对象:动画交叉淡入淡出(
第一个孩子:图标(图标。星形边框),
第二个孩子:图标(Icons.star),
克罗斯法德庄园:
选中?CrossFadeState.showSecond:CrossFadeState.showFirst,
持续时间:持续时间(毫秒:300),
),
onTap:(){
设置已选();
},
);
}
}

颤振的方法是在必要时重新构建小部件。不要害怕构建小部件,它们对于SDK来说很便宜,尤其是对于简单的星星

访问另一个小部件状态需要更多的工作,而不仅仅是重建它。要访问该状态,您应该使用键,或者应该在小部件本身中添加特殊方法

在这种情况下,不管发生什么情况都要重建星形,使用普通的无状态小部件会更好、更简单,因为所选状态可以在重建时由父级提供

由于状态存储在父窗口小部件中,我认为最好在每个单独的星星中将其存储为墙

接下来是一个非常简单的解决方案,遵循这个想法。但是,是的,它仍然重建恒星

import 'package:flutter/material.dart';

import 'package:font_awesome_flutter/font_awesome_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(body: Center(child: StarRatingWidget())),
    );
  }
}

class StarRatingWidget extends StatefulWidget {
  @override
  _StarRatingWidgetState createState() {
    return _StarRatingWidgetState();
  }
}

class _StarRatingWidgetState extends State<StarRatingWidget> {
  int _currentRating = 0;

  List<Widget> buildStars() {
    List<RatingStarWidget> starWidgets = [];
    for (int i = 0; i < 5; i++) {
      starWidgets.add(
        RatingStarWidget(
          clickCallback: () => setState(() {
                _currentRating = i + 1;
              }),
          highlighted: _currentRating > i,
        ),
      );
    }
    return starWidgets;
  }

  @override
  Widget build(BuildContext buildContext) {
    return Row(
      children: buildStars(),
    );
  }
}

class RatingStarWidget extends StatelessWidget {
  //Properties
  final VoidCallback clickCallback;
  final bool highlighted;

  //Constructors
  RatingStarWidget({this.clickCallback, this.highlighted});

  @override
  StatelessElement createElement() {
    print("Element created");
    return super.createElement();
  }

  //Methods
  @override
  Widget build(BuildContext buildContext) {
    return GestureDetector(
      onTap: () {
        clickCallback();
      },
      child: AnimatedCrossFade(
        firstChild: Icon(
          FontAwesomeIcons.star,
          size: 14,
        ),
        secondChild: Icon(
          FontAwesomeIcons.solidStar,
          size: 14,
        ),
        duration: Duration(milliseconds: 300),
        crossFadeState:
            highlighted ? CrossFadeState.showSecond : CrossFadeState.showFirst,
      ),
    );
  }
}
import'包装:颤振/材料
import 'package:flutter/material.dart';

import 'package:font_awesome_flutter/font_awesome_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(body: Center(child: StarRatingWidget())),
    );
  }
}

class StarRatingWidget extends StatefulWidget {
  @override
  _StarRatingWidgetState createState() {
    return _StarRatingWidgetState();
  }
}

class _StarRatingWidgetState extends State<StarRatingWidget> {
  int _currentRating = 0;

  List<Widget> buildStars() {
    List<RatingStarWidget> starWidgets = [];
    for (int i = 0; i < 5; i++) {
      starWidgets.add(
        RatingStarWidget(
          clickCallback: () => setState(() {
                _currentRating = i + 1;
              }),
          highlighted: _currentRating > i,
        ),
      );
    }
    return starWidgets;
  }

  @override
  Widget build(BuildContext buildContext) {
    return Row(
      children: buildStars(),
    );
  }
}

class RatingStarWidget extends StatelessWidget {
  //Properties
  final VoidCallback clickCallback;
  final bool highlighted;

  //Constructors
  RatingStarWidget({this.clickCallback, this.highlighted});

  @override
  StatelessElement createElement() {
    print("Element created");
    return super.createElement();
  }

  //Methods
  @override
  Widget build(BuildContext buildContext) {
    return GestureDetector(
      onTap: () {
        clickCallback();
      },
      child: AnimatedCrossFade(
        firstChild: Icon(
          FontAwesomeIcons.star,
          size: 14,
        ),
        secondChild: Icon(
          FontAwesomeIcons.solidStar,
          size: 14,
        ),
        duration: Duration(milliseconds: 300),
        crossFadeState:
            highlighted ? CrossFadeState.showSecond : CrossFadeState.showFirst,
      ),
    );
  }
}