Рельс навигационный с флаттером

Рекомендации по материальному дизайну включают компонент под названием Navigation rail.

Как создать навигатор с флаттером?

введите описание изображения здесь


person Darish    schedule 07.05.2020    source источник


Ответы (5)


Последняя версия Flutter 1.17 включает встроенный компонент NavigationRail.

Что такое навигационный рельс?

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

Пример

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  MyStatefulWidget({Key key}) : super(key: key);

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

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: <Widget>[
          NavigationRail(
            selectedIndex: _selectedIndex,
            onDestinationSelected: (int index) {
              setState(() {
                _selectedIndex = index;
              });
            },
            labelType: NavigationRailLabelType.selected,
            destinations: [
              NavigationRailDestination(
                icon: Icon(Icons.favorite_border),
                selectedIcon: Icon(Icons.favorite),
                label: Text('First'),
              ),
              NavigationRailDestination(
                icon: Icon(Icons.bookmark_border),
                selectedIcon: Icon(Icons.book),
                label: Text('Second'),
              ),
              NavigationRailDestination(
                icon: Icon(Icons.star_border),
                selectedIcon: Icon(Icons.star),
                label: Text('Third'),
              ),
            ],
          ),
          VerticalDivider(thickness: 1, width: 1),
          // This is the main content.
          Expanded(
            child: Center(
              child: Text('selectedIndex: $_selectedIndex'),
            ),
          )
        ],
      ),
    );
  }
}

Найдите живую демонстрацию здесь.

Вот официальная документация.

person Darish    schedule 07.05.2020

Он был выпущен 7 мая 2020 года вместе с Flutter 1.17 выпуск. Быстрый поиск по запросу "флаттер навигационного рельса" сделали свое дело.

Документация включает живую демонстрацию и пример кода.

int _selectedIndex = 0;

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     body: Row(
       children: <Widget>[
         NavigationRail(
           selectedIndex: _selectedIndex,
           onDestinationSelected: (int index) {
             setState(() {
               _selectedIndex = index;
             });
           },
           labelType: NavigationRailLabelType.selected,
           destinations: [
             NavigationRailDestination(
               icon: Icon(Icons.favorite_border),
               selectedIcon: Icon(Icons.favorite),
               label: Text('First'),
             ),
             NavigationRailDestination(
               icon: Icon(Icons.bookmark_border),
               selectedIcon: Icon(Icons.book),
               label: Text('Second'),
             ),
             NavigationRailDestination(
               icon: Icon(Icons.star_border),
               selectedIcon: Icon(Icons.star),
               label: Text('Third'),
             ),
           ],
         ),
         VerticalDivider(thickness: 1, width: 1),
         // This is the main content.
         Expanded(
           child: Center(
             child: Text('selectedIndex: $_selectedIndex'),
           ),
         )
       ],
     ),
   );
 }


Для обновления запустите flutter upgrade, который загрузит последнюю версию с github.

person Ben Butterworth    schedule 07.05.2020

NavigationRail

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

ОБРАЗЕЦ КОДА

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      debugShowCheckedModeBanner: false,
      home: HomeWidget(),
    );
  }
}

class HomeWidget extends StatefulWidget {
  HomeWidget({Key key}) : super(key: key);

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

class _HomeWidgetState extends State<HomeWidget> {
  int _selectedIndex = 0;
  bool showNavigationBar = false;

  var list = [
    HomePage(),
    WalkPage(),
    LocationPage(),
    NotificationPage(),
    SettingsPage(),
    SearchPage()
  ];

  var title = [
    "HomePage",
    'WalkPage',
    'LocationPage',
    'NotificationPage',
    'SettingsPage',
    'SearchPage'
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title[_selectedIndex]),
        centerTitle: false,
        leading: IconButton(
            icon: Icon(
              Icons.menu,
              color: Colors.white,
            ),
            onPressed: () {
              setState(() {
                showNavigationBar = !showNavigationBar;
              });
            }),
      ),
      body: Container(
        child: SafeArea(
            child: Stack(
          children: <Widget>[
            list[_selectedIndex],
            Positioned(
              top: 0,
              left: 0,
              child: Visibility(
                visible: showNavigationBar,
                child: Container(
                  height: MediaQuery.of(context).size.height,
                  child: NavigationRail(
                    selectedIndex: _selectedIndex,
                    elevation: 10,
                    backgroundColor: Colors.white,
                    leading: Container(
                      child: Center(child: Text('leading')),
                    ),
                    trailing: Container(
                      child: Center(child: Text('trailing')),
                    ),
                    selectedIconTheme: IconThemeData(color: Colors.purple, size: 30),
                    unselectedIconTheme: IconThemeData(color: Colors.grey, size: 20),
                    selectedLabelTextStyle:
                        TextStyle(color: Colors.purple, fontWeight: FontWeight.bold),
                    unselectedLabelTextStyle:
                        TextStyle(color: Colors.grey, fontWeight: FontWeight.normal),
                    onDestinationSelected: (int index) {
                      setState(() {
                        _selectedIndex = index;
                        showNavigationBar = !showNavigationBar;
                      });
                    },
                    labelType: NavigationRailLabelType.none,
                    destinations: [
                      NavigationRailDestination(
                        icon: Icon(Icons.home),
                        selectedIcon: Icon(Icons.home),
                        label: Text('Home'),
                      ),
                      NavigationRailDestination(
                        icon: Icon(Icons.directions_walk),
                        selectedIcon: Icon(Icons.directions_walk),
                        label: Text('Walk'),
                      ),
                      NavigationRailDestination(
                        icon: Icon(Icons.location_on),
                        selectedIcon: Icon(Icons.location_on),
                        label: Text('Location'),
                      ),
                      NavigationRailDestination(
                        icon: Icon(Icons.notifications),
                        selectedIcon: Icon(Icons.notifications),
                        label: Text('Notifications'),
                      ),
                      NavigationRailDestination(
                        icon: Icon(Icons.settings),
                        selectedIcon: Icon(Icons.settings),
                        label: Text('Settings'),
                      ),
                      NavigationRailDestination(
                        icon: Icon(Icons.search),
                        selectedIcon: Icon(Icons.search),
                        label: Text('Search'),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ],
        )),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: Center(
          child: Text('Home Page',
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0))),
    );
  }
}

class WalkPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      child: Center(
          child: Text('Walk Page',
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0))),
    );
  }
}

class LocationPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.orange,
      child: Center(
          child: Text('Location Page',
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0))),
    );
  }
}

class NotificationPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.green,
      child: Center(
          child: Text('Notification Page',
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0))),
    );
  }
}

class SettingsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.amber,
      child: Center(
          child: Text('Settings Page',
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0))),
    );
  }
}

class SearchPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.teal,
      child: Center(
          child: Text('Search Page',
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0))),
    );
  }
}

Давайте разберемся с некоторыми из его важных свойств

selectedIndex - указатель мест назначения для текущего выбранного NavigationRailDestination.

selectedIconTheme - визуальные свойства значка в выбранном месте назначения.

unselectedIconTheme - визуальные свойства значка в невыбранном месте назначения.

selectedLabelTextStyle - текстовый стиль метки места назначения, когда он выбран.

unselectedLabelTextStyle - текстовый стиль метки места назначения, когда он не выбран.

backgroundColor - устанавливает цвет контейнера, в котором находится все содержимое NavigationRail.

leading - ведущий виджет на направляющей, который размещается над пунктами назначения.

trailing - конечный виджет на направляющей, который размещается под пунктами назначения.

labelType

  1. labelType: NavigationRailLabelType.all,
  2. labelType: NavigationRailLabelType.selected,
  3. labelType: NavigationRailLabelType.none,

ВЫХОД

введите описание изображения здесь

Для получения дополнительной информации прочтите документацию по NavigationRail

Вы можете протестировать живую демонстрацию здесь, на демонстрацию NavigationRail

person AskNilesh    schedule 08.06.2020

Примечание. Панель навигации предназначена для макетов с широкими окнами просмотра, таких как горизонтальная ориентация в Интернете на настольном компьютере или планшете. Для небольших макетов, таких как мобильный портрет, следует использовать BottomNavigationBar.

int _index = 0;

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Row(
      children: <Widget>[
        NavigationRail(
          selectedIndex: _index,
          onDestinationSelected: (index) => setState(() => _index = index),
          extended: true,
          destinations: [
            NavigationRailDestination(
              icon: Icon(Icons.favorite_border),
              label: Text('First'),
            ),
            NavigationRailDestination(
              icon: Icon(Icons.bookmark_border),
              label: Text('Second'),
            ),
            NavigationRailDestination(
              icon: Icon(Icons.star_border),
              label: Text('Third'),
            ),
          ],
        ),
        // This is the main content.
        Expanded(child: Center(child: Text('Index: $_index')))
      ],
    ),
  );
}
person iDecode    schedule 10.05.2020

NavigationRail выглядит аккуратно. Но я заметил, что нет способа сохранить состояние виджета, чтобы оно всегда воссоздавалось. Даже AutomaticKeepAliveClientMixin не работает.

person chitgoks    schedule 16.07.2021