Как эмулировать Android showAsAction = "ifRoom" в Flutter? - PullRequest
4 голосов
/ 30 марта 2019

В моем приложении Flutter у меня есть экран, который представляет собой MaterialApp с виджетом Scaffold, когда он дома.

Свойство appBar этого Scaffold представляет собой виджет AppBar со свойством actions, заполненным некоторыми действиями, и всплывающим меню для размещения остальных параметров.

Дело в том, что, как я понимаю, дочерний элемент списка AppBar actions может быть либо общим виджетом (он будет добавлен как действие), либо экземпляром PopupMenuButton, и в этом случае он добавит платформу, специфичную для конкретной платформы. значок, который при запуске открывает всплывающее меню AppBar.

На родном Android это не так. Мне просто нужно надуть меню, заполненное пунктами меню, и каждый элемент может быть либо принудительным действием, либо НЕ иметь действия, либо иметь специальное значение «ifRoom», которое означает «быть действием, если есть место, в противном случае элемент внутри всплывающего меню ".

Есть ли способ во Флаттере иметь такое поведение без необходимости писать сложную логику для заполнения свойства "actions" AppBar?

Я изучил документацию AppBar и PopupMenuButton, и пока ничего не объясняет, как это сделать. Я мог бы смоделировать поведение, но тогда мне пришлось бы на самом деле написать процедуру для вычисления доступного пространства и соответственно создать список «действий».

Вот типичное Android-меню, которое смешивает действия и пункты всплывающего меню. Обратите внимание, что запись «load_game» может быть действием, если есть место, и станет пунктом меню, если нет.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:icon="@drawable/ic_new_game"
          android:title="@string/new_game"
          android:showAsAction="always"/>
    <item android:id="@+id/load_game"
          android:icon="@drawable/ic_load_game"
          android:title="@string/load_game"
          android:showAsAction="ifRoom"/>
    <item android:id="@+id/help"
          android:icon="@drawable/ic_help"
          android:title="@string/help"
          android:showAsAction="never" />
</menu>

С другой стороны, во Флаттере я должен заранее решить, будут ли опции действием или пунктом меню.

AppBar(
  title: Text("My Incredible Game"),
  primary: true,
  actions: <Widget>[
    IconButton(
      icon: Icon(Icons.add),
      tooltip: "New Game",
      onPressed: null,
    ),
    IconButton(
      icon: Icon(Icons.cloud_upload),
      tooltip: "Load Game",
      onPressed: null,
    ),
    PopupMenuButton(
      itemBuilder: (BuildContext context) {
        return <PopupMenuEntry>[
          PopupMenuItem(
            child: Text("Help"),
          ),
        ];
      },
    )
  ],
)

Я надеялся, что сработает то, что AppBar фактически имеет только одно свойство «action» вместо «actions». Это свойство было бы просто виджетом, позволяющим мне иметь что-либо, поэтому, если бы я хотел просто список действий, то строки, заполненной IconButton, было бы достаточно.

Наряду с этим каждый PopupMenuItem внутри PopupMenuButton будет иметь свойство showAsAction. Если один или несколько объектов PopupMenuItem внутри PopupMenuButton были отмечены как действие или «ifRoom» и в них есть место, то PopupMenuButton будет развернут по горизонтали и поместит эти элементы как действия.

...