😋
よくあるUIを作ってみる
Widgetの配置で苦戦した!
Paddingを使って数値で、Widgetを配置してましたがこれは実は良くないのを最近知りました!
端末が変わると、ズレたりするそうです!
こちらの記事が参考になりました
日本語の記事があるとありがたいですね。
SNS風UIを作ってみる
Twitterやグルメアプリのようなリストで表示されるUIを作ってみました。画面を再現するだけなので、Columnの中に書いてます😅
こちらがリストを表示したページ
ソースコード
import 'package:sugary_map/service/export/global_export.dart';
import 'package:sugary_map/theme/appbar_theme.dart';
import 'package:sugary_map/theme/button_theme.dart';
import 'package:sugary_map/ui/page/user/user_nav/post_page/add_post.dart';
import 'package:sugary_map/ui/page/user/user_nav/post_page/post_detail.dart';
class PostPage extends StatefulWidget {
const PostPage({Key? key}) : super(key: key);
State<PostPage> createState() => _PostPageState();
}
class _PostPageState extends State<PostPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('口コミ'),
backgroundColor: MyAppBar.appBar.appColor,
),
floatingActionButton: FloatingActionButton(
onPressed: (() {
context.goNamed(PostAdd.routeName);
}),
backgroundColor: MyButton.appButton.appColor,
child: const Icon(Icons.add),
),
// スクロールさせてOverFlowを解消する.
body: SingleChildScrollView(
child: Center(
child: Column(
children: <Widget>[
SizedBox(height: 50),
// Containerをタップすると詳細ページへ画面遷移する.
GestureDetector(
onTap: () {
GoRouter.of(context).go('/post/post_detail');
},
child: Container(
// 水平方向にContainerを寄せる.
// 左端にスペースを20.0空ける.
margin: EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
children: [
CircleAvatar(
backgroundColor: Colors.grey,
),
SizedBox(width: 20),
Column(
// Textを全て左端に寄せる設定.
crossAxisAlignment: CrossAxisAlignment.start,
verticalDirection: VerticalDirection.down,
children: [
Text('上田 2023/01/04'),
Text('称号 甘党'),
],
)
],
),
),
),
SizedBox(height: 20),
Container(
width: 350,
height: 200,
color: Colors.grey[200],
),
SizedBox(height: 10),
Row(
children: [
IconButton(
onPressed: () {}, icon: Icon(Icons.file_upload_outlined)),
IconButton(onPressed: () {}, icon: Icon(Icons.favorite)),
TextButton(onPressed: () {}, child: Text('12')),
],
),
Container(
alignment: Alignment(-0.7, -0.7),
child: Text('クラシックなフランス菓子を数多く扱う名店。\nおすすめは、ガトーピレネーです。')),
SizedBox(height: 30),
Container(
// 水平方向にContainerを寄せる.
// 左端にスペースを20.0空ける.
margin: EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
children: [
CircleAvatar(
backgroundColor: Colors.grey,
),
SizedBox(width: 20),
Column(
// Textを全て左端に寄せる設定.
crossAxisAlignment: CrossAxisAlignment.start,
verticalDirection: VerticalDirection.down,
children: [
Text('minn 2023/01/04'),
Text('称号 お菓子ライター'),
],
)
],
),
),
SizedBox(height: 20),
Container(
width: 350,
height: 200,
color: Colors.grey[200],
),
SizedBox(height: 10),
Row(
children: [
IconButton(
onPressed: () {}, icon: Icon(Icons.file_upload_outlined)),
IconButton(onPressed: () {}, icon: Icon(Icons.favorite)),
TextButton(onPressed: () {}, child: Text('8')),
],
),
Container(
alignment: Alignment(-0.7, -0.7),
child: Text('ざっくりとした食感のミルフィーユが、\n衝撃的な美味しさでした!')),
],
),
),
),
);
}
}
こちらが詳細ページ
ソースコード
import 'package:sugary_map/service/export/global_export.dart';
import 'package:sugary_map/theme/appbar_theme.dart';
import 'package:sugary_map/theme/button_theme.dart';
import 'package:sugary_map/ui/page/user/user_nav/post_page/add_post.dart';
class PostDetail extends StatefulWidget {
const PostDetail({Key? key}) : super(key: key);
State<PostDetail> createState() => _PostDetailState();
}
class _PostDetailState extends State<PostDetail> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('口コミ詳細'),
backgroundColor: MyAppBar.appBar.appColor,
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: <Widget>[
const SizedBox(height: 40),
Container(
width: 300,
height: 150,
color: Colors.grey[200],
),
Container(
width: 300,
height: 50,
child: Row(
children: [
Text('投稿者'),
const SizedBox(width: 20),
Text('上田'),
],
),
),
Container(
alignment: const Alignment(0.0, 0.0),
width: 300,
height: 50,
child: Row(
children: [
Text('いったお店'),
const SizedBox(width: 20),
Text('オーボン・ビュータン'),
],
),
),
Column(
children: [
Container(
alignment: const Alignment(-1.0, -1.0),
width: 300,
height: 100,
child: Text('クラシックなフランス菓子を数多く扱う名店。\nおすすめは、ガトピレネーです。')),
Container(
alignment: const Alignment(-1.0, -1.0),
width: 300,
height: 100,
child: Column(
// テキストを左端に寄せる.
crossAxisAlignment: CrossAxisAlignment.start,
verticalDirection: VerticalDirection.down,
children: [
Text('東京都尾山台'),
SizedBox(height: 20),
Text('090-9988-3477'),
],
)),
],
),
Image.network(
'https://poi-static-map.cld.navitime.jp/02022/120998/image.png'),
],
),
),
),
);
}
}
まとめ
英語で座標を指定する説明が出てきたので、いくつかをまとめておきます。
-
Swiftでもあった水平か垂直か決めるコード
- 水平 horizontality
- 垂直 vertical
-
Containerで囲む
- alignment: const Alignment(0.0, 0.0),// 中心に配置.
- alignment: const Alignment(-1.0, -1.0),// 左上に配置.
- alignment: const Alignment(-1.0, -1.0),// 右下に配置.
TextWidgetが左端によってくれないことがあった!
Columnに、CrossAxisAlignment.startとVerticalDirection.downを追加すると、左端によった!
Container(
alignment: const Alignment(-1.0, -1.0),
width: 300,
height: 100,
child: Column(
// テキストを左端に寄せる.
crossAxisAlignment: CrossAxisAlignment.start,
verticalDirection: VerticalDirection.down,
children: [
Text('東京都尾山台'),
SizedBox(height: 20),
Text('090-9988-3477'),
],
)),
Discussion