https://dartpad.dev/?id=6c33d8719a4bfcdc9cab3542511e0dd2
Created with <3 with dartpad.dev. 参考:Flutterでのレイアウトの組み合わせ方を学ぼう~実際の画面例を使用 (1/2)|CodeZine(コードジン) https://codezine.jp/article/detail/14820
https://dartpad.dev/?id=6c33d8719a4bfcdc9cab3542511e0dd2
Created with <3 with dartpad.dev. 参考:Flutterでのレイアウトの組み合わせ方を学ぼう~実際の画面例を使用 (1/2)|CodeZine(コードジン) https://codezine.jp/article/detail/14820
| import 'package:flutter/material.dart'; | |
| //import 'package:flutter/cupertino.dart'; | |
| void main() { | |
| runApp(MyApp()); | |
| } | |
| class MyApp extends StatelessWidget { | |
| // This widget is the root of your application. | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| debugShowCheckedModeBanner: false, | |
| title: 'Flutter Layout Sample', | |
| theme: ThemeData( | |
| primarySwatch: Colors.blue, | |
| ), | |
| home: MainPageWidget() | |
| ); | |
| } | |
| } | |
| class MainPageWidget extends StatefulWidget{ | |
| @override | |
| State<StatefulWidget> createState() { | |
| return _MainPageWidget(); | |
| } | |
| } | |
| class _MainPageWidget extends State<MainPageWidget>{ | |
| bool _isSelectedItem = false; | |
| // 詳細画面を表示する | |
| void openDetail(){ | |
| setState(() { | |
| _isSelectedItem = true; | |
| }); | |
| } | |
| // 詳細画面を消す | |
| void closeDetail(){ | |
| setState(() { | |
| _isSelectedItem = false; | |
| }); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return Stack( | |
| children: [ | |
| CouponListView(openDetail), | |
| if (_isSelectedItem) | |
| CouponDetail(closeDetail) | |
| ], | |
| ); | |
| } | |
| } | |
| class MainContent extends StatelessWidget{ | |
| Function onPressed; | |
| MainContent(this.onPressed); | |
| @override | |
| Widget build(BuildContext context) { | |
| return Column( | |
| children: [ | |
| Container( | |
| height: 20, | |
| child : Align( | |
| alignment: Alignment.centerLeft, | |
| child: Padding( | |
| child: FittedBox( | |
| fit: BoxFit.contain, | |
| child: Text("タイトル", | |
| style: TextStyle( | |
| color: Colors.black, | |
| decoration: TextDecoration.none, | |
| fontWeight: FontWeight.normal | |
| ), | |
| ), | |
| ), | |
| padding: EdgeInsets.all(2) | |
| ), | |
| ) | |
| ), | |
| Expanded( | |
| child: Container( | |
| color: Colors.grey.shade300, | |
| ) | |
| ), | |
| Container( | |
| height: 20, | |
| padding: EdgeInsets.symmetric( horizontal: 5, vertical: 2), | |
| child: Row( | |
| children: [ | |
| ElevatedButton( | |
| onPressed: () => { onPressed() }, | |
| child: Padding( | |
| child: FittedBox( | |
| fit: BoxFit.contain, | |
| child: Text("詳細を見る"), | |
| ), | |
| padding: EdgeInsets.all(2) | |
| ), | |
| style: ButtonStyle( | |
| backgroundColor: MaterialStateProperty.all<Color>(Colors.red), | |
| foregroundColor: MaterialStateProperty.all<Color>(Colors.white), | |
| shape: MaterialStateProperty.all<RoundedRectangleBorder>( | |
| RoundedRectangleBorder( | |
| borderRadius: BorderRadius.circular(5.0), | |
| side: BorderSide(color: Colors.red) | |
| ) | |
| ) | |
| ) | |
| ), | |
| Padding( | |
| padding: EdgeInsets.only(top: 5), | |
| child: FittedBox( | |
| fit: BoxFit.fitHeight, | |
| child: Text("2021/07/21", | |
| style: TextStyle( | |
| color: Colors.black, | |
| decoration: TextDecoration.none, | |
| fontWeight: FontWeight.normal | |
| ), | |
| ), | |
| ) | |
| ) | |
| ], | |
| mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
| ), | |
| ) | |
| ], | |
| ); | |
| } | |
| } | |
| class CouponListView extends StatelessWidget{ | |
| Function onPressed; | |
| CouponListView(this.onPressed); | |
| @override | |
| Widget build(BuildContext context) { | |
| return Container( | |
| color: Colors.white, | |
| child: listViewBuilder() | |
| ); | |
| } | |
| Widget buildListView(){ | |
| return ListView( | |
| children: [ | |
| CouponListItem(onPressed), | |
| CouponListItem(onPressed), | |
| CouponListItem(onPressed), | |
| ], | |
| ); | |
| } | |
| // データの個数に従って、表示する場合 | |
| final items = [0,1,2,3,4,5,6]; | |
| Widget listViewBuilder(){ | |
| return ListView.builder( | |
| itemCount: items.length, | |
| itemBuilder: (BuildContext context, int index) { | |
| return CouponListItem(onPressed); | |
| } | |
| ); | |
| } | |
| } | |
| class CouponListItem extends StatelessWidget { | |
| Function onPressed; | |
| CouponListItem(this.onPressed); | |
| @override | |
| Widget build(BuildContext context) { | |
| return Container( | |
| margin: EdgeInsets.all(10), | |
| padding: EdgeInsets.all(10), | |
| decoration: BoxDecoration( | |
| borderRadius: BorderRadius.circular(10), | |
| color: Colors.white, | |
| boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 3)]), | |
| child: Row(children: [ | |
| Container( | |
| width: 100, | |
| height: 100, | |
| margin: EdgeInsets.only(right: 10), | |
| child: imageWidget(), | |
| decoration: BoxDecoration( | |
| borderRadius: BorderRadius.circular(1), | |
| color: Colors.white, | |
| boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 1)]), | |
| ), | |
| Expanded( | |
| child: Container( | |
| height: 100, | |
| child: MainContent(onPressed) | |
| ) | |
| ) | |
| ])); | |
| } | |
| // 画像を表示 | |
| Widget imageWidget(){ | |
| return ClipRect( | |
| child: FittedBox( | |
| child: Image.asset('assets/images/c_img.jpg'), | |
| fit: BoxFit.cover, | |
| ) | |
| ); | |
| } | |
| } | |
| class CouponDetail extends StatelessWidget { | |
| Function closeAction; | |
| CouponDetail(this.closeAction); | |
| @override | |
| Widget build(BuildContext context) { | |
| return Container( | |
| color: Color.fromRGBO(0, 0, 0, 0.5), | |
| child: Center( | |
| child: Padding( | |
| padding: EdgeInsets.all(20), | |
| // 外枠を表示 | |
| child: Container( | |
| margin: EdgeInsets.all(20), | |
| padding: EdgeInsets.all(20), | |
| decoration: BoxDecoration( | |
| borderRadius: BorderRadius.circular(10), | |
| color: Colors.white, | |
| boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 5)]), | |
| // コンテンツの中身を表示 | |
| child: mainContent(), | |
| ), | |
| ))); | |
| } | |
| // コンテンツの中身 | |
| Widget mainContent(){ | |
| return Column( | |
| // 表示するサイズを最小にする | |
| mainAxisSize: MainAxisSize.min, | |
| children: [ | |
| Image.asset('assets/images/c_img.jpg'), | |
| mainCenterContent(), | |
| mainBottomContent(), | |
| ], | |
| ); | |
| } | |
| Widget mainCenterContent(){ | |
| return Container( | |
| margin: EdgeInsets.only(top: 10), | |
| height: 80, | |
| color: Colors.grey, | |
| ); | |
| } | |
| Widget mainBottomContent(){ | |
| return Padding( | |
| padding: EdgeInsets.all(10), | |
| child: Center( | |
| child: Row( | |
| children: [ | |
| Spacer( | |
| flex: 1, | |
| ), | |
| Expanded( | |
| flex: 2, | |
| child: ElevatedButton( | |
| onPressed: () => {closeAction()}, | |
| child: Padding( | |
| child: FittedBox( | |
| fit: BoxFit.contain, | |
| child: Text("閉じる"), | |
| ), | |
| padding: EdgeInsets.all(2)), | |
| style: ButtonStyle( | |
| backgroundColor: | |
| MaterialStateProperty.all<Color>( | |
| Colors.red), | |
| foregroundColor: | |
| MaterialStateProperty.all<Color>( | |
| Colors.white), | |
| shape: MaterialStateProperty.all< | |
| RoundedRectangleBorder>( | |
| RoundedRectangleBorder( | |
| borderRadius: | |
| BorderRadius.circular(5.0), | |
| side: BorderSide( | |
| color: Colors.red)))))), | |
| Spacer( | |
| flex: 1, | |
| ) | |
| ], | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |