前言一:接下来一段时间我会陆续更新一些列Flutter文字教程前端
更新进度: 每周至少两篇;vue
更新地点: 首发于公众号,次日更新于掘金、思否、开发者头条等地方;算法
更多交流: 能够添加个人微信 372623326,关注个人微博:coderwhyshell
但愿你们能够 帮忙转发,点击在看,给我更多的创做动力。bash
建立Flutter项目有两种方式:
经过命令行建立
和经过开发工具建立
微信
经过命令行建立很是简单,在终端输入如下命令便可:数据结构
flutter create learn_flutter
复制代码
我这里也能够直接经过Android Studio来进行建立:app
Start a new Flutter project
,以后填写相关的信息便可,这里再也不赘述咱们讲建立的应用起来跑在模拟器上(我这里选择iPhone模拟器,Android也能够),会看到以下效果:less
默认项目分析:ide
lib
文件夹,里面会存放咱们编写的Flutter代码;main.dart
,它是咱们Flutter启动的入口文件
,里面有main函数
;默认代码分析:
+
符号,上面显示的数字会递增;不认识
的代码,不知道这个内容是如何编写出来的;做为初学者,个人建议是将其中全部的代码所有删除掉,从零去建立里面的代码,这样咱们才能对Flutter应用程序的结构很是清晰;
作任何的开发,咱们都是从祖传的Hello World
开始,那么如今咱们的需求来了:
下面,咱们就动手开始编写Hello World:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(Text("Hello World", textDirection: TextDirection.ltr));
}
复制代码
固然,上面的代码咱们已经实现了在界面上显示Hello World:
没有居中
,字体也有点小
;上面的代码咱们有一些比较熟悉,有一些并不清楚是什么:
入口都是main函数
,而Flutter是Dart编写的,因此入口也是main函数;Material是什么呢
?runApp()函数
又是什么呢?下面,咱们对不认识的代码进行一些分析。
runApp是Flutter内部提供的一个函数,当咱们启动一个Flutter应用程序时就是从调用这个函数开始的
void runApp(Widget app) {
...省略代码
}
复制代码
该函数让咱们传入一个东西:Widget?
咱们先说Widget的翻译:
Widget到底什么东西呢?
所看到的内容
几乎都是Widget,甚至是内边距的设置
,咱们也须要使用一个叫Padding的Widget
来作;runApp函数让咱们传入的就是一个Widget:
material是什么呢?
设计风格
,或者叫设计语言
、设计规范
等;颜色
、文字的排版
、响应动画与过分
、填充
等等;Material风格的Widget
;Text小部件分析:
class Text extends StatelessWidget {
const Text(
this.data, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
});
}
复制代码
StatelessWidget简单介绍:
abstract class StatelessWidget extends Widget {
// ...省略代码
}
复制代码
咱们发现如今的代码并非咱们想要的最终结果:
Center
;咱们修改代码以下:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(
Center(
child: Text(
"Hello World",
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 36),
),
)
);
}
复制代码
目前咱们虽然能够显示HelloWorld,可是咱们发现最底部的背景是黑色,而且咱们的页面并不够结构化。
导航栏
,会有一些背景颜色
等在开发当中,咱们并不须要从零去搭建这种结构化的界面,咱们可使用Material库,直接使用其中的一些封装好的组件来完成一些结构的搭建。
咱们经过下面的代码来实现:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: Center(
child: Text(
"Hello World",
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 36),
),
),
),
)
);
}
复制代码
在最外层包裹一个MaterialApp
Scaffold是什么呢?
脚手架
,脚手架的做用就是搭建页面的基本结构;appBar
和body
;title属性
;咱们可让界面中存在更多的元素:
嵌套太多
了,不要着急,咱们后面会对代码重构的import 'package:flutter/material.dart';
main(List<String> args) {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Checkbox(
value: true,
onChanged: (value) => print("Hello World")),
Text(
"赞成协议",
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 20),
)
],
),
),
),
)
);
}
复制代码
不少学习Flutter的人,都会被Flutter的嵌套
劝退,当代码嵌套过多时,结构很容易看不清晰。
这里有两点我先说明一下:
可是,咱们开发一个这么简单的程序就出现如此多的嵌套,若是应用程序更复杂呢?
如何建立本身的Widget呢?
在上面的案例中对代码的重构,咱们使用StatelessWidget便可,因此咱们接下来学习一下若是利用StatelessWidget来对咱们的代码进行重构;
StatefulWidget咱们放到后面的一个案例中来学习;
StatelessWidget一般是一些没有状态(State,也能够理解成data)须要维护的Widget:
咱们来看一下建立一个StatelessWidget的格式:
class MyStatelessWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return <返回咱们的Widget要渲染的Widget,好比一个Text Widget>;
}
}
复制代码
build方法的解析:
build方法什么状况下被执行呢?:
如今咱们就能够经过StatelessWidget来对咱们的代码进行重构了
重构后的代码以下:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: HomeContent(),
),
)
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Checkbox(
value: true,
onChanged: (value) => print("Hello World")),
Text(
"赞成协议",
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 20),
)
],
),
);
}
}
复制代码
咱们先来看一下案例的最终展现效果:
在咱们的案例中,很明显一个产品的展现就是一个大的Widget,这个Widget包含以下Widget:
另外,三个展现的标题、描述、图片都是不同的,因此咱们可让Parent Widget来决定内容:
class ProductItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
ProductItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(title, style: TextStyle(fontSize: 24)),
Text(desc, style: TextStyle(fontSize: 18)),
Image.network(imageURL)
],
);
}
}
复制代码
如今咱们就能够建立三个ProductItem来让他们展现了:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.blueAccent
),
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ProductItem("Apple1", "Macbook Product1", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg"),
ProductItem("Apple2", "Macbook Product2", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imm9u5zj30u00k0adf.jpg"),
ProductItem("Apple3", "Macbook Product3", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imqlouhj30u00k00v0.jpg"),
],
);
}
}
复制代码
运行效果以下:
如何能够解决这个问题呢?
若是咱们但愿整个内容距离屏幕的边缘有必定的间距,怎么作呢?
咱们如今但愿给全部的商品也添加一个内边距,而且还有边框,怎么作呢?
咱们但愿给图片和文字之间添加一些间距,怎么作呢?
最后,我给出最终实现代码:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.blueAccent
),
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: <Widget>[
ProductItem("Apple1", "Macbook Product1", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg"),
ProductItem("Apple2", "Macbook Product2", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imm9u5zj30u00k0adf.jpg"),
ProductItem("Apple3", "Macbook Product3", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imqlouhj30u00k00v0.jpg"),
],
),
);
}
}
class ProductItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
ProductItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
border: Border.all()
),
child: Column(
children: <Widget>[
Text(title, style: TextStyle(fontSize: 24)),
Text(desc, style: TextStyle(fontSize: 18)),
SizedBox(height: 10,),
Image.network(imageURL)
],
),
);
}
}
复制代码
备注:全部内容首发于公众号,以后除了Flutter也会更新其余技术文章,TypeScript、React、Node、uniapp、mpvue、数据结构与算法等等,也会更新一些本身的学习心得等,欢迎你们关注