I'm using cubit to manage state of widgets, and I want to make widget updated only when specific type of state is emitted.
part of 'TestData.dart';
@immutable
abstract class TestState {}
class TestInitial extends TestState {}
class TestValueUpdated extends TestState {
TestValueUpdated(this.message);
final String message;
@override
bool operator ==(Object other) {
return other is TestValueUpdated && other.message == message;
}
@override
int get hashCode => message.hashCode;
}
class TestScaleUpdated extends TestState {
TestScaleUpdated(this.message);
final String message;
@override
bool operator ==(Object other) {
return other is TestScaleUpdated && other.message == message;
}
@override
int get hashCode => message.hashCode;
}
I created state class called TestState
, and this class currently having 3 states : initial, value updated, scale updated
class TestData extends Cubit<TestState> {
//Codes here
Future<void> keepPlayStatus() async {
emit(TestValueUpdated(getTimeStamp()+" / "+getMaxTime()+" | "+getPosition()));
}
Future<void> updateScaleValueMessage() async {
emit(TestScaleUpdated((size * 100).round().toInt().toString() + " %"));
}
}
and this class called TestData
uses TestState
and extends Cubit
.
Basically, when user updates zoom value by pinching the screen, this class will emit TestScaleUpdated
state, and when user plays something, it will emit TestValueUpdated
state.
and in UI,
//somewhere of the codes, called widget A
child: BlocBuilder<TestData, TestState>(
builder: (context, state) {
if(state is TestValueUpdated) {
return Text(
state.message,
textAlign: TextAlign.end,
style: TextStyle(color: ThemeManager.getRGBfromHex(0x514745)),
);
} else {
return Text(
"00:00.000 / 00:04.800 | 1.1.1",
textAlign: TextAlign.end,
style: TextStyle(color: ThemeManager.getRGBfromHex(0x514745)),
);
}
},
)
//the other part of the codes, called widget B
child: BlocBuilder<TestData, TestState>(
builder: (context, state) {
if(state is TestScaleUpdated) {
return Text(
state.message,
textAlign: TextAlign.center,
style: TextStyle(color: ThemeManager.getRGBfromHex(0x514745)) ,
);
} else {
return Text(
"100 %",
textAlign: TextAlign.center,
style: TextStyle(color: ThemeManager.getRGBfromHex(0x514745)) ,
);
}
},
)
I tried this code. These 2 widgets update their status when TestData
emits some state. Problem for this code is that, if user plays something, since TestScaleUpdated
state won't be emitted, widget B's status goes back to initial state, showing "100 %" always.
If user updates scale, then TestValueUpdated
won't be emitted, so widget A will always have initial state, showing "00:00.000 / 00:04.800 | 1.1.1".
So what I want to perform now is that, I want to make widget ignore status update. For example, in builder of BlocBuilder
(context, state) {
if(state is TestScaleUpdated) {
return Text("Scale!");
else if(state is TestInitial) {
return Text("Initial!");
} else {
//ignore, or keep widget's status
}
}
Problem here, if I explain more detailed, is this :
Let's assume that user played something, so widget A's text is changed to 00:10.000 / 00:40.000 | 2.0.0
.
Then when user tries to change scale value, not only widget B affected, but also widget A gets affected. But since TestData
emitted only TestScaleUpdated
state, widget A's text gets back to 00:00.000 | 00:04.800 | 1.1.1
while it should keep its text, and status.
I want to make only widget B updated when TestScaleUpdated
is emitted, and make only widget A updated when TestValueUpdated
is emitted. Simply, managing 2 or more widgets differently with one cubit class.
Do I have to merge these 2 states : TestScaleUpdated
, and TestValueUpdated
into 1 state containing 2 message
for each widget?
or can I keep status of widget if emitted state doesn't satisfy specific condition?
I would create one state which has all the required information. But if you just want the widgets to rebuild only in certain situations, then you can do it like this for your Widget A:
BlocBuilder<TestData, TestState>(
buildWhen: (oldState, newState) => newState is TestValueUpdated;
builder: (context, state) {
return Text(
state is TestValueUpdated ? state.message : "00:00.000 / 00:04.800 | 1.1.1",
textAlign: TextAlign.end,
style: TextStyle(color: ThemeManager.getRGBfromHex(0x514745)),
);
},
)