Milad-Akarie / auto_route_library

Flutter route generator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dynamic title for AutoTabsScaffold (inside AppBar)

mnbucher opened this issue · comments

dear folks,

so far very happy with the auto_router package as it has already solved our requirements of nested navigation so far!

one issue we came around recently was the need for having "custom" titles for a AutoTabsScaffold (the title in the AppBar), being ideally dynamic on some instance variable living inside the current class/page/route.

so far, our approach was to use tabsRouter.topRoute.args inside the appBarBuilder, as we can get access to the Args of the most current route of the stack. however, this raises the problem that args is a different class for every page (being of type Object to cover all args classes), as of course it may hold completely different arguments in every page. in our case, we want to have a pageTitle on every page inside auto_route, despite having different other arguments.

our current workaround to extract that title in the AppBar is to set a class variable pageTitle on every page inside @MaterialAutoRouter and write an abstract class RouterArgs, which holds this pageTitle:

abstract class RouterArgs {
  late String pageTitle;
}

next, we append all generated Args classes with SomePageArgs extends RouterArgs, such that we can cast the tabsRouter.topRoute.args variable inside the AutoTabsScaffold to a variable of type RouterArgs , giving us access to the pageTitle:

title = (tabsRouter.topRoute.args as RouterArgs).pageTitle;

this is of course only a workaround as we need to manually rewrite the generated ".gr.dart" file, so we thought that it would be great to have an argument inside the @MaterialAutoRouter such as:

@MaterialAutoRouter(
  ...
  argsInterface: RouterArgs,
  ...
)

which would then automatically extend all args classes with that interface. this would of course assume that all args classes actually can extend this abstract class (i.e. interface).

what do you think of our current approach? is there a better option to get access on a class variable which exists on ALL pages (i.e. routes) inside auto_route such that we can generate dynamic titles inside a AutoTabsScaffold?

best and many thanks!
martin

Hello @mnbucher I like the idea of shared args interface but I'm not sure about passing the title everytime we navigate, besides in tabsRouter we usually navigate by setting the active index, how are you going to pass the title then?

I've two suggestions for you
1- using route meta data to set page titles
AutoRoute(page: ..., meta:{'title','PAGE TITLE'})
title = tabsRouter.topRoute.meta['title'] ;
cons: this approach is not strongly typed and it doesn't work for multi Language Apps.

2- is to create a map of route names and their corresponding titles like follows

final _titlesMap = {
   RouteOne.name: 'localized route name',
   RouteTwo.name: 'localized route name',
 }

title = _titlesMap[tabsRouter.topRoute.name];

hi @Milad-Akarie,

thx for taking the time to reply :) your idea makes sense when using "hardcoded" titles known during compile time (if i understood your idea correctly).

however, we wish to generate the titles for the AppBar during runtime, e.g. when navigating to the "Chat" page via a BottomNavigationBar, we have a nested list of views (e.g. first view may be some topic overview, second view may be a list of N chat previews, and a third view may be the actual chat view between 2 people).

this means that we need to display a dynamic title (e.g. the name of the person you're writing in the chat) in the top navigation bar. this is how it is done for many popular native iOS/Android apps and improves UX (in our opinion).

without dynamic titles, we would only have a hardcoded title "Chat" in the AppBar, independent to whom we are writing to in a ChatView / ChatPage.

our current solution solves our issue, as we pass an argument "pageTitle" when dynamically setting the routes or pushing a new route to the current router list. (e.g. push(ChatRoute(pageTitle: "Milad-Akarie")).

we also thought about an approach to dynamically cast the Args object to some JSON (and then read from a simple Map object in dart), as this would circumvent the need to cast our dynamic Args class to a "parent" interface. but so far we haven't been successful, as a toJSON function needs to be defined on the class itself, where we don't have access to, since the class is generated.

best,
martin

hmm I understand the need but I still can't figure out a neat approach. any other ideas than shared args interface?

@mnbucher routers from different platform usually have a title property that has nothing to do with route args, what do you think of something that looks like this.

AutoRoute(page:..., title: 'title priority 1')
router.push(MyRoute(), title: 'title priority 0');

then it can be accessed like so router.topRoute.title;

@Milad-Akarie sounds like a great feature to me. how would an access to this property look like from the AutoTabsScaffold class? Simply tabsRouter.topRoute.title, as the title property lives on the route itself? And may be null if not defined during a push? (which would be fine in my opinion as giving a title is optional, thus title would simply be a nullable class variable living on the Route class.

What is the current status of this issue ?

I'm currently facing a similar case

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions