Flutter настраивает действия AppBar и передает AppBar и Body вместе родительскому элементу?

Я новичок в флаттере и пытаюсь создать приложение, в котором в качестве основного маршрута используется виджет с отслеживанием состояния TabScreen, содержащий Scaffold. Тело Scaffold строится на основе выбранного индекса из bottomNavigationBar, что отлично работает. Моя проблема — это управление действиями AppBar. AppBar должен иметь разные действия для каждого «основного экрана», но действия влияют на данные, которые находятся внутри разных основных экранов.

Например: внутри класса Screen1 у нас есть переменная List list1. Для Screen1 AppBar должен предоставить опцию Clear list1, чтобы удалить все элементы list1, но на Screen2 он должен предоставить опцию Clear Screen2 list.

Моя идея — создать новый класс AppBar, импортировать его в мои классы Screen1, Screen2, Screen3, а также создать и настроить appBars внутри этих экранов, как описано в это сообщение. Есть ли способ, как я могу определить не только тело, но и AppBar в моем классе Screen1 и вернуть их оба в родительский элемент TabScreen? Я думаю, что это было бы самым простым решением, но я не знаю, как это сделать лучше.

    class _TabScreenState extends State<TabScreen> {
    
    int _selectedPageIndex;

    final List<Map<String, Object>> _pages = [
        {
          'page': Screen1(),
          'title': 'Screen1',
        },
        {
          'page': Screen2(),
          'title': 'Screen2',
        },
        {
          'page': Screen3(),
          'title': 'Screen3',
        },
      ];
    
    @override
      Widget build(BuildContext context) {
    
    final appBar = AppBar(
          title: Text('Screen X'),
          actions: [
            PopupMenuButton(
              onSelected: (selectedValue) {
                setState(() {
                  if (selectedValue == 0) {
                    filterOn = true;
                    Provider.of<Screen1Data>(context, listen: false).clear();
                  } else {
                    Provider.of<Screen1Data>(context, listen: false).reset();
                    filterOn = false;
                  }
                });
              },
              icon: Icon(Icons.more_vert),
              itemBuilder: (_) => [
                PopupMenuItem(child: Text('Reset'), value: 0),
                PopupMenuItem(
                    child: Text('Clear List'), value: 1),
              ],
            ),
          ],
        );
    
    
    return Scaffold(
          appBar: appBar,
          body: _pages[_selectedPageIndex]['page'],
          bottomNavigationBar: bottomBar,
        ); 
}

Контент Screen1 может выглядеть так:

class Screen1 extends StatefulWidget {

  @override
  _Screen1State createState() => _Screen1State();
}

class _Screen1State extends State<Screen1> {
  List<String> list1;
  
  @override
  Widget build(BuildContext context) {
     return Text(list1[0]);
  }  

}

См. также:  phpMyAdmin показывает 404 Not Found (Ubuntu 18.04 Nginx)
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 1
  1. AtMakeIT

    Добавьте действия в _pages list:

    final List<Map<String, Object>> _pages = [
            {
              'page': Screen1(),
              'title': 'Screen1',
              'actions': <Widget>[/* List of actions for screen1 */] //<-- optional just in case you need default actions that depend on parent as well
            },
            {
              'page': Screen2(),
              'title': 'Screen2',
              'actions': <Widget>[/* List of actions for screen2 */] //<-- optional just in case you need default actions that depend on parent as well
            },
            {
              'page': Screen3(),
              'title': 'Screen3',
              'actions': <Widget>[/* List of actions for screen3 */] //<-- optional just in case you need default actions that depend on parent as well
            },
          ];
    

    Создайте функцию, которая создает настраиваемую панель приложения:

    AppBar _buildAppBar({String title, List<Widget> actions}) => AppBar(
      title = title,
      actions = actions,
    );
    

    Затем внутри каркаса вы создаете настраиваемые панели приложений для каждой страницы:

     return Scaffold(
              appBar: _buildAppBar(
                         title:  _pages[_selectedPageIndex]['title'],  
                         actions: _pages[_selectedPageIndex]['actions']
                         // or if you have specific actions that are only visible form this page you can do
                         actions: [
                           /* list of page1 only actions*/
    
                         ]
                         // or if you want to combine both default and specific actions you can do
                         actions: [
                           ... _pages[_selectedPageIndex]['actions'],
                           /* list of actions that are specific to page1*/
    
                         ]
                      ),
              body: _pages[_selectedPageIndex]['page'],
              bottomNavigationBar: bottomBar,
            ); 
    

    Теперь вы получите настраиваемую панель приложения на каждой странице, включая настраиваемые действия.

    Привет, Younss, спасибо за ответ! Но я не понимаю, как я должен определять действия внутри моего родительского класса, поскольку мой родительский класс не знает необходимых переменных, на которые следует влиять. Например: я не могу создать действие list1.add (‘hi’) в моем родительском элементе, поскольку list1 принадлежит классу _Screen1State. Или я что-то упускаю? person AtMakeIT; 30.04.2021

    _buildAppBar требовал список действий (виджетов). Если у вас есть определенные действия, которые не видны родителю, вы можете просто передать их функции. Я добавил ключ actions в список _pages только для демонстрации. Позвольте мне обновить ответ, чтобы уточнить;) проверьте обновленный ответ person AtMakeIT; 30.04.2021

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: