Flutter Material 到 Cupertino 的转换问题

Flutter Material to Cupertino transformation issues

我正在做一个项目,几乎完成了 80%。我所有的项目都是在 Material 设计上完成的。现在我正在尝试为 Android 和 IOS 移动 Cupertino UI 主题。

当我尝试从 Material 设计迁移到 Cupertino UI 时,我面临很多问题,尤其是在以下方面..

  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"

此外,如何在 CupertinoPageScaffold 页面内部混合使用非 Cuprtino 小部件?

感谢您的宝贵时间

  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

Cupertino 中没有 TextField 验证和表单方法。在 iOS 开发中,您将编写自己的表单验证代码并相应地调用它们。 Flutter 也不例外。 一种典型的方法是创建一个内部 _FormData class 来存储每个 CupertinoTextFieldTextEditingController,然后在 CupertinoButtononPressed 中验证它们]回调。

  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?

同样,Drawer 小部件仅存在于 Material 设计中。您可能在市场上的各种 iOS 应用程序中看到的所有抽屉都是由第 3 方提供商定制的 UIViewApple Human Interface Guidelines明确指出:

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.

您可能需要考虑使用 CupertinoPageScaffoldCupertinoTabScaffold,具体取决于您的设计要求。

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

您可以将 CupertinoButton 换成 ContainerSizedBoxFractionallySizedBox

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

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

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

一般来说,Container 应该可以。如果您将 CupertinoButton 包装在 Flex 小部件中(例如 ListViewColumn),您可能需要使用 SizedBoxFractionallySizedBox。您可以参考 SizedBox and FractionallySizedBox

的 API 文档
  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"

正如错误日志所说:

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.

我猜你正试图在 CupertinoPageScaffoldCupertinoTabView 中使用 ListTile(这是一个 Material 小部件),这显然是 Cupertino 小部件。我是这样解决的:

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