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, | |
) | |
], | |
), | |
), | |
); | |
} | |
} | |