Есть ли способ иметь аргумент с двумя типами в дартс? - PullRequest
0 голосов
/ 10 ноября 2018

Для навигации я создал простой фабричный класс, который генерирует ListTile, который проталкивает маршрут к навигатору:

static Widget simpleNavRow(String text, BuildContext context, String route) {
  return Column(
    children: <Widget>[
      ListTile(
        title: Text(text),
        onTap: () {
          Navigator.pushNamed(context, route);
        },
      ),
      Divider(),
    ],
  );
}

Однако вскоре я понял, что было бы удобно также поддерживать push-виджеты (или создать экземпляр из своего класса, если это возможно).Я не мог понять, как заставить аргумент «route» принимать либо String, либо Widget, поэтому я создал класс, который инициализируется одним из этих двух типов.Этот код работает, но есть ли лучший способ добиться этого?

class NavTo {
  String route;
  Widget widget;

  NavTo.route(this.route);
  NavTo.widget(this.widget);

  push(BuildContext context) {
    if (route != null) {
      Navigator.pushNamed(context, route);
    }
    if (widget != null) {
      Navigator.push(context, MaterialPageRoute(builder: (context) {
        return widget;
      }));
    }
  }
}

class ListHelper {
  static final padding = EdgeInsets.all(12.0);

  static Widget simpleNavRow(String text, BuildContext context, NavTo navTo) {
    return Column(
      children: <Widget>[
        ListTile(
          title: Text(text),
          onTap: () {
            navTo.push(context);
          },
        ),
        Divider(),
      ],
    );
  }
}

// usage:
// ListHelper.simpleNavRow('MyWidget', context, NavTo.widget(MyWidget()))

Ответы [ 3 ]

0 голосов
/ 10 ноября 2018

Я не верю, что тип союзов доступен в Dart. Мне нравится ваше решение по использованию динамического, поскольку оно строго типизировано. Вы можете использовать именованные параметры.

NavTo({this.route,this.widget})

Но тогда у вас не будет проверки типа компиляции для одного и только одного параметра.

Единственное улучшение, которое я бы сделал для ваших конструкторов, это добавление @required.

0 голосов
/ 11 ноября 2018

Лично я хотел бы дать Предметам параметры MaterialPageRoute

static Widget simpleNavRow(String text, BuildContext context, MaterialPageRoute route) {
 return Column(
   children: <Widget>[
     ListTile(
      title: Text(text),
      onTap: () {
        Navigator.push(context, route);
      },
     ),
    Divider(),
  ],);
}

элементы остаются такими же глупыми, и я решаю, что они делают в родительском. После того, как вы сможете создать фабрику предметов для каждого имеющегося у вас типа, инициализируйте правильный маршрут следующим образом:

class ItemExemple extends StatelessWidget {

final String text;
final MaterialPageRoute route;

ItemExemple(this.text, this.route);

factory ItemExemple.typeA(String text, BuildContext context) =>
  new ItemExemple(text, new MaterialPageRoute(builder: (context) => new   ItemA()));

factory ItemExemple.typeB(String text, BuildContext context) =>
  new ItemExemple(text, new MaterialPageRoute(builder: (context) => new ItemB()));

@override
Widget build(BuildContext context) {
  return Column(
    children: <Widget>[
      ListTile(
        title: Text(this.text),
        onTap: () {
          Navigator.push(context, route);
        },
      ),
      Divider(),
    ],);
}

}
0 голосов
/ 10 ноября 2018

Так как вы ожидаете один из нескольких типов, как насчет dynamic, а затем в методе push NavTo, вы можете проверить тип:

class NavTo {
  dynamic route;

  push(BuildContext context) {
    if (route is String) {
       ...
    } else if (route is Widget) {
       ...
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...