Flutter Material to Cupertino transformation issues

Issue

I am working on a project which is almost 80% done. All my project is done on Material design. Now I am trying to move Cupertino UI theme for Android and IOS both.

As I am trying to migrate from Material design to Cupertino UI I am facing lots of problems especially in the below areas..

  1. TextFormField: I am not able to find TextFormField in Cupertino design to use with forms…
  2. Validator: How to valide CupertinoTextField as there is no validator method
  3. App Drawer: Right now I have App Drawer. As I am moving to Cuprtino UI design for both IOS and Android should I drop the App Drawer?
  4. How can I give the width of the CupertinoButton ?
  5. ListTitle is throwing exception when I am trying to migrate to Cuprtio. The exception is “The specific widget that could not find a Material ancestor was: ListTitle”

Also, How can I mix a non Cuprtino widget on inside CupertinoPageScaffold page?

Thanks for your time

Solution

  1. TextFormField: I am not able to find TextFormField in Cupertino design to use with forms…
  2. Validator: How to valide CupertinoTextField as there is no validator method

There’s no TextField with validation & form methods in Cupertino. In iOS development, you would write your own form validation code and call them accordingly. It is no exception in Flutter as well.
One typical approach would be creating an inner _FormData class to store your TextEditingController for every CupertinoTextField, then validate them in your CupertinoButton‘s onPressed callback.

  1. App Drawer: Right now I have App Drawer. As I am moving to Cuprtino UI design for both IOS and Android should I drop the App Drawer?

Again, Drawer widget only exists in Material design. All drawers that you might be seeing in various iOS apps in the market are custom UIViews made by 3rd party providers. Apple Human Interface Guidelines clearly stated that:

Avoid using drawers. Drawers are seldom used in modern apps and their use is discouraged. Panels, popovers, sidebars, and split views are preferred for displaying supplementary window content.

You might want to consider using CupertinoPageScaffold or CupertinoTabScaffold, depending on your design requirements.

  1. How can I give the width of the CupertinoButton ?

You can wrap your CupertinoButton with Container, SizedBox or FractionallySizedBox.

Container(
    width: 300 // or whatever width you want,
    child: CupertinoButton(
        child: Text('Submit'),
        color: Theme.of(context).primaryColor,
        onPressed: () {
            // Write your callback here
        },
    ),
)

or

SizedBox(
    width: 300 // or whatever you want,
    child: CupertinoButton(
        child: Text('Submit'),
        color: Theme.of(context).primaryColor,
        onPressed: () {
            // Write your callback here
        },
    ),
)

or

FractionallySizedBox(
    widthFactor: 0.5 // or whatever you want,
    child: CupertinoButton(
        child: Text('Submit'),
        color: Theme.of(context).primaryColor,
        onPressed: () {
            // Write your callback here
        },
    ),
)

In general, Container should do the trick. If you wrap your CupertinoButton in a Flex widget (such as ListView, Column), you might want to use SizedBox or FractionallySizedBox. You may refer to API documentation of SizedBox and FractionallySizedBox

  1. ListTitle is throwing exception when I am trying to migrate to Cuprtio. The exception is “The specific widget that could not find a Material ancestor was: ListTitle”

As the error log says:

In material design, most widgets are conceptually “printed” on a sheet of material. In Flutter’s material library, that material is represented by the Material Widget. It is the Material widget that renders ink splashes, for instance. Because of this, many material library widgets require that there be a Material widget in the tree above them.
To introduce a Material widget, you can either directly include one, or use a widget that contains Material itself, such as a Card, Dialog, Drawer, or Scaffold.

I guess you are trying to use ListTile (which is a Material widget) in a CupertinoPageScaffold or CupertinoTabView, which are obviously Cupertino widgets. This is how I solved it:

Material(
    type: MaterialType.transparency,
    child: ListTile(
        ...
    )
)

Answered By – Ken Tan

Answer Checked By – Gilberto Lyons (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *