はじめに
最近Flutterを学んでいます。
今日はFlutterでサイドバーを作ってみました。
公式にて一つのサイドバーを紹介していますが、少し変わり種のサイドバーも紹介しようと思います。
サイドバー2選
1つ目
1つ目はよくあるサイドバーの紹介です。
以下の動画をご覧ください。
左上のMenuボタンを押下することで左側からサイドバーが出現します。
ソースはこちらから
import 'package:flutter/material.dart';
void main() {
runApp(const MenuTestPage());
}
class MenuTestPage extends StatelessWidget {
const MenuTestPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Drawer Test Page'),
),
body: Center(
child: Text('Hey!'),
),
drawer: Drawer(
child: ListView(
children: [
DrawerHeader(
decoration: BoxDecoration(color: Colors.lightBlue),
child: Text('Test App'),
),
ListTile(
title: Text('item1'),
onTap: () {},
),
ListTile(
title: Text('item2'),
onTap: () {},
),
],
),
),
);
}
}
使用しているWidgetまとめ
Drawer
サイドバーを出現させるためのWidget。
ListViewと組み合わせてサイドバーのメニューを表示させるのが一般的な使い方みたい。
ListView
スクロールウィジェットである。
スクロール方向に無限数だけ表示させることができるみたい。
2つ目
2つ目はちょっとイカしたUIのサイドバーです。
こちらは左上のMenuボタンを押下することでアニメーションのように左からスーッとサイドバーが出現してきます。
import 'package:flutter/material.dart';
class MenuDashboardPage extends StatefulWidget {
const MenuDashboardPage({Key? key}) : super(key: key);
@override
State<MenuDashboardPage> createState() => _MenuDashboardPageState();
}
class _MenuDashboardPageState extends State<MenuDashboardPage> {
bool isCollapsed = true;
double screenWidth = 0, screenHeight = 0;
final Duration duration = const Duration(milliseconds: 300);
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
screenHeight = size.height;
screenWidth = size.width;
return Scaffold(
backgroundColor: Colors.blueGrey[600],
body: Stack(
children: <Widget>[
menu(),
dashboard(context),
],
),
);
}
Widget dashboard(context) {
return AnimatedPositioned(
duration: duration,
top: isCollapsed ? 0 : 0.2 * screenHeight,
bottom: isCollapsed ? 0 : 0.05 * screenWidth,
left: isCollapsed ? 0 : 0.6 * screenWidth,
right: isCollapsed ? 0 : -0.4 * screenWidth,
child: Material(
animationDuration: duration,
borderRadius: BorderRadius.all(Radius.circular(40)),
elevation: 8,
color: Colors.blueGrey[600],
child: Container(
padding: EdgeInsets.only(left: 16, right: 16, top: 48),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
InkWell(
onTap: () {
setState(() {
isCollapsed = !isCollapsed;
});
},
child: Icon(
Icons.menu,
color: Colors.white,
),
),
Text(
'My Cards',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
Icon(
Icons.settings,
color: Colors.white,
),
],
),
SizedBox(
height: 50,
),
Container(
height: 200,
child: PageView(
controller: PageController(viewportFraction: 0.8),
scrollDirection: Axis.horizontal,
pageSnapping: true,
children: [
Container(
margin: EdgeInsets.symmetric(
horizontal: 8,
),
color: Colors.redAccent,
width: 100,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 8,
),
color: Colors.blueAccent,
width: 100,
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 8,
),
color: Colors.greenAccent,
width: 100,
),
],
),
),
],
),
),
),
);
}
Widget menu() {
return Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Align(
alignment: Alignment.centerLeft,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Dashboard',
style: TextStyle(color: Colors.white, fontSize: 22),
),
SizedBox(
height: 10.0,
),
Text(
'Messages',
style: TextStyle(color: Colors.white, fontSize: 22),
),
SizedBox(
height: 10.0,
),
Text(
'Utility Bills',
style: TextStyle(color: Colors.white, fontSize: 22),
),
SizedBox(
height: 10.0,
),
Text(
'Funds Transfer',
style: TextStyle(color: Colors.white, fontSize: 22),
),
SizedBox(
height: 10.0,
),
Text(
'Branches',
style: TextStyle(color: Colors.white, fontSize: 22),
),
],
),
),
);
}
}
使用しているWidgetまとめ
AnimatedPositioned
指定した子コンポーネントのポジションを移動させる。(top, bottom, left, rightで指定が可能)
Stackとの組み合わせで使用する必要がある。
InkWell
このウィジェットでラップしたウィジェットをいい感じのボタンに変更するイメージ。
onTapなどでイベントの設定もすることが可能
コメント