【问题标题】:Flutter bloc: updating the state does not refresh my view which is manged by blocFlutter bloc:更新状态不会刷新我由 bloc 管理的视图
【发布时间】:2020-11-21 13:15:28
【问题描述】:

性别页面

class GenderPage extends StatelessWidget {
  final UserRepository userRepository;

  GenderPage({@required this.userRepository});

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => SexblocBloc(userRepository: userRepository),
      child: SelectGenderPage(userRepository: userRepository),
    );
  }
}

// ignore: must_be_immutable
class SelectGenderPage extends StatelessWidget {
  UserRepository userRepository;
  FirebaseUser user;
  ProgressDialog pr;
  SexblocBloc sexblocBloc;
 bool isSelecte=false;
 bool isSelecteds=true;

  SelectGenderPage({this.userRepository});
  @override
  Widget build(BuildContext context) {
     sexblocBloc = BlocProvider.of<SexblocBloc>(context);
    pr = ProgressDialog(
      context,
      type: ProgressDialogType.Normal,
      isDismissible: false,
    );
    pr.style(
        message: 'Loading please wait...',
        borderRadius: 2.0,
        progressWidget: Padding(
          padding: const EdgeInsets.all(8.0),
          child: CircularProgressIndicator(
              valueColor: AlwaysStoppedAnimation(Colors.pinkAccent),
              strokeWidth: 2.0),
        ),
        elevation: 10.0,
        insetAnimCurve: Curves.easeInOut,
        messageTextStyle:
            TextStyle(fontSize: 18.0, fontWeight: FontWeight.w300));

    // Size size = MediaQuery.of(context).size;
    return Scaffold(
      
      bottomNavigationBar: BottomAppBar(
        child: InkWell(
          onTap: () {
            
          },
          child: Container(
            color: Colors.pink,
            height: 46,
            width: double.infinity,
            child: Center(
              child: Text(
                'Next',
                style: TextStyle(
                  fontSize: 16,
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ),
      ),

      body:  Builder(builder: (BuildContext context) {
        return Container(
              padding: EdgeInsets.only(left: 16, right: 16),
                child: Container(
                  child:  BlocListener<SexblocBloc, SexblocState>(
              listener: (context, state)  async {
                if (state is SexLoadingState) {
                        pr.hide();
                } else if(state is SexblocInitial){
                      isSelecte=false;
                      isSelecteds=true;
                        pr.hide();
                }
                else if (state is SexblocSelectedMaleState)  {
                    pr.hide();
                      print("Malee");
                      isSelecteds=true;
                      isSelecte=false;
                 
                } else if (state is SexblocSelectedFemaleState)  {
                    pr.hide();
                     print("FeMale");
                      isSelecte=true;
                      isSelecteds=false;
                }
                else if (state is SexFailState) {
                     pr.hide();
                  }
              },

      
      child : Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Container(
              padding: EdgeInsets.only(bottom: 10),
              width: 320,
              child: Text('I am a',
                  style: TextStyle(
                    fontSize: 30,
                    // color: Colors.pink,
                  )),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                DispalyBox(
                  context:context,
                   sexblocBloc : sexblocBloc,
                    userRepository: userRepository,
                    imgURL: 'images/male.png',
                    sex: 'Male',
                    backColor: Color(0xFF4286F4),
                    isSelected: isSelecteds),
                    
                SizedBox(
                  width: 20,
                ),
                DispalyBox(
                   context:context,
                     sexblocBloc : sexblocBloc,
                    userRepository: userRepository,
                    imgURL: 'images/female.png',
                    sex: 'Female',
                    backColor: Color(0xFF0F9D58),
                    isSelected: isSelecte),
              ],
            ),
          ]),

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

  void navigateToUserPage(
      BuildContext context, UserRepository userRepository, String gender) {
    //prefs.setGenderVal(gender);
    Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) {
      return SelectUserPage(userRepository: userRepository);
    }));
  }
}

class DispalyBox extends StatelessWidget {
  const DispalyBox({
    Key key,
     @required this.context,
    @required this.userRepository,
    @required this.imgURL,
    @required this.sex,
    @required this.backColor,
    @required this.isSelected,
     @required this.sexblocBloc,
  }) : super(key: key);

  final UserRepository userRepository;
    final  BuildContext context;
  final String imgURL;
  final String sex;
  final Color backColor;
  final bool isSelected;
  final  SexblocBloc sexblocBloc;
  
  @override
  Widget build( context) {
     print(isSelected);
    return InkWell(
      onTap: () {

        if(sex=='Male'){
           sexblocBloc.selectGender(sex);
        }else{  
          sexblocBloc.selectFemaleGender(sex);
        }
        
       
      },
      child: Container(
          height: 180,
          width: 150,
          foregroundDecoration: BoxDecoration(
            color: isSelected ? Colors.transparent : Colors.black,
            backgroundBlendMode: BlendMode.saturation,
          ),
          child: Card(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7.0),
            ),
            child: Stack(
              children: <Widget>[
                Positioned(
                  top: 10,
                  left: 10,
                  child: Icon(
                    Icons.adjust,
                    color: backColor,
                    size: 24.0,
                    semanticLabel: '',
                  ),
                ),
                Positioned(
                  top: 10,
                  left: 40,
                  child: Text(sex,
                      style: TextStyle(
                        fontSize: 20,
                        color: Colors.amber,
                      )),
                ),
                Positioned(
                  bottom: 0,
                  right: 3,
                  child: Image(
                    width: 135,
                    image: AssetImage(imgURL),
                  ),
                ),
              ],
            ),
          )),
    );
  }
}

性别群体

class SexblocBloc extends Bloc<SexblocEvent, SexblocState> {
UserRepository userRepository;

  SexblocBloc({UserRepository userRepository}) : super(null) {
    this.userRepository = userRepository;
  }

  SexblocState get initialState => SexblocInitial();

  @override
  Stream<SexblocState> mapEventToState(SexblocEvent event,) async* {
 if (event is SexButtonPressed) {
      yield SexLoadingState();
      try {
        
        yield SexblocSelectedMaleState(true);
      } catch (e) {
        print(e.toString());    
        yield SexFailState(e.toString());
      }
    }else if(event is FeMaleSexButtonPressed) {
      yield SexLoadingState();
      try {
        
        yield SexblocSelectedFemaleState(true);
      } catch (e) {
        print(e.toString());    
        yield SexFailState(e.toString());
      }
    }

    
  }


 //Gender button pressed
  selectGender(String sex) async {
    //SessionManager prefs=SessionManager();
    //String sex = await prefs.getGenderValue();
    print('GenderButtonPressed');
    add(
      SexButtonPressed(sex:sex),
    );
  }

  //Gender button pressed
  selectFemaleGender(String sex) async {
    //SessionManager prefs=SessionManager();
    //String sex = await prefs.getGenderValue();
    print('GenderButtonPressed');
    add(
      FeMaleSexButtonPressed(sex:sex),
    );
  }

}

性别状态

abstract class SexblocState extends Equatable {
  const SexblocState();
}

class SexblocInitial extends SexblocState {
  @override
   List<Object> get props => null;
}

class SexLoadingState extends SexblocState {
  @override
  List<Object> get props => null;
}

class SexblocSelectedMaleState extends SexblocState {
   final bool select ;
  SexblocSelectedMaleState(this.select);
  @override
  List<Object> get props => null;
}
class SexblocSelectedFemaleState extends SexblocState {
   final bool select ;
  SexblocSelectedFemaleState(this.select);
  @override
  List<Object> get props => null;
}

class SexFailState extends SexblocState {
  final String message;
  SexFailState(this.message);
  @override
  List<Object> get props => null;
}

性别事件

abstract class SexblocEvent extends Equatable {
  const SexblocEvent();
}

class SexButtonPressed extends SexblocEvent {
  final String sex;
  SexButtonPressed({this.sex});
  @override
  List<Object> get props => null;
}
class FeMaleSexButtonPressed extends SexblocEvent {
  final String sex;
  FeMaleSexButtonPressed({this.sex});
  @override
  List<Object> get props => null;
}

我正在为此尝试使用单击事件选择性别的 Bloc 模式,选择后它将通过状态更改其颜色,但是当我使用单击它时我的视图出现问题,它不会更改颜色 n 不刷新它。请帮助我,因为我对这个集团模式不是很熟悉。

【问题讨论】:

    标签: flutter dart flutter-bloc


    【解决方案1】:

    使您的 SelectGenderPage 成为 StatefulWidget 并调用 setState

    class SelectGenderPage extends StatefulWidget {
      final UserRepository userRepository;
      const SelectGenderPage({@required this.userRepository});
      @override
      _SelectGenderPageState createState() => _SelectGenderPageState();
    }
    
    class _SelectGenderPageState extends State<SelectGenderPage> {
      bool _isSelecte = false;
      bool _isSelecteds = true;
    
      @override
      Widget build(BuildContext context) {
        return BlocListener<SexblocBloc, SexblocState>(listener: (context, state) {
          if (state is SexLoadingState) {
            pr.hide();
          } else if (state is SexblocInitial) {
            setState(() {
              _isSelecte = false;
              _isSelecteds = true;
            });
            pr.hide();
          }
        });
      }
    }
    

    【讨论】:

    • 我知道有状态的 setState 但我通过使用无状态小部件询问你是否可以帮助解决这个问题。
    【解决方案2】:

    今天遇到同样的问题,我发现原因是get props对于bloc决定状态是否改变很重要,所以将你的属性添加到返回数组中。

    @override
    List<Object> get props => [select];
    

    【讨论】:

      猜你喜欢
      • 2021-03-19
      • 2020-10-10
      • 2021-03-04
      • 2019-12-28
      • 2020-02-27
      • 2020-08-03
      • 2020-09-16
      • 2022-08-11
      • 2019-08-04
      相关资源
      最近更新 更多