切换按钮



我正在尝试使用Flutter提供的Bloc模式实现ToggleButton。代码很简单,但是有一个问题。当我尝试更新我的索引以便它可以从Bloc中发出以改变我的bool值时,整个事情将什么也不做。我已经尝试重写代码来寻找问题,但我的猜测是更新不会通过。有人知道怎么解决这个问题吗?

这是我的分组:

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
part 'calculate_event.dart';
part 'calculate_state.dart';
class CalculateBloc extends Bloc<CalculateEvent, CalculateState> {
///Constructor
CalculateBloc()
: super(CalculateInitial(
selection: List.filled(3, false),
totalAmount: '',
textEditingController: TextEditingController())) {
///On-Method to emit the State
on<CalculateEvent>((event, emit) {
///UpdateSelectionEvent
if (event is UpdateSelectionEvent) {
///emit the Index of the button-press
final updateSelect = List.of(state.selection);
for (int i = 0; i < updateSelect.length; i++) {
updateSelect[i] = event.selectIndex == i;
}
emit(UpdateSelectionState(
selection: updateSelect,
totalAmount: state.TotalAmount,
tip: state.tip,
textEditingController: state.textEditingController));
}
///CalculatePercentageEvent
if (event is CalculatePercentageEvent) {
final controller = state.textEditingController;
final totalAmount = double.parse(controller.text);
final selectedIndex = state.selection.indexWhere((element) => element);
final tipPercentage = [0.1, 0.15, 0.2][selectedIndex];
final tipTotal = (totalAmount * tipPercentage).toStringAsFixed(2);
emit(CalculatePercentageState(
selection: state.selection,
totalAmount: totalAmount.toString(),
tip: tipTotal,
textEditingController: state.textEditingController));
}
});
}
}

这是我的State-class:

part of 'calculate_bloc.dart';
@immutable
abstract class CalculateState extends Equatable {
final List<bool> selection;
final String? tip;
final String TotalAmount;
final TextEditingController textEditingController;
CalculateState(
{this.tip = '',
required this.TotalAmount,
required this.selection,
required this.textEditingController});
@override
List<Object?> get props => [selection, tip, TotalAmount];
}
class CalculateInitial extends CalculateState {
CalculateInitial(
{required List<bool> selection,
String? tip = '',
required String totalAmount,
required TextEditingController textEditingController})
: super(
selection: selection,
TotalAmount: totalAmount,
textEditingController: textEditingController);
}
class CalculatePercentageState extends CalculateState {
CalculatePercentageState(
{required List<bool> selection,
String? tip = '',
required String totalAmount,
required TextEditingController textEditingController})
: super(
selection: selection,
TotalAmount: totalAmount,
tip: tip,
textEditingController: textEditingController);
}
class UpdateSelectionState extends CalculateState {
UpdateSelectionState(
{required List<bool> selection,
String? tip = '',
required String totalAmount,
required TextEditingController textEditingController})
: super(
selection: selection,
TotalAmount: totalAmount,
tip: tip,
textEditingController: textEditingController);
}

下面是我的Event-class:

part of 'calculate_bloc.dart';
@immutable
abstract class CalculateEvent {}
class CalculatePercentageEvent extends CalculateEvent {}
class UpdateSelectionEvent extends CalculateEvent {
final int selectIndex;
UpdateSelectionEvent(this.selectIndex);
}

和我的UI:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_day_1/bloc/calculate_bloc.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CalculateBloc(),
child: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BlocBuilder<CalculateBloc, CalculateState>(
bloc: BlocProvider.of<CalculateBloc>(context),
builder: (context, state) {
if (state.tip != null) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(20),
child: Text(state.tip ?? '',
style: const TextStyle(fontSize: 30)),
),
const Text('Total Amount'),
SizedBox(
width: 80,
child: TextField(
controller: state.textEditingController,
keyboardType:
const TextInputType.numberWithOptions(),
textAlign: TextAlign.center,
decoration:
const InputDecoration(hintText: '$100.00'),
),
),
Padding(
padding: const EdgeInsets.all(20),
child: ToggleButtons(
onPressed: (index) =>
BlocProvider.of<CalculateBloc>(context)
.add(UpdateSelectionEvent(index)),
isSelected: state.selection,
children: const [
Text('10%'),
Text('15%'),
Text('20%'),
],
),
),
],
);
} else {
return Container(
child: const Text('flase'),
);
}
}),
ElevatedButton(
onPressed: () {
BlocProvider.of<CalculateBloc>(context)
.add(CalculatePercentageEvent());
},
child: const Text('Calculate Amount'),
),
],
),
),
),
);
}
}

我试图利用一些BlocListener,但它不会工作。我的另一个猜测是使用额外的状态来发射它。

我发现问题了。在主页上,BlocProvider继续使用CalculateInitialState来构建应用程序,这样新值就不会被传递。

最新更新