Flutter-从入门到放弃(目录,持续更新中)
这一节我们将会继续开发第二个卡片界面:作者卡片,效果如下图
跟主卡片相比,有相似之处,都有图片背景,另外这里使用一个自定义widget来展示作者的头像,名字及头衔,另外除了常规得文本之外,这里还有一个垂直排列的文本与众不同.新建card2.dart文件,初始代码如下:
import 'package:flutter/material.dart';
class Card2 extends StatelessWidget {
const Card2({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: Container(
constraints: const BoxConstraints.expand(width: 350, height: 450),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/mag5.jpg'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
child: Column(
children: const [
// TODO 1: add author information
// TODO 4: add Positioned text
],
),
),
);
}
}
可以回顾下组件得结构,Center的child Container包含了三个属性,constraints和decoration属于外观方面的,child 指定了Container的子组件为Column,以垂直排列的方式进行组合.
进入home.dart,把之前的TODO: Replace with Card2 替换为
const Card2(),
运行app,点击导航栏Card2,可以看看初步的效果
目前只是完成了背景的部分,还有数据展示的部分需要我们继续来完成,完成后的结构如下:
接下来我们先把展示头像和名字的组件完成一下,结构如下:
通过分析可以发现,我们首先需要把展示头像的CircleImage组件开发出来才能进行下一步的工作.
在lib文件夹下创建circle_image.dart文件,代码如下:
import 'package:flutter/material.dart';
class CircleImage extends StatelessWidget {
const CircleImage({
Key? key,
this.imageProvider,
this.imageRadius = 20,
}) : super(key: key);
final double imageRadius;
final ImageProvider? imageProvider;
@override
Widget build(BuildContext context) {
return CircleAvatar(
backgroundColor: Colors.white,
radius: imageRadius,
//外面是白色背景的圆,里面是小一点的圆形图片
child: CircleAvatar(
radius: imageRadius - 5,
backgroundImage: imageProvider,
),
);
}
}
开发完头像组件后,我们可以继续来开发整个卡片了.新建author_card.dart文件,代码如下:
import 'package:flutter/material.dart';
class AuthorCard extends StatelessWidget {
//需要展示的名字,头衔,头像数据
final String authorName;
final String title;
final ImageProvider? imageProvider;
const AuthorCard({
Key? key,
required this.authorName,
required this.title,
this.imageProvider,
}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: Replace return Container(...);
return Container(
padding: const EdgeInsets.all(16),
child: Row(
children: const [],
),
);
}
}
先把头像组件的结构搭起来,然后去card2中把头像组件替换进去,定位到TODO 1: add author information,替换为如下代码:
AuthorCard(
authorName: 'Mike Katz',
title: 'Smoothie Connoisseur',
imageProvider: AssetImage('assets/author_katz.jpeg'),
),
然后回到author_card中来,继续把Container里的内容补充完整
return Container(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleImage(
imageProvider: imageProvider,
imageRadius: 28,
),
const SizedBox(
width: 8,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
authorName,
style: FooderlichTheme.lightTextTheme.headline2,
),
Text(
title,
style: FooderlichTheme.lightTextTheme.headline3,
)
],
),
IconButton(
icon: const Icon(Icons.favorite_border),
iconSize: 30,
color: Colors.green[400],
onPressed: () {
const snackBar = SnackBar(content: Text("Favorite Pressed"));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
},
)
],
),
);
author_card开发完毕了,我们需要回到card2中,把剩下的文字数据展示出来.定位到TODO 4: add Positioned text,用如下代码替换:
child: Column(
children: [
const AuthorCard(
authorName: 'Mike Katz',
title: 'Smoothie Connoisseur',
imageProvider: AssetImage('assets/author_katz.png'),
),
//Expanded组件将会把剩余的空间全部填充
Expanded(
child: Stack(
children: [
//此处文本定位在距离底部16,距离右侧16的位置
Positioned(
bottom: 16,
right: 16,
child: Text(
'Recipe',
style: FooderlichTheme.lightTextTheme.headline1,
),
),
//此处使用RotatedBox组件,可以进行旋转,通过旋转来形成我们需要的展示效果
//可以通过跳转quarterTurns参数来探索旋转的效果
Positioned(
bottom: 70,
left: 16,
child: RotatedBox(
quarterTurns: 3,
child: Text(
'Smoothies',
style: FooderlichTheme.lightTextTheme.headline1,
),
),
),
],
),
),
],
),
最终效果还是不错的
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)