Padding 组件:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Padding 组件
return Padding(
padding: EdgeInsets.all(10),
child: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
children: [
Image.network(
'https://images.pexels.com/photos/6569318/pexels-photo-6569318.jpeg?cs=srgb&dl=pexels-david-underland-6569318.jpg&fm=jpg',
fit: BoxFit.cover,
),
Image.network(
'https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg',
fit: BoxFit.cover,
),
Image.network(
'https://images.pexels.com/photos/5994821/pexels-photo-5994821.jpeg?cs=srgb&dl=pexels-matteus-silva-de-oliveira-5994821.jpg&fm=jpg',
fit: BoxFit.cover,
),
Image.network(
'https://images.pexels.com/photos/7173820/pexels-photo-7173820.jpeg?cs=srgb&dl=pexels-lisa-fotios-7173820.jpg&fm=jpg',
fit: BoxFit.cover,
),
Image.network(
'https://images.pexels.com/photos/7042988/pexels-photo-7042988.jpeg?cs=srgb&dl=pexels-jc-siller-7042988.jpg&fm=jpg',
fit: BoxFit.cover,
),
Image.network(
'https://images.pexels.com/photos/7137430/pexels-photo-7137430.jpeg?cs=srgb&dl=pexels-monica-turlui-7137430.jpg&fm=jpg',
fit: BoxFit.cover,
),
],
),
);
}
}
Row组件:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconWidget(Icons.home_filled, color: Colors.pink, size: 30),
IconWidget(Icons.search_off, color: Colors.blue, size: 30),
IconWidget(Icons.access_alarm, color: Colors.redAccent, size: 30),
],
);
}
}
class IconWidget extends StatelessWidget {
IconWidget(this.icon, {this.color = Colors.white70, this.size = 32});
final double size;
final IconData icon;
final Color color;
@override
Widget build(BuildContext context) {
return Container(
color: this.color,
width: 100,
height: 100,
child: Center(
child: Icon(this.icon, size: this.size, color: Colors.black),
),
);
}
}
属性 | 说明 |
---|---|
mainAxisAlignment | 主轴的排序方式 |
crossAxisAlignment | 次轴的排序方式 |
children | 组件的子元素 |
Column组件:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconWidget(Icons.home_filled, color: Colors.pink, size: 30),
IconWidget(Icons.search_off, color: Colors.blue, size: 30),
IconWidget(Icons.access_alarm, color: Colors.redAccent, size: 30),
],
);
}
}
class IconWidget extends StatelessWidget {
IconWidget(this.icon, {this.color = Colors.white70, this.size = 32});
final double size;
final IconData icon;
final Color color;
@override
Widget build(BuildContext context) {
return Container(
color: this.color,
width: 100,
height: 100,
child: Center(
child: Icon(this.icon, size: this.size, color: Colors.black),
),
);
}
}
Column 组件跟 Row 组件是差不多的。
Expanded 组件:
属性 | 说明 |
---|---|
flex | 元素占整个父 Row / Column 的比例 |
child | 子元素 |
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
flex: 1,
child: IconWidget(Icons.home_filled, color: Colors.pink, size: 30)),
Expanded(
flex: 2,
child: IconWidget(Icons.search_off, color: Colors.blue, size: 30)),
Expanded(
flex: 1,
child: IconWidget(Icons.access_alarm,
color: Colors.redAccent, size: 30)),
],
);
}
}
class IconWidget extends StatelessWidget {
IconWidget(this.icon, {this.color = Colors.white70, this.size = 32});
final double size;
final IconData icon;
final Color color;
@override
Widget build(BuildContext context) {
return Container(
color: this.color,
width: 100,
height: 100,
child: Center(
child: Icon(this.icon, size: this.size, color: Colors.black),
),
);
}
}
Expanded组件跟 web 中的 flex 布局相似。
一个布局demo:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10),
// decoration: BoxDecoration(color: Colors.pink),
child: Column(
children: [
BannerWidget(),
BannerListWidget(),
],
),
);
}
}
class BannerWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 100,
decoration: BoxDecoration(
color: Colors.pink,
borderRadius: BorderRadius.circular(10),
),
);
}
}
class BannerListWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 10),
child: Row(
children: [
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.only(right: 10),
child: Image.network(
'https://cdn.pixabay.com/photo/2021/03/16/15/30/beach-6100209_960_720.jpg',
fit: BoxFit.cover,
height: 180,
),
),
),
Expanded(
flex: 1,
child: Container(
height: 180,
child: layoutImage(),
),
),
],
),
);
}
}
class layoutImage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: Container(
width: double.infinity,
padding: EdgeInsets.only(bottom: 10),
child: Image.network(
'https://cdn.pixabay.com/photo/2015/09/09/16/40/girl-931776_960_720.jpg',
fit: BoxFit.cover),
)),
Expanded(
child: Container(
width: double.infinity,
child: Image.network(
'https://cdn.pixabay.com/photo/2014/12/16/22/25/woman-570883_960_720.jpg',
fit: BoxFit.cover),
)),
],
);
}
}
在这个 布局demo 中,你需要体会, 布局约束的重要性,否则你将有很多无法理解的东西。
建议查看文档: https://flutter.cn/docs/development/ui/layout/constraints
Stack 组件:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
padding: EdgeInsets.all(10),
// decoration: BoxDecoration(color: Colors.pink),
child: Container(
width: 200,
height: 500,
decoration: BoxDecoration(
color: Colors.pink,
),
child: Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Icon(Icons.home),
),
Align(
alignment: Alignment.bottomLeft,
child: Icon(Icons.search_off),
),
],
),
),
),
);
}
}
AspectRatio 的作用是设置调整子元素的宽高比:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 2 / 1,
child: Image.network(
'https://cdn.pixabay.com/photo/2021/01/29/09/29/bridge-5960361_960_720.jpg',
fit: BoxFit.cover,
),
);
}
}
Card 组件:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CardListWidget();
}
}
class CardListWidget extends StatelessWidget {
Widget _imageList(context, index) {
return Card(
margin: EdgeInsets.all(10),
child: Column(
children: [
Expanded(child: Image.network(listData[index]['imageUrl'])),
ListTile(
title: Text(
listData[index]['title'],
textAlign: TextAlign.center,
),
subtitle: Text(
listData[index]['author'],
textAlign: TextAlign.center,
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 1,
crossAxisSpacing: 2,
),
itemCount: listData.length,
itemBuilder: this._imageList);
}
}
CircleAvatar 圆形头像组件:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CardListWidget();
}
}
class CardListWidget extends StatelessWidget {
Widget _imageList(context, index) {
return Card(
margin: EdgeInsets.all(10),
child: Column(
children: [
AspectRatio(
aspectRatio: 20 / 9,
child:
Image.network(listData[index]['imageUrl'], fit: BoxFit.cover),
),
ListTile(
// CircleAvatar 处理头像
leading: CircleAvatar(
backgroundImage: NetworkImage(listData[index]['imageUrl']),
),
title: Text(listData[index]['title']),
subtitle: Text(listData[index]['author']),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: listData.length, itemBuilder: this._imageList);
}
}
Warp 自动换行组件:
import 'package:flutter/material.dart';
import 'data/newList.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: HomeContent(),
),
theme: ThemeData(
primaryColor: Colors.pink,
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 180,
padding: EdgeInsets.all(20),
child: Center(
child: Wrap(
spacing: 5,
runSpacing: 10,
runAlignment: WrapAlignment.spaceAround,
children: [
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
Container(
width: 70,
height: 70,
child: Column(
children: [
Expanded(
child: CircleAvatar(
backgroundImage: NetworkImage('https://images.pexels.com/photos/6922718/pexels-photo-6922718.jpeg?cs=srgb&dl=pexels-kira-schwarz-6922718.jpg&fm=jpg'),
),
),
Text('首页'),
],
),
),
],
),
),
);
}
}