在图解了布局之后,再从细节到整体来实现这个布局就容易了。为了让嵌套的代码看起来不那么混乱,我们将一些实现置于变量和函数中。

Step 2:实现Title Section

首先需要在Title Section左侧创建一列。在Expanded组件中的Column组件使得当前列(column并非组件)可以覆盖真个Title section. 将Column组件的 crossAxisAlignment 属性设置CrossAxisAlignment.start ,这样Column组件位于当前行的起始位置。

将第一行的文本组件放置于Container组件中以便添加Container内边据。第二个文本组件文字是灰色。

最后的2个组件包括一个红色星型图标和一个数字“41”的文本。将整个标题行(Title Section图解中的Row with 3 children)放置在一个Container组件中,并且设置Container组件32px的内边距。

Note: 如何代码实现有问题,可以依据Github上的lib/main.dart 来检查你的代码。

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
Widget titleSection = new Container(
padding: const EdgeInsets.all(32.0),
child: new Row(
children: [
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
new Container(
padding: const EdgeInsets.only(bottom: 8.0),
child: new Text(
‘Oeschinen Lake Campground’,
style: new TextStyle(
fontWeight: FontWeight.bold,
),
),
),
new Text(
‘Kandersteg, Switzerland’,
style: new TextStyle(
color: Colors.grey[500],
),
),
],
),
),
new Icon(
Icons.star,
color: Colors.red[500],
),
new Text(‘41’),
],
),
);
//…
}

Tip: 粘贴代码到工程中时,代码缩进可能错乱。如果是在IntelliJ中,可以有单机选择Reformat with Dart Style。或者在命令行中使用dartfmt命令。

Tip: 为体验更快开发过程,尝试使用Flutter的热加载功能。热加载使得在修改代码同时快速地在查看到修改后的效果,而不用重运行app。

##Step 3:实现按钮行(Button Section)

Button Section包含3列相同的布局——一个图标和一个文本。这行中3列均匀分布,并且文本和图标颜色是APP build()方法中设置的primary color。

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// title section implementation

return new MaterialApp(
title: ‘Flutter Demo’,
theme: new ThemeData(
primarySwatch: Colors.blue,
),

//…
}

由于创建每列的代码是相同的,最高效的办法就是创建一个嵌套函数,例如就定义为buildButtonColumn(),这个方法中创建包含一个图标和一个文本得组件,并且返回Column对象。

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//…

Column buildButtonColumn(IconData icon, String label) {
Color color = Theme.of(context).primaryColor;

return new Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
new Icon(icon, color: color),
new Container(
margin: const EdgeInsets.only(top: 8.0),
child: new Text(
label,
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
);
}
//…
}

这个创建方法中直接添加icon组件。将文本组件放于Container组件中来添加上边距,将icon与text分离开。

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//…

Widget buttonSection = new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
buildButtonColumn(Icons.call, ‘CALL’),
buildButtonColumn(Icons.near_me, ‘ROUTE’),
buildButtonColumn(Icons.share, ‘SHARE’),
],
),
);
//…
}

##Step 4:实现多行文本(Text Section)

由于文本太长,其实现我们赋值于一个变量。将文本放在Container中,四周边距设置32px。设置softwrap属性,这个属性表示当每行文本遇到句号或者逗号时是否需要换行。

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
//…

Widget textSection = new Container(
padding: const EdgeInsets.all(32.0),
child: new Text(

Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese Alps. Situated 1,578 meters above sea level, it is one of the larger Alpine Lakes. A gondola ride from Kandersteg, followed by a half-hour walk through pastures and pine forest, leads you to the lake, which warms to 20 degrees Celsius in the summer. Activities enjoyed here include rowing, and riding the summer toboggan run.
softWrap: true,
),
);
//…
}

##Step 5:实现头部图片(Image Section)

目前只剩头部图片部分还未实现。这张图片基于Creative Commons协议在网上是可以获取到的(当然学习过程,可以自己比较随意的拿一张图片进行)。由于图片较大且网络加载慢,所以在Step 0步骤中已经inlude进来并且修改了pubspec.yml文件,可以直接在本地进行访问。

body: new ListView(
children: [
new Image.asset(
‘images/lake.jpg’,
height: 240.0,
fit: BoxFit.cover,
),
// …
],
)

BoxFit.cover 告诉Framework图片需要尽可能的小但是需要充满显示部分。

##Step 6:整合

最后一步,将删除个步骤中定义的组件最终整合在一起。所有组件放置于ListView中。

import ‘package:flutter/material.dart’;

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
Widget titleSection = new Container(
padding: const EdgeInsets.all(32.0),
child: new Row(
children: [
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
new Container(
padding: new EdgeInsets.only(bottom: 8.0),
child: new Text(
‘Oeschinec lake Compground’,
style: new TextStyle(fontWeight: FontWeight.bold),
),
),
new Text(
‘Kandersteg, Switzerland’,
style: new TextStyle(color: Colors.grey[500]),
),
],
)),
new Icon(
Icons.star,
color: Colors.red[500],
),
new Text(‘41’)
],
),
);

最后

现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水!

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!

Android架构师之路很漫长,一起共勉吧!

力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水!

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!

Android架构师之路很漫长,一起共勉吧!

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐