Вы можете просто использовать ListView для управления 17 вариантами навигации. Оберните это ListView
внутри столбца . ListView
будет первым потомком Column
второго потомка, поэтому размещение внизу будет вашим выходом из системы.
Если вы используете прозрачные виджеты (например, ListTile ) внутри ListView
для отображения параметров навигации, вы можете просто обернуть их внутри Контейнера . Container
, помимо многих других виджетов, позволяет вам установить новый цвет фона с его атрибутом color
.
При таком подходе дерево виджетов будет выглядеть следующим образом:
- Column // Column to place your LogutButton always below the ListView
- ListView // ListView to wrap all your navigation scrollable
- Container // Container for setting the color to green
- GreenNavigation
- Container
- GreenNavigation
- Navigation
- Navigation
- ...
- LogOutButton
Обновление 1 - Sticky LogOutButton:
Для достижения LogOutButton
прилипания к концу ListView
вам необходимо сделать две вещи:
- Заменить Расширенный на Гибкий
- Набор
shrinkWrap: true
внутри ListView
Обновление 2 - интервал LogOutButton до большого списка:
Достижение описанного поведения - более сложный шаг. Вам нужно проверить, превышает ли ListView
экран и можно ли его прокручивать.
Для этого я написал короткий фрагмент:
bool isListLarge() {
return controller.positions.isNotEmpty && physics.shouldAcceptUserOffset(controller.position);
}
Он вернет true, если ListView
превысит свои ограничения. Теперь мы можем обновить состояние просмотра в зависимости от результата isListViewLarge
. Ниже снова полный пример кода.
Пример автономного кода ( Обновление 2: интервал LogOutButton до большого списка ):
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
drawer: MyDrawer(),
),
);
}
}
class MyDrawer extends StatefulWidget {
@override
_MyDrawerState createState() => _MyDrawerState();
}
class _MyDrawerState extends State<MyDrawer> {
ScrollController controller = ScrollController();
ScrollPhysics physics = ScrollPhysics();
int entries = 4;
@override
Widget build(BuildContext context) {
Widget logout = IconButton(
icon: Icon(Icons.exit_to_app),
onPressed: () => {setState(() => entries += 4)});
List<Widget> navigationEntries = List<int>.generate(entries, (i) => i)
.map<Widget>((i) => ListTile(
title: Text(i.toString()),
))
.toList();
if (this.isListLarge()) { // if the List is large, add the logout to the scrollable list
navigationEntries.add(logout);
}
return Drawer(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, // place the logout at the end of the drawer
children: <Widget>[
Flexible(
child: ListView(
controller: controller,
physics: physics,
shrinkWrap: true,
children: navigationEntries,
),
),
this.isListLarge() ? Container() : logout // if the List is small, add the logout at the end of the drawer
],
),
);
}
bool isListLarge() {
return controller.positions.isNotEmpty && physics.shouldAcceptUserOffset(controller.position);
}
}
Пример автономного кода ( Обновление 1: Sticky LogOutButton ):
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
drawer: MyDrawer(),
),
);
}
}
class MyDrawer extends StatefulWidget {
@override
_MyDrawerState createState() => _MyDrawerState();
}
class _MyDrawerState extends State<MyDrawer> {
int entries = 4;
@override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: <Widget>[
Flexible(
child: ListView(
shrinkWrap: true,
children: List<int>.generate(entries, (i) => i)
.map((i) => ListTile(
title: Text(i.toString()),
))
.toList(),
),
),
IconButton(
icon: Icon(Icons.exit_to_app),
onPressed: () => {setState(() => entries += 4)})
],
),
);
}
}
Пример автономного кода ( Старый: прилипание к низу ):
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
drawer: MyDrawer(),
),
);
}
}
class MyDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: <Widget>[
Expanded(
child: ListView(
children: List<int>.generate(40, (i) => i + 1)
.map((i) => ListTile(
title: Text(i.toString()),
))
.toList(),
),
),
IconButton(icon: Icon(Icons.exit_to_app), onPressed: () => {})
],
),
);
}
}