首页 > 解决方案 > 如何使用flutter_bloc在不改变Flutter状态的情况下将一个页面导航到另一个页面

问题描述

我面临一个问题,当我使用flitter BLoC从一页转到另一页时,我的第一页在到达第二页之前重建。我可以在BlocBuilder中使用buildWhen来限制页面的重建,但问题是当我通过后按再次返回第一页时,页面无法显示以前的状态小部件。我不知道如何在不重新重建页面的情况下管理页面之间的导航,我使用的是flutter_bloc 6.1.1下面是我的代码。

第一页

class FirstPage extends StatefulWidget {
final MyData dataObj;

FirstPage({this.dataObj});

@override
_MyFirstPageState createState() => _MyFirstPageState();
}

class _MyFirstPageState extends State<FirstPage> {

FirstPageBloc _bloc = FirstPageBloc();
String _userAddress='';

@override
void initState() {
super.initState();
_bloc.add(UserInfoEvent(dataObj:widget.dataObj));
}

@override
Widget build(BuildContext context) {
return Scaffold(
    resizeToAvoidBottomPadding: false,
    appBar: AppBar(
      title: Text(StringConstants.APP_TITLE_HEADING),
    ),
    body: BlocListener<FirstPageBloc, FirstPageState>(
      cubit: _bloc,
      listenWhen: (previousState, state) {
        // return true/false to determine whether or not
        // to call listener with state

        return true;
      },
      listener: (context, state) async{
        if (state is LoadingState) {
          print('Loading ...');
        }
        if (state is DataInfoState) {
          _userAddress=state.userAddress;
        }
        if(state is ConfirmationState){
          Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage(dataObj: widget.dataObj)));
        }

      },
      child: BlocBuilder<FirstPageBloc, FirstPageState>(
          //bloc: _bloc,
          cubit: _bloc,
          buildWhen: (previousState, state) {
            // return true/false to determine whether or not
            // to rebuild the widget with state
            if(state is ConfirmationState){
              return false;
            }
            return true;
          },
          builder: (context, state) {
            if (state is LoadingState) {
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    CircularProgressIndicator(valueColor:
                    AlwaysStoppedAnimation<Color>(ColorConstants.Primary),),
                    Text(StringConstants.PLEASE_WAIT)
                  ],),
              );
            }
            return _mainWidget();
          }),
     ),
  );
 }
}

集团

 class FirstPageBloc extends Bloc<FirstPageEvent, FirstPageState>{

 FirstPageBloc() : super(InitialState());

 @override
 Stream<FirstPageState> mapEventToState(FirstPageEvent event) async*{

// TODO: implement mapEventToState
if(event is DataInfoEvent){
  yield* _getUserData(event.dataObj);
}
if(event is ConfirmationEvent){
  yield* _confirmTaskData(event.dataObj);
 }
}
 Stream<DelConfirmState> _confirmTaskData(MyData dataObj) async* {
  yield LoadingState();

  //Performing some SQLite DB operations

  yield ConfirmationState();

}
Stream<DelConfirmState> _getUserData(MyData dataObj) async* {

  yield LoadingState();
  String userAddress='ABDC001, PIN- 0091910, 5th Main USA';
  //Fetching User data from SQLite database and passing to UI

  yield DataInfoState(userAddress:userAddress);
 }
}

状态

  abstract class FirstPageState extends Equatable {}

 ///This is our initial state
 class InitialState extends FirstPageState {
 @override
 List<Object> get props => null;
 }

 //This state will call for loading the progress var
class LoadingState extends FirstPageState {
@override
List<Object> get props => [];
}

//This state will call for loading the progress var
class ErrorState extends FirstPageState {
final String errorMessage;

ErrorState({@required this.errorMessage});
@override
List<Object> get props => [];
}

//This state will retun the userdata
class DataInfoState extends FirstPageState {
final String userAddress;

DataInfoState({@required this.userAddress});

@override
// TODO: implement props
List<Object> get props => [];
}
class TaskConfirmationState extends FirstPageState {

ConfirmationState({});

@override
// TODO: implement props
List<Object> get props => [];
}

事件

   abstract class FirstPageEvent extends Equatable {}

   class GetUserInfoEvent extends FirstPageEvent {
   final MyData dataObj;

   GetUserInfoEvent({this.taskObj});
   @override
   List<Object> get props => [];
  }
  class ConfirmationEvent extends FirstPageEvent {
  final MyData dataObj
  ConfirmationEvent({this.dataObj});
  @override
  List<Object> get props => [];
 }

请指教 谢谢

标签: flutterflutter-blocflutter-android

解决方案


您需要在更高级别的小部件上提供您的 bloc,然后您需要从上下文中获取它。这样,即使通过导航,状态也会持续存在。你可以像这样包装你的小部件:

BlocProvider(
      create: (context) => FirstPageBloc(),
      child: FirstPage(),
    )

然后在 initState 里面你可以像这样得到它:

_bloc = BlocProvider.of<FirstPageBloc>(context);

推荐阅读