如何在 Flutter Web 中动态更改 App Title?
Posted
技术标签:
【中文标题】如何在 Flutter Web 中动态更改 App Title?【英文标题】:How to dynamically change the App Title in Flutter Web? 【发布时间】:2020-06-12 20:25:12 【问题描述】:网络应用通常会在标签的标题中反映当前显示的内容。
将title
parameter 提供给MaterialApp
或WidgetsApp
意味着我无法在不重建整个树的情况下更改它,即在我返回@ 的顶层调用setState
987654328@.
MaterialApp(
title: 'Web app title',
...,
)
我希望能够在任何时间从应用中的anywhere更改应用标题。我该怎么做?
【问题讨论】:
【参考方案1】:Flutter 中的动态应用标题
应用标题可以使用SystemChrome.setApplicationSwitcherDescription
动态在所有平台上更改:
@override
Widget build(BuildContext context)
SystemChrome.setApplicationSwitcherDescription(ApplicationSwitcherDescription(
label: 'Dynamic web app title',
primaryColor: Theme.of(context).primaryColor.value,
));
return Container(...);
SystemChrome
与 import 'package:flutter/services.dart';
一起可用,并且您想在 build
方法中调用 setApplicationSwitcherDescription
。
Title
也是这样做的(参见source code),这是WidgetsApp
、MaterialApp
等使用的小部件。
因此,您也可以使用Title
小部件而不是自己访问SystemChrome
:
@override
Widget build(Context context)
return Title(
label: 'Dynamic app title',
primaryColor: Theme.of(context).primaryColor,
child: ..,
);
label
label
参数非常简单:它精确映射到 title
在您的 MaterialApp
中的内容,并且只是一个 String
。
primaryColor
primaryColor
将确定系统可能在应用程序切换器中使用的颜色,例如android 上最近使用的标题栏颜色。
这是Color
的int
,而不是,这就是为什么您需要调用Color.value
将您的原色转换为整数。
干扰其他Title
s
您可能会问自己,在设置MaterialApp
上的title
属性时调用setApplicationSwitcherDescription
或插入Title
小部件是否会导致任何问题。
答案是:否,因为树中最深处的小部件将设置标题。从本质上讲,即使整个应用程序重新构建,您的 setApplicationSwitcherDescription
也会在 MaterialApp
之后被调用,假设您在孩子中调用它,因此您将覆盖 MaterialApp
标题。
【讨论】:
@easeccy 您的编辑正在discissed on meta。 使用Title
小部件,使用Navigator.pop(context);
从另一个页面返回时如何恢复标题?或者如何检测onResume
事件以便我可以调用SystemChrome.setApplicationSwitcherDescription()
?我对这种简单需求的复杂性感到困惑。【参考方案2】:
这已经晚了将近 2 年,但我为此找到了不错的解决方案。没那么简单,但是很好用。
main.dart
在MaterialApp
内,添加navigatorObservers
:
MaterialApp(
initialRoute: "/welcome",
routes: <String, WidgetBuilder>
'/welcome': (BuildContext context) => WelcomeScreen(),
'/login': (BuildContext context) => LoginScreen(),
'/register': (BuildContext context) => RegisterScreen(),
,
// other codes ...
navigatorObservers: [MyRouteObserver()],
// other codes ...
);
在最底部添加:
class MyRouteObserver extends RouteObserver<PageRoute<dynamic>>
void _setTitle(String what, PageRoute<dynamic> routeFrom, PageRoute<dynamic> routeTo)
final oldScreenName = routeFrom.settings.name;
final newScreenName = routeTo.settings.name;
log("route changed: $what ($oldScreenName -> $newScreenName)"); // it's just route activity log, don't forget to import 'dart:developer';
final uri = Uri.parse(newScreenName ?? "");
final routeName = uri.pathSegments.isNotEmpty ? uri.pathSegments.first : "";
switch ("/$routeName")
case "/welcome" : return setTitle("Welcome");
case "/login" : return setTitle("Login");
case "/register" : return setTitle("Sign Up");
// etc ...
setTitle("Not Found");
@override
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute)
super.didPush(route, previousRoute);
if (route is PageRoute && previousRoute is PageRoute) _setTitle("push", previousRoute, route);
@override
void didReplace(Route<dynamic>? newRoute, Route<dynamic>? oldRoute)
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
if (newRoute is PageRoute && oldRoute is PageRoute) _setTitle("replace", oldRoute, newRoute);
@override
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute)
super.didPop(route, previousRoute);
if (route is PageRoute && previousRoute is PageRoute) _setTitle("pop", route, previousRoute);
helpers.dart
void setTitle([String? title]) async
Future.microtask(()
SystemChrome.setApplicationSwitcherDescription(ApplicationSwitcherDescription(
label: "Your APP | $title ?? 'Your Tagline'",
primaryColor: Colors.blue.value, // your app primary color
));
);
最后,如果您想在特定页面中单独覆盖标题,请执行以下操作:
@override
void initState()
super.initState();
WidgetsBinding.instance?.addPostFrameCallback((_)
setTitle("Custom Page Title");
);
【讨论】:
以上是关于如何在 Flutter Web 中动态更改 App Title?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Eclipse 中更改动态 Web 项目的上下文根?