Contents
Add a Drawer to a screen
マテリアルデザインを使用するアプリでは、ナビゲーションに2つの主要なオプションがあります。
タブ(Tab)と(Drawer)ドロワーです。
タブを表示するのに十分なスペースがない場合、ドロワーは便利な代替手段を提供します。
Flutterで、DrawerウィジェットをScaffoldと組み合わせて使用して、MaterialDesignドロワーでレイアウトを作成します。 このレシピでは、次の手順を使用します。
- scaffoldを生成する。
- drawerを追加する。
- ドロワーにアイテムを追加する。
- プログラミングによりドロワーを閉じる。
1. Create a Scaffold
アプリにドロワーを追加するには、それをScaffoldウィジェットでラップします。
Scaffoldウィジェットは、マテリアルデザインガイドラインに準拠するアプリに一貫した視覚的構造を提供します。
また、ドロワー、AppBars、SnackBarsなどの特別なマテリアルデザインコンポーネントもサポートしています。
この例では、Drawer付きのScaffoldを作成します。
Scaffold(
drawer: // Add a Drawer here in the next step.
);
2. Add a drawer
次に、ScaffoldにDrawerを追加します。 Drawerはどのウィジェットでもかまいませんが、マテリアルデザインの仕様に準拠しているマテリアルライブラリのDrawerウィジェットを使用するのが最適な場合がよくあります。
Scaffold(
drawer: Drawer(
child: // Populate the Drawer in the next step.
)
);
3. Populate the drawer with items
ドロワーが配置されたので、それにコンテンツを追加します。 この例では、ListViewを使用します。
Columnウィジェットを使用することもできますが、リストビュー(ListView)は、コンテンツが画面でサポートされているよりも多くのスペースを占める場合にユーザーがドロワーをスクロールできるため便利です。
ListViewの子ウィジェットとして、DrawerHeaderウィジェットとListTileウィジェットを配置しています。リストについてさらに学びたい場合list recipesをご覧ください。
Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// 重要: ListViewからPaddingを排除してください.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
// Update the state of the app.
// ...
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
// Update the state of the app.
// ...
},
),
],
),
);
ユーザーがアイテムをタップした後、ドロワーを閉じたい場合があります。 Navigator(ナビゲーター)を使用してこれを行うことができます。
ユーザーがドロワーを開くと、Flutterはドロワーをナビゲーションスタックに追加します。 したがって、ドロワーを閉じるには、Navigator.pop(context)を呼び出します。
ListTile(
title: Text('Item 1'),
onTap: () {
// Update the state of the app.
// ...
// Then close the drawer.
Navigator.pop(context);
},
),
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final appTitle = 'Drawer Demo'; @override Widget build(BuildContext context) { return MaterialApp( title: appTitle, home: MyHomePage(title: appTitle), ); } } class MyHomePage extends StatelessWidget { final String title; MyHomePage({Key key, this.title}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(title)), body: Center(child: Text('My Page!')), drawer: Drawer( // Add a ListView to the drawer. This ensures the user can scroll // through the options in the drawer if there isn't enough vertical // space to fit everything. child: ListView( // Important: Remove any padding from the ListView. padding: EdgeInsets.zero, children: <Widget>[ DrawerHeader( child: Text('Drawer Header'), decoration: BoxDecoration( color: Colors.blue, ), ), ListTile( title: Text('Item 1'), onTap: () { // Update the state of the app // ... // Then close the drawer Navigator.pop(context); }, ), ListTile( title: Text('Item 2'), onTap: () { // Update the state of the app // ... // Then close the drawer Navigator.pop(context); }, ), ], ), ), ); } }
以上です。シンプルですね。いいですね。
このサンプルではドロワーのアイテムをタップすると元のページに戻る(ドロワーが閉じる)例ですが、アイテムをタップすると別のページにページ遷移するようなドロワーも考えられますね。はい。
上の説明でendDrawerフィールドの説明有り。
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final appTitle = 'Drawer Demo'; @override Widget build(BuildContext context) { return MaterialApp( title: appTitle, home: MyHomePage(title: appTitle), ); } } class MyHomePage extends StatelessWidget { final String title; MyHomePage({Key key, this.title}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(title)), body: Center(child: Text('My Page!')), drawer: Drawer( // Add a ListView to the drawer. This ensures the user can scroll // through the options in the drawer if there isn't enough vertical // space to fit everything. child: ListView( // Important: Remove any padding from the ListView. padding: EdgeInsets.zero, children: <Widget>[ DrawerHeader( child: Text('Drawer Header'), decoration: BoxDecoration( color: Colors.green, ), ), ListTile( title: Text('Item 1'), onTap: () { // Update the state of the app // ... // Then close the drawer Navigator.pop(context); }, ), ListTile( title: Text('Item 2'), onTap: () { // Update the state of the app // ... // Then close the drawer //Navigator.pop(context); Navigator.push( context, MaterialPageRoute( builder: (context) => SecondPage(), )); }, ), ], ), ), ); } } class SecondPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( /* actions: <Widget>[ IconButton( tooltip:'前のページに戻る', icon: Icon( Icons.chevron_left, ), onPressed: () { Navigator.pop(context); }, ), ], */ ), endDrawer: Drawer( child: ListView( padding: EdgeInsets.zero, children: <Widget>[ DrawerHeader( child:Text("Header2"), decoration: BoxDecoration( color: Colors.orange, ), ), ListTile( title: Text('前のページに戻る'), onTap: () { Navigator.pop(context); //←ドロワーが閉じるだけなので意味無い。 }, ), ListTile( title: Text('item2_1'), ), ], ), ), body: Text('second_pageです。'), ); } }
参考