(main.dart)
และหน้ารายละเอียด (detail_page.dart)
แต่ก่อนหน้านั้นเรามาเตรียมสีที่จะใช้ กับข้อมูลกันก่อนcolor_palette.dart
โลดimport 'package:flutter/material.dart'; | |
class ColorPalette { | |
static Color grey10 = Color(0xFFf2f6f5); | |
static Color grey30 = Color(0xFFc8dad3); | |
static Color grey60 = Color(0xFF93b5b3); | |
static Color grey90 = Color(0xFF63707e); | |
} |
icon_data.dart
import 'dart:core'; | |
import 'package:flutter/cupertino.dart'; | |
import 'package:flutter/material.dart'; | |
class IconModel { | |
final String title; | |
final IconData icon; | |
IconModel({this.title, this.icon}); | |
} | |
final List<IconModel> iconList = [ | |
IconModel(title: 'Motorcycle', icon: Icons.motorcycle), | |
IconModel(title: 'Car', icon: Icons.directions_car), | |
IconModel(title: 'Train', icon: Icons.directions_railway), | |
IconModel(title: 'Laptop',icon: Icons.laptop_windows), | |
IconModel(title: 'Home',icon: Icons.home), | |
]; |
IconModel
โดยข้อมูลแต่ละอันจะประกอบไปด้วยชื่อ title
กับไอคอน icon
และสร้างข้อมูลต่อ เป็น List
ของ IconModel
เก็บไว้ในตัวแปร iconList
main.dart
import 'package:flutter/material.dart'; | |
import 'package:icon_showcase_design_part/color_palette.dart'; | |
import 'package:icon_showcase_design_part/icon_data.dart'; | |
import 'package:icon_showcase_design_part/detail_page.dart'; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Icon Showcase', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: MyHomePage(title: 'Icon Showcase'), | |
debugShowCheckedModeBanner: false, | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
MyHomePage({Key key, this.title}) : super(key: key); | |
final String title; | |
@override | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
backgroundColor: ColorPalette.grey90, | |
appBar: AppBar( | |
backgroundColor: Colors.transparent, | |
elevation: 0.0, | |
title: Text( | |
widget.title, | |
style: TextStyle(color: ColorPalette.grey10), | |
), | |
leading: Icon( | |
Icons.menu, | |
color: ColorPalette.grey10, | |
), | |
), | |
body: ListView.builder( | |
itemCount: iconList.length, | |
itemBuilder: (context, index) => InkWell( | |
onTap: () => Navigator.of(context).push(MaterialPageRoute(builder: (context)=> DetailPage(iconData: iconList[index],))), | |
child: Card( | |
color: ColorPalette.grey10, | |
margin: EdgeInsets.all(10), | |
elevation: 10.0, | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(25.0)), | |
child: Padding( | |
padding: const EdgeInsets.all(30.0), | |
child: ListTile( | |
leading: Icon( | |
iconList[index].icon, | |
size: 45.0, | |
color: ColorPalette.grey60, | |
), | |
title: Text(iconList[index].title,style: TextStyle(color: Colors.black87, fontSize: 20.0),), | |
), | |
), | |
), | |
), | |
)); | |
} | |
} |
class _MyHomePageState
Scaffold
เราจะตั้งสีพื้นหลัง ทั้งหมดเป็น ColorPalette.grey90
Appbar
เราก็ทำให้สีพื้นหลังโปร่งใสซะ และไม่ให้มันเกิดเงา ก็ตั้ง elevation
เป็น 0.0 แล้วเพิ่ม leading
เป็น icon menu จะได้ดูเหมือนมีฟีเจอร์อื่น แต่เราจะไม่ได้ใส่เมนูลงไปจริงๆListView
ที่ประกอบไปด้วย Card ที่สร้างมาจากข้อมูลของเรา เราจะใช้ ListView.builder
ให้มันสร้าง Card
แล้วในจะใส่ ListTile
เข้าไป เพื่อจัดวางข้อมูลของเราWidget
child เข้าไปก็ใช้งานได้ทันที ถ้าอยากปรับความมนของขอบก็ส่ง shape:
เข้าไปได้เลยCard
แล้ว เราอยากจัดองค์ประกอบแบบง่ายๆก็ใช้ Widget ListTile
Widget
child ของเราเข้าไปตรงนั้นเลย (ปล.ไม่จำเป็นต้องอยู่ใน Card
นะ แค่ส่วนใหญ่ชอบใช้คู่กัน)padding
เพื่อให้องค์ประกอบออกมากำลังดี ได้ผลลัพธ์สุดท้ายดังนี้detail_page.dart
กันเลยimport 'package:icon_showcase_design_part/color_palette.dart'; | |
import 'package:icon_showcase_design_part/icon_data.dart'; | |
import 'package:flutter/material.dart'; | |
class DetailPage extends StatefulWidget { | |
final IconModel iconData; | |
DetailPage({Key key, @required this.iconData}) : super(key: key); | |
@override | |
_DetailPageState createState() => _DetailPageState(); | |
} | |
class _DetailPageState extends State<DetailPage> { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
backgroundColor: ColorPalette.grey90, | |
body: SafeArea( | |
child: Card( | |
margin: EdgeInsets.all(10), | |
clipBehavior: Clip.antiAlias, | |
elevation: 0.0, | |
color: ColorPalette.grey10, | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(25.0)), | |
child: Stack(children: <Widget>[ | |
Positioned.fill( | |
bottom: -90, | |
right: -90, | |
child: Align( | |
alignment: Alignment.bottomRight, | |
child: Icon( | |
widget.iconData.icon, | |
size: 400, | |
color: ColorPalette.grey30, | |
))), | |
Container( | |
width: MediaQuery.of(context).size.width, | |
height: 500, | |
child: Padding( | |
padding: const EdgeInsets.only(left: 20.0, top: 20.0), | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: <Widget>[ | |
InkWell( | |
onTap: () { | |
Navigator.of(context).pop(true); | |
return Future.value(false); | |
}, | |
child: Icon( | |
Icons.arrow_back, | |
)), | |
Text(widget.iconData.title,style: TextStyle(color: Colors.black87, fontSize: 60.0),), | |
]))), | |
])), | |
), | |
); | |
} | |
} |
Scaffold
เราจะไม่มี appbar
ดังนั้นที่ body
เราจะหุ้ม widget
ด้วย SafeArea
Widget Stack
Navigator
ใน main.dart
ให้ push หน้า detail_page.dart
และในหน้า detail_page.dart
ก็ใส่ pop จะได้กลับหน้าหลักได้