如何在AlertDialog中显示bloc状态

huangapple go评论51阅读模式
英文:

flutter - How to show bloc state in AlertDialog

问题

I have very simple app which use switch and bloc state management. Switch state management work, but I would like to show state of switch to user via AlertDialog.

Here is switch widget:

@override
Widget build(BuildContext context) {
  return BlocProvider(
    create: (_) => SwitchCubit(),
    child: BlocBuilder<SwitchCubit, bool>(
      builder: (context, state) {
        return Switch(
          value: state,
          activeColor: Colors.green,
          onChanged: (bool value) {
            // This is called when the user toggles the switch.
            BlocProvider.of<SwitchCubit>(context).toggle();
          },
        );
      },
    ),
  );
}

and here is way I'm trying to show state of switch to user (true or false).

appBar: AppBar(
  title: const Text('Switch bloc test'),
  actions: [
    IconButton(
      icon: const Icon(Icons.info),
      tooltip: 'Switch bloc test',
      onPressed: () {
        showDialog(
          context: context,
          builder: (context) {
            return Material(
              child: BlocBuilder<SwitchCubit, bool>(
                builder: (context, state) => AlertDialog(
                  content: Text(state.toString()),
                ),
              ),
            );
          },
        );
      },
    ),
  ],
),

Source code of project: GitHub Link

英文:

I have very simple app which use switch and bloc state management. Switch state management work, but I would like to show state of switch to user via AlertDialog.

Here is switch widget:

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) =&gt; SwitchCubit(),
      child: BlocBuilder&lt;SwitchCubit, bool&gt;(
        builder: (context, state) {
          return Switch(
            value: state,
            activeColor: Colors.green,
            onChanged: (bool value) {
              // This is called when the user toggles the switch.
              BlocProvider.of&lt;SwitchCubit&gt;(context).toggle();
            },
          );
        },
      ),
    );
  }

and here is way I'm trying to show state of switch to user (true or false).

appBar: AppBar(
  title: const Text(&#39;Switch bloc test&#39;),
  actions: [
    IconButton(
      icon: const Icon(Icons.info),
      tooltip: &#39;Switch bloc test&#39;,
      onPressed: () {
        showDialog(
          context: context,
          builder: (context) {
            return Material(
              child: BlocBuilder&lt;SwitchCubit, bool&gt;(
                builder: (context, state) =&gt; AlertDialog(
                  content: Text(state.toString()),
                ),
              ),
            );
          },
        );
      },
    ),
  ],
),

How should I continue and avoid getting this ?

如何在AlertDialog中显示bloc状态

Source code of project: https://github.com/Kalyxt/switchbloc_flutter

答案1

得分: 1

你需要将Bloc/Cubit提供给AlertDialog。这是因为在对话框中使用了不同的BuildContext。

在showDialog方法中,使用BlocProvider包装Material小部件,并在那里提供SwitchCubit,类似于我在这里描述的解决方案:https://stackoverflow.com/questions/75774451/handle-blocprovider-with-modal-bottom-sheet/75775051#75775051

编辑:

1)不要创建一个新的SwitchCubit。提供一个已经存在的SwitchCubit。
2)确保已存在的SwitchCubit在widget树中位于此之上。
3)重命名内部BuildContext,以便在向对话框提供Bloc/Cubit时使用正确的BuildContext。

showDialog(
  context: context,
  builder: (innerContext) {
    return BlocProvider.value(
      value: context.watch<SwitchCubit>(),
      child: Material(
        child: BlocBuilder<SwitchCubit, bool>(
          builder: (context, state) => AlertDialog(
            content: Text(state.toString()),
          ),
        ),
      ),
    );
  },
);

注意: 如果现在仍然出现相同的问题,那么你还没有执行步骤2)。

英文:

You have to provide the Bloc/Cubit to the AlertDialog. That's because it is a different BuildContext in the dialog.

Wrap the Material widget in the showDialog method with a BlocProvider and provide the SwitchCubit there.

Kind of the same solution as I described here:

https://stackoverflow.com/questions/75774451/handle-blocprovider-with-modal-bottom-sheet/75775051#75775051

Edit:

  1. Don't create a new SwitchCubit. Provide an already existing one.

  2. Make sure that the existing SwitchCubit is created above this in the widget tree.

  3. Rename the inner build context so that the correct BuildContext is used when providing the Bloc/Cubit to the dialog.

     showDialog(
       context: context,
       builder: (innerContext) {
         return BlocProvider.value(
           value: context.watch&lt;SwitchCubit&gt;(),
           child: Material(
             child: BlocBuilder&lt;SwitchCubit, bool&gt;(
               builder: (context, state) =&gt; AlertDialog(
                 content: Text(state.toString()),
               ),
             ),
           ),
         );
       },
     );
    

Note: If you get the same fault now, then you haven't done bullet 2) above.

答案2

得分: 1

尝试添加一个额外的构建器,以获取一个使用已创建的SwitchCubit的新上下文

return BlocProvider(
  create: (_) => SwitchCubit(),
  child: Builder(
    builder: (context) {
      return BlocBuilder<SwitchCubit, bool>(
        builder: (context, state) {
          return Switch(
            value: state,
            activeColor: Colors.green,
            onChanged: (bool value) {
              // 当用户切换开关时调用此方法。
              BlocProvider.of<SwitchCubit>(context).toggle();
            },
          );
        },
      );
    },
  ),
);
英文:

Try to add an extra builder, to get a new context with the created SwitchCubit

    return BlocProvider(
      create: (_) =&gt; SwitchCubit(),
      child: Builder(
        builder: (context) {
          return BlocBuilder&lt;SwitchCubit, bool&gt;(
            builder: (context, state) {
              return Switch(
                value: state,
                activeColor: Colors.green,
                onChanged: (bool value) {
                  // This is called when the user toggles the switch.
                  BlocProvider.of&lt;SwitchCubit&gt;(context).toggle();
                },
              );
            },
          );
        },
      ),
    );
    ```

</details>



# 答案3
**得分**: 0

You used bloc provider in different route, so that state can't find provider, use provider in main then all widget in the tree can access it.

<details>
<summary>英文:</summary>

You used bloc provider in different route, so that state can&#39;t find provider, use provider in main then all widget in the tree can access it

</details>



huangapple
  • 本文由 发表于 2023年4月17日 20:08:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76035009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定