接下来,我们将会通过组合使用展示widget和布局widget来实现自定义的三种类型的Card,利用这些Card组件来替换之前导航栏点击后的跳转页面.
展示组件就是用户可以直接看到的那些组件,例如
- Text
- Image
- Button
布局组件则是那些帮助我们进行页面布局,美化界面的组件,例如
- Container
- Padding
- Stack
- Column
- SizedBox
- Row
关于布局组件,可以查看这个文档里面的介绍
https://flutter.dev/docs/development/ui/widgets/layout
创建主卡片
我们先创建一个主卡片,如下图
主卡片由以下widget组合而成:
- Container
- Stack
- Text
- Image
我们在使用中来逐步体会这些widget的功能吧.
在lib文件夹下新建card1.dart文件,实现代码如下:
import 'package:flutter/material.dart';
class Card1 extends StatelessWidget {
const Card1({Key? key}) : super(key: key);
//定义一些数据用来展示在卡片上
final String category = 'Editor\'s Choice';
final String title = 'The Art of Dough';
final String description = 'Learn to make the perfect bread.';
final String chef = 'Ray Wenderlich';
@override
Widget build(BuildContext context) {
return Center(
// TODO: Card1 Decorate Container
child: Container(),
);
}
}
然后在home.dart中导入card1.dart,在TODO: Replace with Card1这个地方使用Card1来替换原来的Container.
const Card1(),
现在的Card1只是一片空白,没用内容,我们来添加一些数据到卡片上.
回到car1.dart文件中,定位到 TODO: Card1 Decorate Container的地方,我们在Container中添加一些新的内容:
child: Container(
// TODO: Add a stack of text
//1.添加16单位的padding,Flutter中的单位叫做logic pixels,类似Android中的dp
padding: const EdgeInsets.all(16),
//2.设置宽高
constraints: const BoxConstraints.expand(
width: 350,
height: 450,
),
//3.设置背景图片和四角的弧度
decoration: const BoxDecoration(
image: DecorationImage(image: AssetImage('assets/mag1.jpg'), fit: BoxFit.cover),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
),
此处需要使用图片资源,在根目录下新建assets目录,然后把图片资源放在该目录下,在pubspec.yaml文件中声明资源的位置:
flutter:
uses-material-design: true
assets:
- assets/
自己找的图片,凑合着看吧
下面我们继续把Card1.dart里定义的一些文字展示在卡片上来.
定位到TODO: Add a stack of text的位置,添加以下代码:
child: Stack(
children: [
Text(
category,
style: FooderlichTheme.darkTextTheme.bodyText1,
),
Text(
title,
style: FooderlichTheme.darkTextTheme.headline5,
),
Text(
description,
style: FooderlichTheme.darkTextTheme.bodyText1,
),
Text(
chef,
style: FooderlichTheme.darkTextTheme.bodyText1,
),
],
),
可以看到有点尴尬,Stack组件并没有按照想象中的顺序帮我们排列好位置,我们需要自己来进行位置的排列.
child: Stack(
children: [
//位置不变
Text(
category,
style: FooderlichTheme.darkTextTheme.bodyText1,
),
//距离顶部20
Positioned(
child: Text(
title,
style: FooderlichTheme.darkTextTheme.headline2,
),
top: 20,
),
//距离底部30,右边0
Positioned(
child: Text(
description,
style: FooderlichTheme.darkTextTheme.bodyText1,
),
bottom: 30,
right: 0,
),
//距离底部10,右侧0
Positioned(
child: Text(
chef,
style: FooderlichTheme.darkTextTheme.bodyText1,
),
bottom: 10,
right: 0,
)
],
),
可以看下效果,达到了我们的期望.
第一个Card完成了,接下来我们还要开发另外两个Card.