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

Design a dynamic platform theming mechanism between Material and Cupertino #8410

Open
xster opened this Issue Feb 25, 2017 · 19 comments

Comments

@xster
Copy link
Contributor

xster commented Feb 25, 2017

Provide an easy way for developers to insert a simple widget whose UI conforms to Material or Cupertino depending on runtime platform

@xster

This comment has been minimized.

Copy link
Contributor

xster commented Mar 28, 2017

One concrete example for a semi-complex case where we probably want the experience to be magical-ish without too much user selection is with page routes.

Currently the dependency is:

material.MaterialPageRoute -> material._MountainViewPageTransition
                           -> material._CupertinoPageTransition

So the graph is
user's app
material [_MountainViewPageTransition, _CupertinoPageTransition]
widget

We'd need to clear up the dependency graph a bit. Starting from the graph down, we probably want:
user's app
platform dynamic
material / cupertino
widget

So one unpolished idea might be to do something like:

platform_widget(or something).PlatformPageRoute -> material.MaterialPageTransition
                                                -> cupertino.CupertinoPageTransition

which implies a user API change from pushing MaterialPageRoute to PlatformPageRoute.

or we can do something like:

material.MaterialPageRoute -> widget.PageTransition => platform_widget.PlatformPageTransition -> material.MaterialPageTransition
                                                                                              -> cupertino.CupertinoPageTransition

which implies we're saying the users don't have to manually think about page transitions and the Material spec is automatically platform dynamic. We'd also have to do the dependency injection of widget.PageTransition -> platform_widget.PlatformPageTransition in the MaterialApp.

@xster

This comment has been minimized.

Copy link
Contributor

xster commented Mar 28, 2017

https://material.io/guidelines/patterns/navigational-transitions.html
Doesn't really say anything about any platform specific page transitions and basically says all parent->child transitions are hero transitions. If we take it literally, we still need to do something for #8726 since not every user wants to strictly adhere to Material design.

Which makes me lean more towards option 1 where the user specifies that he wants a platform dynamic page route (and perhaps will be overriden with a hero navigation observer most of the time).

cc @HansMuller

@abarth

This comment has been minimized.

Copy link
Contributor

abarth commented Mar 28, 2017

Material Design has a notion of adapting to the target platform. That means it's conceptually fine for material.dart to take a dependency on cupertino.dart and for MaterialPageRoute to know about both _MountainViewPageTransition and _CupertinoPageTransition.

Another way to approach this thought experiment is to build a pure CupertinoPageRoute and then see what parts of its machinery MaterialPageRoute wants to use in order to adapt to iOS.

@HansMuller

This comment has been minimized.

Copy link
Contributor

HansMuller commented Mar 28, 2017

Developers may want to control the mapping from generic components to potentially platform-specific ones. In other words rather than providing generic components that just map from the platform to some platform-specific component (or transition or whatever), developers might prefer for control to flow through a look-and-feel theme that they can customize. Maybe I'd like generic buttons to map to MyButton and route transition durations to be 500ms. If the l&f theme was an inherited widget I could configure for the app or a subtree.

@xster

This comment has been minimized.

Copy link
Contributor

xster commented Mar 28, 2017

@HansMuller that's always going to be true in any of the options. Users can always pick a specific route or transition. If there were dynamic wrappers, they're just a thin convenience layer.

@xster

This comment has been minimized.

Copy link
Contributor

xster commented Mar 28, 2017

Chatted offline. So conceptually, instead of making Cupertino and Material siblings with each meaning a full spec'ed design opinion and components for iOS and Android and having a common parent, we'll extract MountainView out of Material and make MountainView and Cupertino siblings. Those will be the basic OS components that have less value add if the developers remade them. Material will be the opinionated design usage of MountainView and Cupertino base components. And the user that wants to create non-Material apps can reuse MountainView and not have to recreate non-value-add basic components.

(cc @sethladd https://docs.google.com/presentation/d/1cw7A4HbvM_Abv320rVgPVGiUP2msVs7tfGbkgdrTy0I/edit?ts=58d9dd75#slide=id.gbb3c3233b_0_162)

@pspeter3

This comment has been minimized.

Copy link

pspeter3 commented Mar 16, 2018

Is there any documentation about rendering the correct widgets for each platform? I thought there was but I'm not sure anymore.

@pascalwacker

This comment has been minimized.

Copy link

pascalwacker commented Mar 23, 2018

Is this behaviour set in the MaterialApp, theme property, like
theme: new ThemeData( platform: Theme.of(context).platform == TargetPlatform.iOS ? TargetPlatform.iOS : TargetPlatform.android ),

@xster xster added this to Pending O(weeks) in xster tasks Mar 29, 2018

@kowsheek

This comment has been minimized.

Copy link

kowsheek commented Apr 2, 2018

@pspeter3 I don't think there was. After much digging the closest thing I could find was this by @emshack 👏

@xster xster moved this from Pending O(weeks) to In-Progress O(days) in xster tasks May 16, 2018

@xster xster self-assigned this May 16, 2018

@xster xster moved this from In-Progress O(days) to Holding for review in xster tasks May 23, 2018

@xster

This comment has been minimized.

Copy link
Contributor

xster commented May 25, 2018

We're discussing about a solution for this now.

For those that are interested on the thread, can you guys provide some specific examples (even better with usage code) of what behaviors you'd like to see from Flutter?

Especially if you would like additional functionalities than Flutter providing a widget that simply does:

class PlatformBuilder extends StatelessWidget {
  const PlatformBuilder({
    this.materialWidgetBuilder,
    this.cupertinoWidgetBuilder,
  });

  final WidgetBuilder materialWidgetBuilder;
  final WidgetBuilder cupertinoWidgetBuilder;

  @override
  Widget build(BuildContext context) {
    switch (Theme.of(context).platform) {
      case TargetPlatform.android:
        return materialWidgetBuilder(context);
      case TargetPlatform.iOS:
        return cupertinoWidgetBuilder(context);
    }
  }
}
@pspeter3

This comment has been minimized.

Copy link

pspeter3 commented May 25, 2018

Either that or providing people a way to think about cross platform well. Right now, I feel like I would either write many Builders similar to what you wrote or leave switch statements scattered across the code.

@mpiannucci

This comment has been minimized.

Copy link

mpiannucci commented Jun 17, 2018

I recently struggled with this, and kinda ditched it because it got a little too tedious for me.

All I really want is a way to get Platform Specific AppBar's (ios Navbars), BottonNavigtionBar (ios TabBar), spinners, and dialogs without extra effort. Those are the main pieces that really stand out to me that I feel like MUST be in the native design language.

@jeanluc243

This comment has been minimized.

Copy link

jeanluc243 commented Aug 7, 2018

👏

@Hixie

This comment has been minimized.

Copy link
Contributor

Hixie commented Aug 14, 2018

cc @willlarche - you may be interested in seeing above what some of our developers are saying they would like from Flutter in terms of automatic cross-platformness (beyond what Material is defined as doing today).

@xster xster removed their assignment Sep 13, 2018

@Hixie Hixie modified the milestones: Goals, Stretch Goals Oct 16, 2018

@giacomocerquone

This comment has been minimized.

Copy link

giacomocerquone commented Oct 25, 2018

Where are we with this?
I was reading 10 minutes ago this topic on google groups: https://groups.google.com/forum/#!topic/flutter-dev/UOqzbSpurqg

Basically what "Adam Barth" was saying is that changing design language, can change the functionalities of the single widgets and it's right but not for most of them.
A dialog is a dialog and they differ only in the way they're styled and it's so for around 85% of the widgets.

At the expense of clarity, I see two roads:

  1. Apply as default the behaviour showed by @xster only on the "safe" widgets (safe meaning here that I can't attach a function on an inexistent behaviour of another design language of the same widget). This creates a weir behaviour for the user that don't know this.
  2. Create "n" extra components that are called somewhat like: "PlatformDialog", "PlatformActionSheet" or "PlatformButton" that does nothing more of the switch proposed above.

I'd go for the second

But not having this functionality built-in, I know for sure is not good for a project's codebase. I've seen many flutter apps doing this switch manually over the flutter widgets.

Tell me yours :)

@wenerme

This comment has been minimized.

Copy link

wenerme commented Oct 25, 2018

second pleases. https://ionicframework.com display platform styled widget, but expose the same interface.

@pascalwacker

This comment has been minimized.

Copy link

pascalwacker commented Oct 25, 2018

I would also prefer the second option. If there are platform specific settings these widgets could have a property like cupertinoFooBar where you can pass in additional arguments.

@rajkar86

This comment has been minimized.

Copy link

rajkar86 commented Nov 1, 2018

I'd prefer the second option as well.

@manhluong

This comment has been minimized.

Copy link

manhluong commented Nov 9, 2018

Second option for me as well.

If I am not wrong, it should be something like what this library is doing: https://pub.dartlang.org/packages/flutter_platform_widgets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment