如何在颤动中忽略肘部的状态?

Posted

技术标签:

【中文标题】如何在颤动中忽略肘部的状态?【英文标题】:How to ignore state with cubit in flutter? 【发布时间】:2021-08-09 22:25:15 【问题描述】:

我正在使用 cubit 来管理小部件的状态,并且我希望仅在发出特定类型的状态时才更新小部件。

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;

我创建了名为 TestState 的状态类,这个类目前有 3 个状态:初始、值更新、规模更新

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() + " %"));
  

这个名为TestData 的类使用TestState 并扩展了Cubit

基本上,当用户通过捏屏幕更新缩放值时,该类会发出TestScaleUpdated状态,当用户播放某些东西时,它会发出TestValueUpdated状态。

在用户界面中,

//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)) ,
      );
    
  ,
)

我试过这段代码。当TestData 发出一些状态时,这两个小部件会更新它们的状态。这段代码的问题是,如果用户播放某些东西,由于不会发出 TestScaleUpdated 状态,小部件 B 的状态会回到初始状态,始终显示“100 %”。

如果用户更新 scale,则不会发出 TestValueUpdated,因此小部件 A 将始终具有初始状态,显示“00:00.000 / 00:04.800 | 1.1.1”。

所以我现在想要执行的是,我想让小部件忽略状态更新。比如BlocBuilder的builder中

(context, state) 
  if(state is TestScaleUpdated) 
    return Text("Scale!");
  else if(state is TestInitial) 
    return Text("Initial!");
   else 
    //ignore, or keep widget's status
  

这里的问题,如果我解释得更详细,是这样的: 假设用户玩了一些东西,所以小部件 A 的文本更改为 00:10.000 / 00:40.000 | 2.0.0

然后,当用户尝试更改比例值时,不仅小部件 B 受到影响,小部件 A 也受到影响。但由于TestData 只发出TestScaleUpdated 状态,小部件A 的文本会回到00:00.000 | 00:04.800 | 1.1.1,同时它应该保留其文本和状态。

我想在发出TestScaleUpdated 时只更新小部件B,并在发出TestValueUpdated 时只更新小部件A。简单地说,用一个肘类以不同的方式管理 2 个或多个小部件。

我是否必须将这 2 个状态:TestScaleUpdatedTestValueUpdated 合并为 1 个状态,其中每个小部件包含 2 个 message

如果发出的状态不满足特定条件,我可以保留小部件的状态吗?

【问题讨论】:

【参考方案1】:

我会创建一个包含所有必需信息的状态。但是,如果您只是希望小部件仅在某些情况下重建,那么您可以为小部件 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)),
      );
  ,
)

【讨论】:

嗯,我应该更详细地解释一下情况。假设小部件 A 的文本是 00:10:000 / 00:40.000 | 2.0.0。但是,当用户更改比例时,小部件 A 的文本会返回到 00:00.000 / 00:04.800 | 1.1.1,而它应该保持其时间和数字。我只想在发出 TestScaleUpdated 状态时更新小部件 B。我可以将 2 个状态合并为 1 个状态,包含小部件 A 和 B 所需的所有数据,但我不想创建不必要的 data。合并状态,使包含所有数据的状态成为唯一的方法吗? 合并状态很有用,但可能足以实现我的上述解决方案,因为小部件 A 然后重建,例如,仅当状态相应更改时。但我会同时做:实现 BlocBuilder 的 buildWhen-Function 并拥有一个保存所有必需数据的状态。 哦,抱歉,我现在看到了buildWhen。是的,我想要这样的东西。非常感谢,我会接受你的回答

以上是关于如何在颤动中忽略肘部的状态?的主要内容,如果未能解决你的问题,请参考以下文章

在listview中颤动Custompaint:忽略两个手指滚动

如何在颤动中维护页面的状态

如何在颤动中从父小部件访问所有孩子的状态?

如何在颤动中使用 hydated_bloc 保持状态?

如何在颤动的另一个有状态小部件中访问在一个有状态小部件中创建的对象

如何在颤动中使设备顶部面板(状态栏)具有与 AppBar 相同的背景颜色?