Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dynamic color support #605

Merged
merged 4 commits into from
Jan 14, 2025
Merged

add dynamic color support #605

merged 4 commits into from
Jan 14, 2025

Conversation

ErBWs
Copy link
Contributor

@ErBWs ErBWs commented Jan 14, 2025

Close #2

用 Provider 代替 Adaptive theme

已知问题:

======== Exception caught by foundation library ====================================================
The following assertion was thrown while dispatching notifications for ThemeProvider:
setState() or markNeedsBuild() called during build.

This _InheritedProviderScope<ThemeProvider?> widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: _InheritedProviderScope<ThemeProvider?>
  value: Instance of 'ThemeProvider'
  listening to value
The widget which was currently being built when the offending call was made was: AppWidget
  dirty
  dependencies: [_InheritedProviderScope<ThemeProvider?>]
  state: _AppWidgetState#816d1

@Predidit
Copy link
Owner

也许我们可以尝试解决一下这个报错

是否可以将 app_widget.dart 中 build 函数进行的 setDynamic setTheme 等调用移动到一个组件树相对稳定的场合

例如 init_page.dart 中的 build 函数的 WidgetsBinding.instance.addPostFrameCallback 回调中

@ErBWs
Copy link
Contributor Author

ErBWs commented Jan 14, 2025

晚点试试,先打会游戏(

@Predidit
Copy link
Owner

Predidit commented Jan 14, 2025

总之我们不能在 build 时调用 themeProvider 的 set 方法。

app_widget 中使用其他方式初始化主题应该也可以,例如直接将 color 等作为 MaterialApp 的参数传入。

@ErBWs
Copy link
Contributor Author

ErBWs commented Jan 14, 2025

问题出在 notifyListeners,控制 app_widget 内不执行就可以了

全部放在 init_page 会导致 theme 未初始化错误

如果初始状态 useDynamicColor 为真会导致白屏再切换到正常状态,可能是因为通过 PlatformChannel 获取主题色比较耗时的原因。在深色模式下会很难受,所以把 setDynamic 放在 init_page,取折中的方案让主题色延后应用

Screen-2025-01-15-003501.1.mp4

@Predidit
Copy link
Owner

感谢你的工作,这个实现非常漂亮

只剩下两个小问题

  1. 我们一般不在 initState 中注册WidgetsBinding.instance.addPostFrameCallback回调,一般是注册在 build 方法中。

这里注册在 initState 中的目的是?

  1. modules文件夹下存放的都是一些实体类。我们也许可以把 themeprovider.dart 放在 bean/theme 下面

这个项目并不是 Clean Arch 架构,我们也没有必要在项目根目录下创建 provider 文件夹来存放 themeprovider

@ErBWs
Copy link
Contributor Author

ErBWs commented Jan 14, 2025

  1. 放在 build 中会显示 late 重复初始化,我一开始以为上面那个报错是 initState 中初始化方式不对造成的
  2. OK

@Predidit
Copy link
Owner

Predidit commented Jan 14, 2025

  1. 这个操作应该不需要注册回调,应该可以直接在 initState 中安全地获取 Provider

@ErBWs
Copy link
Contributor Author

ErBWs commented Jan 14, 2025

话说为什么把这个文件夹命名为 bean?这是我一直好奇的一个点,不是很了解

@Predidit
Copy link
Owner

那段时间有在看 Java,来源应该是 Java Spring Bean。

不过和 Bean 的理念现在看上去完全不符,命名很失败。

@ErBWs
Copy link
Contributor Author

ErBWs commented Jan 14, 2025

噢 init_page 的 setDynamic 那里应该加个注释的,算了以后再加吧(

@Predidit Predidit merged commit 1b3dda3 into Predidit:main Jan 14, 2025
6 checks passed
@ErBWs
Copy link
Contributor Author

ErBWs commented Jan 14, 2025

那段时间有在看 Java,来源应该是 Java Spring Bean。

不过和 Bean 的理念现在看上去完全不符,命名很失败。

原来如此,感谢解答

@ErBWs ErBWs deleted the feat-dynamic-color branch January 14, 2025 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

支援md3的動態取色
2 participants