Всплывающая нижняя панель навигации — вопрос для лучшей практики

#flutter #navigation

#трепетание #навигация

Вопрос:

Я довольно новичок в Flutter. Я хочу разработать приложение с нижней панелью навигации. Но я действительно не знаю, каков наилучший способ навигации. Я создал пользовательскую версию этого руководства: https://medium.com/flutter/getting-to-the-bottom-of-navigation-in-flutter-b3e440b9386

То, что я делал до сих пор, было:

  • Создан основной виджет с каркасом с нижней панелью навигации
  • Каждый раз, когда индекс меняется, я изменяю дочернее свойство каркаса
 void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: MainWidget()
    );
  }
}

/// This is the stateful widget that the main application instantiates.
class MainWidget extends StatefulWidget {
  @override
  _MainWidgetState createState() => _MainWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
class _MainWidgetState extends State<MainWidget> {

  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
            top: false,
            child: IndexedStack(
              index: _selectedIndex,
              children: allDestinations.map<Widget>((Destination destination) {
                return DestinationView(destination: destination);
              }).toList(),
            )
        ),
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          selectedItemColor: Colors.blue,
          currentIndex: _selectedIndex,
          onTap: (int index) {
            setState(() {
              _selectedIndex = index;
            });
          },
          items: allDestinations.map((Destination destination) {
            return BottomNavigationBarItem(
                icon: Icon(destination.icon),
                label: destination.title
            );
          }).toList(),
        )
    );
  }
}

enum DestinationType {
  Page1,
  Page2,
  Page3,
  Page4,
  Page5
}

class Destination {
  const Destination(this.type, this.title, this.icon);
  final DestinationType type;
  final String title;
  final IconData icon;
}

const List<Destination> allDestinations = <Destination>[
  Destination(DestinationType.Page1, 'Page1', Icons.lightbulb),
  Destination(DestinationType.Page2, 'Page2', Icons.search),
  Destination(DestinationType.Page3, 'Page3', Icons.attach_money),
  Destination(DestinationType.Page4, 'Page4', Icons.calendar_today_outlined),
  Destination(DestinationType.Page5, 'Page5', Icons.settings)
];
  
  • Я возвращаю DestinationView, где я проверяю, какой пункт назначения должен быть создан.
 class DestinationView extends StatefulWidget {
  const DestinationView({Key key, this.destination}) : super(key: key);

  final Destination destination;

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

class _DestinationViewState extends State<DestinationView> {
  @override
  Widget build(BuildContext context) {
    switch (widget.destination.type) {
      case DestinationType.Page1:
        return Page1Destination(destination: widget.destination);
      case DestinationType.Page2:
        return Page2Destination(destination: widget.destination);
      case DestinationType.Page3:
        return Page3();
      case DestinationType.Page4:
        return Page4();
      case DestinationType.Page5:
        return Page5();
    }
  }
}
  
  • Если у меня есть часть, в которой я хочу иметь навигацию только в этой части, я создаю навигатор и определяю маршруты:
 class Page1Destination extends StatefulWidget {
  const Page1Destination({Key key, this.destination}) : super(key: key);

  final Destination destination;

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

class _Page1DestinationState extends State<Page1Destination> {
  @override
  Widget build(BuildContext context) {
    return Navigator(
      onGenerateRoute: (RouteSettings settings) {
        return MaterialPageRoute(
          settings: settings,
          builder: (BuildContext context) {
            switch(settings.name) {
              case '/':
                return Page1Home(destination: widget.destination);
              case '/list':
                return Page1List();
              case '/settings':
                return Page1Settings(destination: widget.destination);
            }
          },
        );
      },
    );
  }
}
  
  • Внутри этих виджетов я использую Navigator.pushNamed и так далее.
  • Если вкладка / страница представляет собой только один виджет. Я возвращаю только обычный виджет без каких-либо маршрутов.
  • Но если вы хотите вызвать виджет на странице 1 с маршрутом / списком и параметром с другой страницы. Я не знаю, как это сделать.

Я почти уверен, что есть лучший способ справиться с такой навигацией. Так что, может быть, кто-нибудь из вас знает, как я могу создать лучший навигационный обработчик.