Skip to content

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

Closed

Description

@xster

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

Activity

  1. added
    p: cupertino_uicupertino_ui package in flutter/packages
    p: material_uimaterial_ui package in flutter/packages
    platform-iosiOS applications specifically
    on Feb 25, 2017
  2. added this to the milestone on Feb 25, 2017
  3. xster commented on Mar 28, 2017

    @xster
    MemberAuthor

    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.

  4. xster commented on Mar 28, 2017

    @xster
    MemberAuthor

    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

  5. abarth commented on Mar 28, 2017

    @abarth
    Contributor

    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.

  6. HansMuller commented on Mar 28, 2017

    @HansMuller
    Contributor

    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.

  7. xster commented on Mar 28, 2017

    @xster
    MemberAuthor

    @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.

  8. xster commented on Mar 28, 2017

    @xster
    MemberAuthor

    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)

  9. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    on May 23, 2017
  10. modified the milestones: , 3: Current Milestone on Jul 31, 2017
  11. pspeter3 commented on Mar 16, 2018

    @pspeter3

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

  12. pascalwacker commented on Mar 23, 2018

    @pascalwacker

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

  13. 16 remaining items

  14. Hixie commented on Feb 27, 2019

    @Hixie
    Contributor

    I'm curious about what people would actually like here. For something like the back button, we do this automatically already. For something a little more elaborate, like a regular text button, one could imagine a control that automatically switches between Cupertino and Material variants. But what about more complicated things? For example, the Switch control is a different size on iOS and Material, what should happen when you use that? Should it change size? Be the biggest size? What about something like a checkbox, which exists on Material but not iOS? Or Navigator, which works entirely differently in Material and iOS paradigms?

  15. xster commented on Feb 27, 2019

    @xster
    MemberAuthor

    To somewhat second Hixie, as we try to make this more concrete, it's becoming clearer that these are questions that need to be answered at design time rather than implementation time (and even less so doing it implicitly).

    Even for relatively simple things like sliders and dialogs, in Material, sliders can have manually editable numeric fields, iOS does not. With dialogs, Material specs against having more than 2 responses while UIAlertController supports a vertical scrollable list of actions when there are more than 2 (though discouraged). The interchangeability of dialog/alerts and action sheets is also greater on iOS and requires more design level subjectivity. What should the API be in a common widget?

    At mid-level complexity: the Material app bar supports toggling into contextual actions mode and having stateful actions (such as the pin button in Google Inbox). iOS's navigation bar commonly has segmented controls in lieu of a title. Material bottom sheets are highly flexible, can be dismissible without choosing any action, can be scrollable/expandable, can even expand into full screens themselves. iOS action sheets are always modal, can't contain arbitrary widgets and aren't even necessarily anchored at the bottom of the screen on iPads. What to do in each case are answers your apps' designers need to answer.

    At your application's information architecture level, the 2 designs can diverge on the general pattern. In iOS, tab bars with parallel navigation stacks are common. Page navigations occur inside of tabs generally but you can also summon full screen modals that presents pages over the tabs. With Material, what the HIG calls "Flat Navigation" isn't common practice and lateral navigation happens in one page at the hierarchy root level via commonly the drawer. This can create entirely different app experiences. You can navigate to the same sub-item from a feed in tab 1 and from search in tab 2 on iOS. You can go into a profile tab in tab 3, change some app-wide setting and go back to tab 1. These interactions aren't possible if lateral navigation only happen at the root. These are all product/design level questions that are likely too late to try to answer at implementation time.

    Given the need to make design choices, there are 2 choices we can take (and get community feedback on).

    1- Present an opinionated and (arbitrarily) shrunk down set of widgets that takes the minimally supported API options from both while making compromises clearly documented. e.g. there's always 2 choices on dialogs, common app/nav bars can't have iOS 11 style large titles or be translucent etc. Since these design choices aren't inherently related to Material or Cupertino themselves, they can't be in either packages and should be separate Flutter package in pub.
    2- Produce a design spec that specifies what happens in the harder cases such as the app's IA such that it's coherent in both cases. Though this is clearly a harder task and could still imply some design choices are either excluded (no sliders with manual value edits) or not platform adapting (only simple bottom/action sheets. If you try to use expandable, you need to fallback to straight Material design).

    Orthogonally to all of this, some UI are always going to be 'wrong' if not done, such as back swipe navigations on iOS or iOS scroll physics on Android. For those, we always auto-adapt to the platform.

  16. xster commented on May 7, 2019

    @xster
    MemberAuthor

    In order to move this issue forward and to take concrete action based on user feedback, I've created a doc http://bit.ly/flutter-adaptive-widget-problem to clarify terminology around this nebulous concept and hopefully break it down into smaller bits.

    Please give us your feedback in terms of what specifically is desired with respect to 'dynamic adaptations'. Once we have some feedback, we can close this issue and break it down into smaller specific actionable issues.

  17. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on May 10, 2019
  18. ShadyBoukhary commented on May 27, 2019

    @ShadyBoukhary

    @xster The document you provided is very helpful. I think automatic switching on types 3 and 4 is very helpful. In addition, just to add to the conversation, something like https://pub.dartlang.org/packages/flutter_platform_widgets
    would also be incredibly helpful.

  19. no-response commented on May 31, 2019

    @no-response

    Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now. Please don't hesitate to comment on the bug if you have any more information for us; we will reopen it right away!
    Thanks for your contribution.

  20. xster commented on Jun 4, 2019

    @xster
    MemberAuthor

    We haven't received any actionable feedback from http://bit.ly/flutter-adaptive-widget-problem so we're closing this issue and branching off the subset (type 4) of the problem that's solvable in #33830.

    @ShadyBoukhary, for type 3, specifically based on http://bit.ly/flutter-adaptive-widget-problem, which compromises would you like us to make (such as in the dialog/dropdown/action sheet/picker/pop-up many-to-many scenario)?

  21. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jun 4, 2019
  22. chornbe commented on Jul 10, 2019

    @chornbe

    This feels a lot like the discussions when Swing was first introduced.

    Basically, what people WANT is the ability to say something like ( child: Text( “some text” ) ) and have the platform draw an OEM or OEM-ish textbox without thinking any more about it. When you build a material app you’re essentially agreeing to have the whole thing look like Android unless you take other actions. The DESIRE in the community is for it to look like the device’s native design language without taking extra steps.

    That’s hard. But that’s what people want. Adding class decoration or different types just makes for clunkier code, and IMO, should only be necessary when you really, really want to decorate something in a very particular way.

    For me and my company, we just say screw it... you get an Android-looking app while we continue to evaluate what Flutter really does for us that we can’t get with Native, beyond just the kitsch of saying we can work in Flutter. Which not one single customer has ever heard of (yet). :)

    The hope of “write once, run everywhere” is still very much in its youth because every time you blink, another new company, another new platform, another new “better idea” pops up, and now you’ve got to decide between Ionic, React Native (bleh), Trigger, Flutter, and... let’s see what’s next.

    Great goal. Competing platforms may drive platform enhancements and updates and innovations, but also further fragments the landscape.

    At least Flutter came from one of the big campuses, and it’s pretty much the only cross-platform tool that has. That’s power. I don’t see Apple ever building XCode for Android, and native Android development is akin to eating a live rattlesnake, so at the very least, Flutter brings WAY more approachability to “native”-enough development for Android. If nothing else ever comes of it in terms of cross-platform adoption, THAT ALONE is well, well worth the price of admission.

    $.02

  23. galeyang commented on Nov 5, 2019

    @galeyang

    Updated: this sign-up form has been closed. Thank you for your interests!


    Hello from the Flutter team!

    If you’re following this discussion, we are looking for a few Flutter developers to share their experience on developing Flutter apps that have a platform-specific look & feel for both iOS and Android.

    If you’re interested, please fill out this short questionnaire: [closed]

    Thank you very much for your help!

  24. github-actions commented on Aug 15, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  25. locked as resolved and limited conversation to collaborators on Aug 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: new featureNothing broken; request for a new capabilityframeworkflutter/packages/flutter repository. See also f: labels.p: cupertino_uicupertino_ui package in flutter/packagesp: material_uimaterial_ui package in flutter/packagesplatform-iosiOS applications specifically

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions