Flutter Bloc:更新状态不会刷新由Bloc管理的视图

时间:2020-07-31 16:59:21

标签: flutter dart flutter-bloc

gender_page

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),
                  ),
                ),
              ],
            ),
          )),
    );
  }
}

gender_bloc

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),
    );
  }

}

gender_state

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不刷新它。请帮助我,因为我对这种集团模式不太熟悉。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

将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();
      }
    });
  }
}