Flutter動画やってみよ(Foodアプリ)5/5
YoutubeのFlutter UI作成動画トライの続きです。
食べ物の横スクロール一覧を足していきます。
小見出しを付ける
カテゴリの下に、小見出しをつけます。
SizedBox(height: 10, ), ], ), ), FadeAnimation(1, Padding( padding: EdgeInsets.all(20), child: Text('Free Delivery', style: TextStyle(color: Colors.grey[700], fontSize: 20, fontWeight: FontWeight.bold)) ))
この動画では、Widget間の余白を作るのに、Paddingの他にもSizedBoxが頻繁に使われていますね。
どういう使い分けなんだろう。
小見出しが追加されましたが、センタリングされています。 左寄せに変更します。
body: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.start,
食べ物画像を表示する
画像の表示エリアを追加します。
FadeAnimation(1, Padding( padding: EdgeInsets.all(20), child: Text('Free Delivery', style: TextStyle(color: Colors.grey[700], fontSize: 20, fontWeight: FontWeight.bold)) )), Expanded( child: Padding( padding: EdgeInsets.symmetric(horizontal: 20.0), child: ListView( scrollDirection: Axis.horizontal, children: <Widget>[ FadeAnimation(2, makeItem(image: 'assets/images/one.jpg')), ], ) ) ), SizedBox( height: 30, )
今後、複数のアイテムを並べることを想定して、画像表示エリアを生成する makeItem 関数を用意します。
関数は以下です。
Widget makeItem({image}) { return AspectRatio( aspectRatio: 1 / 1.4, child: GestureDetector( child: Container( color: Colors.red, ) ) ); }
赤いエリアが表示されました。 ここに画像をはめ込んでいきます。
赤いエリアは、左右の画面の境界線にスワイプすると自然に戻ってきます。 (動きは、Youtubeの 22:00 頃を見てね)
これは、GestureDetector Widgetのおかげかな?
makeItem 関数を書き換えて、画像をはめ込みます。
Widget makeItem({image}) { return AspectRatio( aspectRatio: 1 / 1.4, child: GestureDetector( child: Container( decoration: BoxDecoration ( image: DecorationImage( image: AssetImage(image), fit: BoxFit.cover, )
引数に指定される画像は、アセットのパスなので AssetImage で読み込んでいます。
美味しそうなピザの画像が出ました!
次に画像に、価格などの文字を重ねるため、黒いグラデーションをかけます。
画像に文字を重ねる
画像に文字を重ねる箇所に、うっすら黒いグラデーションをかけます。
child: Container( decoration: BoxDecoration ( image: DecorationImage( image: AssetImage(image), fit: BoxFit.cover, ) ), child: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.bottomCenter, stops: [.2, .9], colors:[ Colors.black.withOpacity(.9), Colors.black.withOpacity(.3), ] ) ), child: Padding( padding: EdgeInsets.all(20.0), child: Column( children: <Widget>[ Align( alignment: Alignment.topRight, child: Icon(Icons.favorite, color: Colors.white, ), ) ], ) ) )
画像を配置したコンテナに、グラデーション用のコンテナを追加します。 ついでに、お気に入りアイコンも右上に追加します。
動画では画面サイズピッタリなのに 僕のは、はみ出してしまってる・・・なぜだ・・・
基本の表示が出来たので、画像を3枚に増やします。
child: ListView( scrollDirection: Axis.horizontal, children: <Widget>[ FadeAnimation(1.4, makeItem(image: 'assets/images/one.jpg')), FadeAnimation(1.5, makeItem(image: 'assets/images/two.jpg')), FadeAnimation(1.6, makeItem(image: 'assets/images/three.jpg')), ],
画像の間隔が詰まりすぎているので、余白を付けます。
Widget makeItem({image}) { return AspectRatio( aspectRatio: 1 / 1.5, // ← 1.4 を 1.5 に。 child: GestureDetector( child: Container( margin: EdgeInsets.only(right: 20), // margin 設定を追加
Container の右側に margin をつけました。 合わせて、aspectRatio の設定も変更しています。 これで、1画面に収まるようになりました。
最後に、価格と商品名を追加します。
child: Column( crossAxisAlignment: CrossAxisAlignment.start, // ← 左寄せ mainAxisAlignment: MainAxisAlignment.spaceBetween, // ← 文字を下側に children: <Widget>[ Align( alignment: Alignment.topRight, child: Icon(Icons.favorite, color: Colors.white, ), ), Column( crossAxisAlignment: CrossAxisAlignment.start, // ← 左寄せ children: <Widget>[ // ←テキスト追加 Text("\$ 15.00", style: TextStyle(color: Colors.white, fontSize: 40, fontWeight: FontWeight.bold)), SizedBox(height: 10,), ← 行間は、SizedBoxで調整 Text("Vegetarian Pizza", style: TextStyle(color: Colors.white, fontSize: 20)), ], )
それっぽい感じに出来ました!
最後に、起動ページをStartupに戻して動作確認すれば終了です。
void main() => runApp( MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData(fontFamily: 'Roboto'), home: StarterPage(), // ← もとのStarterPage から始まるように戻します。 ) );