Как осуществлять связь между блоками? flutter_bloc

#flutter #dart #bloc #flutter-bloc

Вопрос:

Пожалуйста, помогите. Я новичок в flutter_bloc и в настоящее время в замешательстве. Я хочу рассчитать общую цену заказанного продукта. Проблема, с которой я в настоящее время сталкиваюсь, состоит из двух ситуаций

  1. Я сделал свой quantity_bloc(для кнопки «Количество») в качестве локального блока, так как я хочу отображать состояние по-разному в соответствии со списком заказов.
  2. Я хочу рассчитать цену с количеством, но цена-это данные, полученные из локального json, и я не знаю, как передать их в total_bloc(или, может быть, не нужно передавать их).

вот мой скриншот пользовательского интерфейса

вот мой код для экрана:

 import ...

class ProfileScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return _ProfileScreen();
  }
}

class _ProfileScreen extends StatefulWidget {
  const _ProfileScreen({Key? key}) : super(key: key);

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

class _ProfileScreenState extends State<_ProfileScreen> {
  var top = 0.0;
  List<Order> orders = [];

  Future<void> readOrderJson() async {
    final String response =
        await rootBundle.loadString('lib/assets/data/order.json');
    final orderData = await json.decode(response);

    var list = orderData["service"] as List<dynamic>;

    setState(() {
      orders = list.map((e) => Order.fromJson(e)).toList();
    });
  }

  bool isFilled = true;
  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;
    return Scaffold(
      backgroundColor: Colors.black,
      body: Column(
        children: [
          Expanded(
            child: NestedScrollView(
              headerSliverBuilder:
                  (BuildContext context, bool innerBoxIsScrolled) {
                return <Widget>[
                  SliverAppBar(
                    floating: false,
                    pinned: true,
                    snap: false,
                    expandedHeight: height * 30 / 100,
                    leading: Container(
                      margin: EdgeInsets.all(10),
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(50),
                          color: HexColor('#06090b')),
                      child: Icon(
                        CupertinoIcons.left_chevron,
                        size: 15,
                      ),
                    ),
                    actions: [
                      Container(
                        margin: EdgeInsets.all(8),
                        padding: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(50),
                            color: HexColor('#06090b')),
                        child: Icon(
                          Icons.more_horiz,
                          size: 20,
                        ),
                      )
                    ],
                    flexibleSpace: LayoutBuilder(
                      builder:
                          (BuildContext context, BoxConstraints constraints) {
                        top = constraints.biggest.height;
                        return FlexibleSpaceBar(
                          collapseMode: CollapseMode.pin,
                          centerTitle: true,
                          title: AnimatedOpacity(
                              duration: Duration(milliseconds: 100),
                              opacity: top ==
                                      MediaQuery.of(context).padding.top  
                                          kToolbarHeight
                                  ? 1.0
                                  : 0.0,
                              // opacity: 1.0,
                              child: Text(
                                'User',
                              )),
                          
                        );
                      },
                    ),
                  ),
                ];
              },
              body: Column(
                children: [
                  Center(
                    child: Container(
                      child: GestureDetector(
                        onTap: readOrderJson,
                        child: Text(
                          'Fetch Data',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                  ),
                  Expanded(
                    child: ListView.builder(
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      itemCount: orders.length,
                      itemBuilder: (BuildContext context, index) {
                        return Column(
                          children: [
                            Container(
                              margin: EdgeInsets.symmetric(
                                  horizontal: 15, vertical: 5),
                              decoration: BoxDecoration(
                                border: Border(
                                  bottom: BorderSide(
                                    width: 1,
                                    color: HexColor('#232323'),
                                  ),
                                ),
                              ),
                              child: BlocProvider(
                                create: (_) => CheckBoxBloc(),
                                child: BlocBuilder<CheckBoxBloc, bool>(
                                  builder: (context, state) {
                                    return Column(
                                      children: [
                                        SizedBox(
                                          height: 10,
                                        ),
                                        Row(
                                          crossAxisAlignment:
                                              CrossAxisAlignment.start,
                                          children: [
                                            Container(
                                              margin: EdgeInsets.only(
                                                  right: width * 5 / 100),
                                              width: width * 5 / 100,
                                              height: height * 3 / 100,
                                              child: Transform.scale(
                                                scale: 1.25,
                                                child: Checkbox(
                                                  activeColor:
                                                      HexColor('#00e0d2'),
                                                  checkColor:
                                                      HexColor('#0a0a0a'),
                                                  value: state,
                                                  onChanged: (value) {
                                                    context
                                                        .read<CheckBoxBloc>()
                                                        .add(CheckBoxEvent
                                                            .toggled);
                                                  },
                                                ),
                                              ),
                                            ),
                                            OrderItem(
                                              spaceOne: 5,
                                              spaceTwo: 15,
                                              title: orders[index].title,
                                              desc: orders[index].desc,
                                              price: " ${orders[index].price}",
                                              isFilled: isFilled,
                                            ),
                                          ],
                                        ),
                                        Visibility(
                                          visible: context.watch<CheckBoxBloc>().state,
                                          child: BlocProvider(
                                            create: (_) => QtyBloc(),
                                            child: BlocBuilder<QtyBloc, int>(
                                              builder: (context, state) {
                                                return Row(
                                                  children: [
                                                    Text('${context.watch<QtyBloc>().qty}', style: TextStyle(color: Colors.blue),),
                                                    Text(
                                                      '${state * orders[index].price}',
                                                      style: TextStyle(
                                                          color: Colors.red),
                                                    ),
                                                    SizedBox(
                                                      width: width * 10 / 100,
                                                    ),
                                                    AddQty(
                                                      buttoncolor: '#dcfff4',
                                                      result: state,
                                                      incrementFunction: () {
                                                        context
                                                            .read<QtyBloc>()
                                                            .add(QtyEvent
                                                                .increment);
                                                      },
                                                      decrementFunction: () {
                                                        context
                                                            .read<QtyBloc>()
                                                            .add(QtyEvent
                                                                .decrement);
                                                      },
                                                    ),
                                                  ],
                                                );
                                              },
                                            ),
                                          ),
                                        )
                                      ],
                                    );
                                  },
                                ),
                              ),
                            ),
                          ],
                        );
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
          Container(
            padding: EdgeInsets.all(10),
            decoration: BoxDecoration(
                border: Border(
                    top: BorderSide(width: 1, color: HexColor('#4a4a4a')))),
            child: Center(
              child: Container(
                padding: EdgeInsets.all(10),
                width: width * 60 / 100,
                decoration: BoxDecoration(
                    color: HexColor('#6824f8'),
                    borderRadius: BorderRadius.circular(5)),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(
                      'Book',
                      style: TextStyle(
                          color: HexColor('#f8f8f8'),
                          fontWeight: FontWeight.bold,
                          fontSize: 15),
                    ),
                    SizedBox(
                      width: 5,
                    ),
                    Text(
                      '${context.watch<QtyBloc>().state}',
                      style: TextStyle(
                          color: HexColor('#f8f8f8'),
                          fontWeight: FontWeight.bold,
                          fontSize: 15),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

 

код для qty_bloc:

 import 'dart:async';

import 'package:flutter_bloc/flutter_bloc.dart';

enum QtyEvent { increment, decrement, init }

class QtyBloc extends Bloc<QtyEvent, int> {
  int qty = 1;
  QtyBloc() : super(1);

  @override
  Stream<int> mapEventToState(QtyEvent event) async* {
      if (event == QtyEvent.increment) {
      yield state   1;
      qty = state;
    } else if (event == QtyEvent.decrement) {
      yield state - 1;
      qty = state;
    } else if (event == QtyEvent.init) {
      yield 1;
      qty = 1;
    }
  }
  @override
  Future<void> close() {
    return super.close();
  }
}
 

Мне удалось рассчитать общую цену заказа * количество(красный текст слева), и мне также удалось изменить количество не только состояние, но и переменную количества в quantity_bloc, потому что у меня есть идея просто рассчитать общую цену в listview и передать ее в quantity_bloc, а затем установить связь между блоком количества и общим блоком. или моя вторая идея состояла в том, чтобы рассчитать ее внутри поставщика qty_bloc в listview и передать ее в total(я не знаю, возможно ли это).