InheritedWidget - метод get был вызван в значение null после navigator.push - PullRequest
0 голосов
/ 10 сентября 2018

У меня возникают проблемы при попытке получить доступ к InheritedWidget после перехода к новому виджету.

У меня есть виджет верхнего уровня, подобный этому

class App extends StatelessWidget{
  build(context){
    return MaterialApp(
        title: 'Iniciar Sesion',
        home: LoginBlocProvider(child: WelcomeScreen()),
    );
  }  
}

Затем WelcomeScreen имеет кнопку для навигациина LoginScreen

class WelcomeScreen extends StatelessWidget {

  @override Widget build(BuildContext context){
    return Scaffold(
      body: Center(child: MyButton)
    );
  }
}

class MyButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      shape: StadiumBorder(),
      child: Text('Ingresar', style: TextStyle(color: Colors.black)),
      elevation: 5.0,
      onPressed: () { 
        Navigator.of(context).push(MaterialPageRoute(
           builder: (BuildContext context) =>LoginScreen()
        ));
      }
    );
  }
}

Наконец на LoginScreen я хочу получить доступ к InheritedWidget

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  LoginBloc bloc;  

  @override void didChangeDependencies() {
    bloc = LoginBlocProvider.of(context);
    super.didChangeDependencies();
  }

  @override Widget build(BuildContext context){
    return Scaffold(
      body:
      Stack(
        fit: StackFit.expand,
        children: <Widget>[
          Positioned(
            top: 0.0,
            child: Image.asset('assets/images/img.jpg',
              fit: BoxFit.none,
            ),
          ),
          _buildLogin(),
        ],
      ),
    );
  }
}

Отредактировано: Здесь это LoginBlocProvider

class LoginBlocProvider extends InheritedWidget {
  final bloc;

  LoginBlocProvider({Key key, Widget child}) 
  : bloc = LoginBloc(), 
  super(key:key, child:child);

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;

  static LoginBloc of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(LoginBlocProvider) as LoginBlocProvider).bloc;
  }
}

Но когда я запускаю метод .of InheritedWidget, я получаю эту ошибку

I/flutter (27725): The following NoSuchMethodError was thrown building Builder:
I/flutter (27725): The getter 'bloc' was called on null.
I/flutter (27725): Receiver: null
I/flutter (27725): Tried calling: bloc

У меня создается впечатление, что все это связано с контекстом в методе построителя Navigator.push.Потому что, если я использую виджет LoginScreen без Navigator.push, я могу отлично использовать InheritedWidget

Ошибка возникает из-за того, что контекст, переданный методу LoginBlocProvider.of(), не находит экземпляр.

Есть мысли по этому поводу?

1 Ответ

0 голосов
/ 11 сентября 2018

В предоставленном вами коде LoginScreen не является потомком LoginBlocProvider, поэтому не может найти виджет предка. Ваш код оборачивает маршрут WelcomeScreen в LoginBlocProvider, но не весь навигатор. Решение состоит в том, чтобы обернуть ваш MaterialApp в LoginBlocProvider, и тогда у вас будет доступ к нему везде в вашем приложении.

class App extends StatelessWidget {
  @override
  Widget build(context) {
    return LoginBlocProvider(
      child: MaterialApp(
        title: 'Iniciar Sesion',
        home: WelcomeScreen(),
      ),
    );
  }
}
...