#flutter #dart #bloc #flutter-bloc
Вопрос:
Пожалуйста, помогите. Я новичок в flutter_bloc и в настоящее время в замешательстве. Я хочу рассчитать общую цену заказанного продукта. Проблема, с которой я в настоящее время сталкиваюсь, состоит из двух ситуаций
- Я сделал свой quantity_bloc(для кнопки «Количество») в качестве локального блока, так как я хочу отображать состояние по-разному в соответствии со списком заказов.
- Я хочу рассчитать цену с количеством, но цена-это данные, полученные из локального 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(я не знаю, возможно ли это).