Как обрабатывать одно состояние виджета из другого состояния виджета? - PullRequest
0 голосов
/ 30 октября 2019

Я делаю флаттер приложение, в котором есть корзина. Сейчас я просто работаю над одной его функциональностью, когда мы выбираем конкретный продукт, после увеличения или уменьшения его количества наша корзина не сразу показывает количество этого товара в корзине. мы должны перейти к другому виджету, а затем обновить счетчик в корзине. Примечание. HomeScreen состоит из двух виджетов с состоянием, один из которых является нижней панелью навигации, на которой есть корзина и другие значки, а также другие значки и соответствующие им пользовательские интерфейсы, а другой - экран «Продукт», на котором отображаются все наши продукты, а на экране моего продукта я использовал просмотр списка ив его интерфейсе я использовал значки - и +, чтобы увеличить или уменьшить его количество. Я делюсь кодом виджета - и + (небольшая часть экрана продукта), на котором я хочу реализовать эту функцию. Это ссылка на видео для показа https://youtu.be/3qqVpmWguys

HomeScreen:

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  //static _HomeScreenState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<_HomeScreenState>());
  int _currentindex = 0;
  var cart;

  final List<Widget> children = [
    ProductScreen(),
    OrderScreen(),
    CartScreen(),
    AccountScreen(),
  ];

  List<BottomNavigationBarItem> _buildNavigationItems() {
    var bloc = Provider.of<CartManager>(context);
    int totalCount = bloc.getCart().length;
    setState(() {
      totalCount;
    });

    return <BottomNavigationBarItem>[
      BottomNavigationBarItem(
        icon: Icon(
          Icons.reorder,
          size: 30,
          color: Colors.white,
        ),
        title: Text(
          'Product',
          style: TextStyle(fontSize: 15, color: Colors.white),
        ),
      ),
      BottomNavigationBarItem(
        icon: Icon(
          Icons.add_alert,
          size: 30,
          color: Colors.white,
        ),
        title: Text(
          'Order',
          style: TextStyle(fontSize: 15, color: Colors.white),
        ),
      ),
      BottomNavigationBarItem(
        icon: Stack(
          children: <Widget>[
            Icon(
              Icons.shopping_cart,
              size: 30,
              color: Colors.white,
            ),
            Positioned(
              bottom: 12.0,
              right: 0.0,

              child: Container(
                constraints: BoxConstraints(
                  minWidth: 20.0,
                  minHeight: 20.0,
                ),
                decoration: BoxDecoration(
                  color: Colors.red,
                  borderRadius: BorderRadius.circular(10.0),
                ),
                child: Center(
                  child: Text(
                    '$totalCount',
                    style: TextStyle(
                      fontSize: 12,
                      color: Colors.white,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
        title: Text(
          'Cart',
          style: TextStyle(fontSize: 15, color: Colors.white),
        ),
      ),
      BottomNavigationBarItem(
        icon: Icon(
          Icons.lock,
          size: 30,
          color: Colors.white,
        ),
        title: Text(
          'Account',
          style: TextStyle(fontSize: 15, color: Colors.white),
        ),
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {

    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.white,
        resizeToAvoidBottomPadding: true,
        body: children[_currentindex],
        bottomNavigationBar: BottomNavigationBar(
          fixedColor: Colors.transparent,
          backgroundColor: Colors.orange,
          onTap: onNavigationTapbar,
          currentIndex: _currentindex,
          items: _buildNavigationItems(),
          type: BottomNavigationBarType.fixed,
        ),
      ),
    );
  }

  void onNavigationTapbar(int index) {
    setState(() {
      _currentindex = index;
    });
  }
}

Инкремент или декремент ProductScreen:

class TEProductIncrementor extends StatefulWidget {
  var product;
  TEProductIncrementor({
    this.product,
  });

  @override
  _TEProductIncrementorState createState() => new _TEProductIncrementorState();
}

class _TEProductIncrementorState extends State<TEProductIncrementor> {
  int totalCount = 0;
  @override
  Widget build(BuildContext context) {
    var cartmanager = CartManager();
    void decrementsavecallback() {
 //     bloc.decreaseToCart(widget.ctlist);
//CartManager().updateToCart(totalCount.toString(), widget.ctlist);
      setState(() {
        if (totalCount > 0) {
          totalCount--;
          cartmanager.updateToCart(totalCount.toString(),widget.product);
        }
      });
    }

    void increasesavecallback() {
      setState(() {
          totalCount++;
          cartmanager.updateToCart(totalCount.toString(),widget.product);
      });
    }


      return Container(
          margin: EdgeInsets.only(top: 8),
          decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(10), color: Colors.orange),
          child: Container(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                IconButton(
                  iconSize: 30,
                  icon: new Icon(
                    Icons.remove,
                  ),
                  onPressed: () {
                  decrementsavecallback();
                  },
                ),
                Text(
                  totalCount.toString(),
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
                IconButton(
                  iconSize: 30,
                  icon: new Icon(Icons.add),
                  onPressed: () {
                    increasesavecallback();
                  },
                )
              ],
            ),
          ),
        );
  }
}

Ответы [ 3 ]

0 голосов
/ 30 октября 2019

Вы можете передать всю функцию в только что реализованный виджет, как показано ниже

class Parent extends StatefulWidget {
  @override
  _ParentState createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  @override
  Widget build(BuildContext context) {
    return Button(
        (){
          setState(() {
            ///define your logic here
          });
        }
    );
  }
}

class Button extends StatelessWidget {
  final Function onTap;
  Button(this.onTap);
  @override
  Widget build(BuildContext context) {
    return FlatButton(
      onPressed: onTap,
    );
  }
}

Но если ваш проект довольно большой, я порекомендую вам использовать любые библиотеки управления состоянием, такие как redux или mobx.

https://pub.dev/packages/mobx

0 голосов
/ 30 октября 2019

Почему бы не использовать ключи? Назначьте для обоих виджетов GlobalKey, а затем, когда вам нужно обновить это состояние, вам просто нужно позвонить

yourGlobalKeyName.currentState.setState((){
  //your code
});
0 голосов
/ 30 октября 2019

Для этого вы можете использовать шаблон BLoC,

Здесь - это полный ответ и демонстрационный код, который вы можете проверить.

...