无法在提供者的容器外部设置状态

问题描述 投票:0回答:1

我知道问题出在我的生命周期中,我试图在呈现Widget之前在Provider中设置状态,但是我在哪里可以做到这一点。仅在容器小部件中?但是除非有按钮或其他东西,否则我无法这样做。

希望您能在这里解决问题。

我将不胜感激!

我的错误:

setState() or markNeedsBuild() called during build.

The setter 'lastPage=' was called on null.
Receiver: null
Tried calling: lastPage=true

如果我在这里设置状态

  _detectLastPage() {
    int currentPage = this.currentStep == null ? 1 : this.currentStep + 1;

    if (currentPage == 1 && this.currentStep == null) {
      this._onFirstPage();
    } else if (currentPage == this.totalSteps) {
      this.lastPage = true;
      _welcomeBloc.lastPage = true;
      this._onLastPage();
    } else {
      this.lastPage = false;
      _welcomeBloc.lastPage = true;
    }
  }

我的小部件:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:ui_flutter/screens/welcome/welcome_bloc.dart';

class Footer extends StatelessWidget {
  final int currentStep;
  final int totalSteps;
  final Color activeColor;
  final Color inactiveColor;
  final Duration duration;
  final Function onFinal;
  final Function onStart;

  final double radius = 10.0;
  final double distance = 4.0;

  Container stepper;
  Container nextArrow;
  bool lastPage;
  WelcomeBloc _welcomeBloc;

  Footer({
    this.activeColor,
    this.inactiveColor,
    this.currentStep,
    this.totalSteps,
    this.duration,
    this.onFinal,
    this.onStart,
  }) {
    this._detectLastPage();
    this._makeStepper();
    this._makeNextArrow();
  }

  @override
  Widget build(BuildContext context) {
    print('footer is launching');

    final WelcomeBloc _welcome = Provider.of<WelcomeBloc>(context);
    _welcomeBloc = _welcome;
    // this._welcomeBloc.lastPage = true; // I'd like to set the state here

    return Container(
      alignment: Alignment.bottomCenter,
      padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 30.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          this.stepper,
          this.nextArrow,
          RaisedButton(
            child: Text('kdfljds'),
            onPressed: () {
              print(_welcomeBloc.lastPage);
              _welcomeBloc.lastPage = true; // I can access from here BUT CANNOT access outside this container
            },
          )
        ],
      ),
    );
  }

  _makeCirle(activeColor, inactiveColor, position, currentStep) {
    currentStep = currentStep ?? 0;
    Color color = (position == currentStep) ? activeColor : inactiveColor;

    return Container(
      height: this.radius,
      width: this.radius,
      margin: EdgeInsets.only(left: this.distance, right: this.distance),
      decoration: BoxDecoration(
          color: color,
          border: Border.all(color: activeColor, width: 2.0),
          borderRadius: BorderRadius.circular(50.0)),
    );
  }

  _makeStepper() {
    List<Container> circles = List();

    for (var i = 0; i < totalSteps; i++) {
      circles.add(
        _makeCirle(this.activeColor, this.inactiveColor, i, this.currentStep),
      );
    }

    this.stepper = Container(
      child: Row(
        children: circles,
      ),
    );
  }

  _makeNextArrow() {
    this.nextArrow = Container(
      child: Padding(
        padding: const EdgeInsets.only(right: 8.0),
        child: GestureDetector(
            onTap: () {
              _welcomeBloc.controller.nextPage(
                duration: this.duration ?? Duration(milliseconds: 500),
                curve: Curves.easeInOut,
              );
            },
            child: Icon(
              Icons.arrow_forward,
            )),
      ),
    );
  }

  _onLastPage() {
    if (this.onFinal != null) {
      this.onFinal();
    }
  }

  _onFirstPage() {
    if (this.onStart != null) {
      this.onStart();
    }
  }

  _detectLastPage() {
    int currentPage = this.currentStep == null ? 1 : this.currentStep + 1;

    if (currentPage == 1 && this.currentStep == null) {
      this._onFirstPage();
    } else if (currentPage == this.totalSteps) {
      this.lastPage = true;
      this._onLastPage();
    } else {
      this.lastPage = false;
    }
  }
}


flutter flutter-dependencies provider
1个回答
0
投票

您无法在setState中使用StatelessWidget方法。将其转换为StatefulWidget,然后在setState方法中调用initState

喜欢这个

class Footer extends StatefulWidget {
  final int currentStep;
  final int totalSteps;
  final Color activeColor;
  final Color inactiveColor;
  final Duration duration;
  final Function onFinal;
  final Function onStart;

  Footer({
    this.activeColor,
    this.inactiveColor,
    this.currentStep,
    this.totalSteps,
    this.duration,
    this.onFinal,
    this.onStart,
  });

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


class _FooterState extends State<Footer> {


  final double radius = 10.0;
  final double distance = 4.0;

  Container stepper;
  Container nextArrow;
  bool lastPage;
  WelcomeBloc _welcomeBloc;

  @override
  void initState(){
    this._detectLastPage();
    this._makeStepper();
    this._makeNextArrow();
    final WelcomeBloc _welcome = Provider.of<WelcomeBloc>(context);
    _welcomeBloc = _welcome;
    setState((){
     this._welcomeBloc.lastPage = true; // Where to use setState
    });
  }

  @override
  Widget build(BuildContext context) {
    print('footer is launching');


    return Container(
      alignment: Alignment.bottomCenter,
      padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 30.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          this.stepper,
          this.nextArrow,
          RaisedButton(
            child: Text('kdfljds'),
            onPressed: () {
              print(_welcomeBloc.lastPage);
              _welcomeBloc.lastPage = true; // I can access from here BUT CANNOT access outside this container
            },
          )
        ],
      ),
    );
  }

  _makeCirle(activeColor, inactiveColor, position, currentStep) {
    currentStep = currentStep ?? 0;
    Color color = (position == currentStep) ? activeColor : inactiveColor;

    return Container(
      height: this.radius,
      width: this.radius,
      margin: EdgeInsets.only(left: this.distance, right: this.distance),
      decoration: BoxDecoration(
          color: color,
          border: Border.all(color: activeColor, width: 2.0),
          borderRadius: BorderRadius.circular(50.0)),
    );
  }

  _makeStepper() {
    List<Container> circles = List();

    for (var i = 0; i < totalSteps; i++) {
      circles.add(
        _makeCirle(this.activeColor, this.inactiveColor, i, this.currentStep),
      );
    }

    this.stepper = Container(
      child: Row(
        children: circles,
      ),
    );
  }

  _makeNextArrow() {
    this.nextArrow = Container(
      child: Padding(
        padding: const EdgeInsets.only(right: 8.0),
        child: GestureDetector(
            onTap: () {
              _welcomeBloc.controller.nextPage(
                duration: this.duration ?? Duration(milliseconds: 500),
                curve: Curves.easeInOut,
              );
            },
            child: Icon(
              Icons.arrow_forward,
            )),
      ),
    );
  }

  _onLastPage() {
    if (this.onFinal != null) {
      this.onFinal();
    }
  }

  _onFirstPage() {
    if (this.onStart != null) {
      this.onStart();
    }
  }

  _detectLastPage() {
    int currentPage = this.currentStep == null ? 1 : this.currentStep + 1;

    if (currentPage == 1 && this.currentStep == null) {
      this._onFirstPage();
    } else if (currentPage == this.totalSteps) {
      this.lastPage = true;
      this._onLastPage();
    } else {
      this.lastPage = false;
    }
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.