一、水平布局Row

Row控件可以分为非灵活排列和灵活排列两种,灵活的可以在外边加入Expanded使用

两者混用:

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: '',
home: new Scaffold(
appBar: new AppBar(title: new Text('hello row')),
body: new Row(
children: <Widget>[
Expanded( //灵活使用
child: new RaisedButton(
onPressed: () {},
color: Colors.blue,
child: new Text('Blue Button'),
)),
new RaisedButton(
onPressed: () {},
color: Colors.green,
child: new Text('Green Button'),
),
],
),
),
);
}
}

二、垂直布局Column

对齐方式:

  • main轴: 比如Row组件,那水平就是主轴。比如Column组件,那垂直就是主轴。

  • cross轴:比如Row组件,那垂直就是副轴。比如Columu组件,那水平就是副轴。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: '',
home: new Scaffold(
appBar: new AppBar(title: new Text('hello Column')),
body: new Center(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center, //副轴对齐方式
mainAxisAlignment: MainAxisAlignment.center, //主轴对齐方式
children: <Widget>[
new Text('君不见黄河之水天上来,',
style: TextStyle(
color: Colors.black,
fontSize: 30.0,
)),
new Text('东流到海不复还,',
style: TextStyle(
color: Colors.redAccent,
fontSize: 30.0,
)),
],
),
),
),
);
}
}

三、层叠布局Stack

alignment属性:控制层叠的位置

alignment: const FractionalOffset(dx,dy) dx、dy 为0~1
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var stack = new Stack(
alignment: const FractionalOffset(0.5, 0.8),
children: <Widget>[
new CircleAvatar(
backgroundImage:
new NetworkImage('https://profile.csdnimg.cn/0/5/2/1_jyd0124'),
radius: 100.0,
),
new Container(
decoration: BoxDecoration(
color: Colors.cyan,
),
child: new Text('blog_jyd0124'),
padding: EdgeInsets.all(5.0),
),
],
);
// TODO: implement build
return MaterialApp(
title: '',
home: new Scaffold(
appBar: new AppBar(title: new Text('hello Stack')),
body: new Center(child: stack),
),
);
}
}

说明:CircleAvatar组件经常用来作头像,radius属性可以设置图片的弧度

Stack布局高级用法:Positioned(层叠定位组件)用于层叠多个组件

var stack = new Stack(
//alignment: const FractionalOffset(0.5, 0.8),
children: <Widget>[
new CircleAvatar(
backgroundImage:
new NetworkImage('https://profile.csdnimg.cn/0/5/2/1_jyd0124'),
radius: 100.0,
),
new Positioned(
bottom: 20.0,
left: 60.0,
child: new Container(
decoration: BoxDecoration(
color: Colors.cyan,
),
child: new Text('blog_jyd0124'),
padding: EdgeInsets.all(5.0),
)),
],
);

四、卡片布局Card

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
var card = new Card(
child: new Column(
children: <Widget>[
ListTile(
title: new Text('成都市',style:TextStyle(fontWeight:FontWeight.w100)),
subtitle: new Text('QQ:150048****'),
leading: new Icon(Icons.account_balance,color: Colors.blue,),
),
ListTile(
title: new Text('西安市',style:TextStyle(fontWeight:FontWeight.w100)),
subtitle: new Text('QQ:150048****'),
leading: new Icon(Icons.account_balance,color: Colors.blue,),
),
ListTile(
title: new Text('兰州市',style:TextStyle(fontWeight:FontWeight.w100)),
subtitle: new Text('QQ:150048****'),
leading: new Icon(Icons.account_balance,color: Colors.blue,),
),
],
)
);
// TODO: implement build
return MaterialApp(
title: '',
home: new Scaffold(
appBar: new AppBar(title: new Text('hello Column')),
body: new Center(child: card),
),
);
}
}

五、页面的导航和返回

1.RaisedButton按钮组件

两个常用属性:

  • child:可以放入容器,图标,文字
  • onPressed:事件的响应,一般调用Navigator组件

2.Navigator组件

  • Navigator.push()   =====跳转到下一个页面,接受两个参数一个是上下文context,另一个是要跳转的函数。
  • Navigator.pop()     =====返回到上一个页面,接受一个context(上下文)参数
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
title: '导航演示',
home: new FirstScreen(),
)); class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(''),
),
body: Center(
child: RaisedButton(
child: Text('跳转'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => new SecondScreen(),
));
}),
),
);
}
} class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: new Scaffold(
appBar: new AppBar(title: new Text('跳转完成')),
body: new Center(
child: RaisedButton(
child: Text('返回'),
onPressed: () {
Navigator.pop(context);
},
)),
),
);
}
}

六、导航参数的传递和接收

import 'package:flutter/material.dart';

class Product {
String title;
String description;
Product(this.title, this.description);
} void main() {
runApp(MaterialApp(
title: '导航的数据传递和接受',
home: ProductList(
products:
List.generate(, (i) => Product('商品 $i', '这是一个商品详情,编号为 $i'))),
));
} class ProductList extends StatelessWidget {
final List<Product> products;
ProductList({Key key, @required this.products}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('商品列表'),
),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(products[index].title),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ProductDetail(product: products[index])));
},
);
}),
);
}
} class ProductDetail extends StatelessWidget {
final Product product;
ProductDetail({Key key, @required this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('${product.title}')),
body: Center(
child: Text('${product.description}'),
),
);
}
}
  • 小技巧 :Android Studio 中输入stless可以自动生成StatelessWidget,但在VSCode中,需先安装Awesome Flutter snippets插件,然后输入stlss;

七、页面跳转并返回数据

1.异步请求与等待

使用async...await

2.SnackBar

显示提示信息的一个控件,会自动隐藏,SnackBar是以Scaffold的showSnackBar()方法来进行显示的;

3.返回数据

Navigator.pop()带第二个参数就可以

import 'package:flutter/material.dart';

void main() {
runApp(MaterialApp(
title: '页面跳转返回数据',
home: FirstPage(),
));
} class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('得到一个数字')),
body: Center(
child: RouteButton(),
),
);
}
} class RouteButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
navigateToNumber(context);
},
child: Text('Get'),
);
} navigateToNumber(BuildContext context) async {
//async是启用异步方法
final result = await Navigator.push(
//等待
context,
MaterialPageRoute(builder: (context) => Number()));
Scaffold.of(context).showSnackBar(SnackBar(content: Text('$result')));
}
} class Number extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('我是你找的数')),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text('两位数'),
onPressed: () {
Navigator.pop(context, '两位数:98');
},
),
RaisedButton(
child: Text('三位数'),
onPressed: () {
Navigator.pop(context, '三位数:124');
},
),
],
),
),
);
}
}

八、静态资源和项目图片的处理

在pubspec.yaml文件中声明资源文件

测试:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Image.asset('images/csdn.jpg'),
);
}
}

九、客户端打包(Android)

1. 配置APP的图片的目录    /android/app/src/main/res/

2.配置APP的名称、图标和系统权限的目录    /android/app/src/main/AndroidManifest.xml

3.生成keystore

<1> flutter doctor -v  命令找到keytool.exe的位置

<2>cd进入这个目录,然后执行下面命令就会在D盘下面有一个jks的文件

  keytool -genkey -v -keystore D:\key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key

<3>到项目目录下的android文件夹下,创建一个名为key.properties的文件,并打开粘贴下面的代码

storePassword=<password from previous step>    //输入上一步创建KEY时输入的 密钥库 密码
keyPassword=<password from previous step> //输入上一步创建KEY时输入的 密钥 密码
keyAlias=key
storeFile=<E:/key.jks> //key.jks的存放路径

4.配置key注册

<1>进入项目目录的/android/app/build.gradle文件,在android{这一行前面,加入如下代码

def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

<2>把如下代码进行替换

替换成的代码:

signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}

5.生成apk

在终端输入 flutter build apk,这时候打包成功,可在build\app\outputs\apk\release\找到

然后在终端输入flutter install 直接安装到

Flutter开发之Widget布局和页面导航的更多相关文章

  1. Flutter开发之Widget学习

    一.Text 组件 属性  textAlign: TextAlign.left,                           -----文本对齐方式  maxLines: 1,        ...

  2. 轻量级应用开发之(10) UINavigationController导航控制器

    一 多控制器 1)一个iOS的app很少只由一个控制器组成,除非这个app极其简单2)当app中有多个控制器的时候,我们就需要对这些控制器进行管理3)有多个view时,可以用一个大的view去管理1个 ...

  3. iOS开发之widget实现

    前言     iOS extension的出现,方便了用户查看应用的服务,比如用户可以在Today的widgets中查看应用的简略信息,然后点击进入相关的应用界面.暂且不表网络上现有的widget文章 ...

  4. Android 4.0开发之GridLayOut布局实践

    在上一篇教程中http://blog.csdn.net/dawanganban/article/details/9952379,我们初步学习了解了GridLayout的布局基本知识,通过学习知道,Gr ...

  5. IOS开发之UI布局

    前言:本篇随笔会经常更新,随着本人对布局的深入学习,会不断补充新的知识.新的使用技巧.新的认识等等. 1.Autoresizing(在代码中使用) 先简单的看看下面的代码,以及左边运行出来的效果,然后 ...

  6. 浅谈android4.0开发之GridLayout布局

    作者:李响 本文重点讲述了自android4.0版本号后新增的GridLayout网格布局的一些基本内容,并在此基础上实现了一个简单的计算器布局框架.通过本文,您可以了解到一些android UI开发 ...

  7. Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)

    Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下:       1.Vi ...

  8. 个人博客开发之xadmin 布局和后台样式

    项目源码下载:http://download.vhosts.cn 一. xadmin 后台配置注册信息 1. 在apps 的blogs 和 users 两个app中添加adminx.py文件 vim ...

  9. 【Android UI】Android开发之View的几种布局方式及实践

    引言 通过前面两篇: Android 开发之旅:又见Hello World! Android 开发之旅:深入分析布局文件&又是“Hello World!” 我们对Android应用程序运行原理 ...

随机推荐

  1. Linux Cgroup浅析

    cgroup从2.6.4引入linux内核主线,目前默认已启用该特性.在cgroup出现之前,只能对一个进程做资源限制,比如通过sched_setaffinity设置进程cpu亲和性,使用ulimit ...

  2. 使用iview遇到问题记录总结

    1.iview设置日期不可用,设置开始开始时间早于结束时间 官网示例,设置今天之前不可选,但是不能识别thisdisabledDate (date) { return date && ...

  3. 打造m3u8视频(流视频)下载解密合并器(kotlin)

    本文是对我原创工具m3u8视频下载合并器关键代码解析及软件实现的思路的讲解,想要工具的请跳转链接 1.思路说明 思路挺简单,具体步骤如下: 下载m3u8文件 解析m3u8文件获得ts文件列表 根据文件 ...

  4. MySQL快速回顾:计算字段与函数

    9.1 计算字段 存储在数据库表中的数据一般不是应用程序所需要的格式.比如: 如果想要在一个字段中既显示公司名,又显示公式的地址,但这两个信息一般包含在不同的表列中. 城市.州和邮政编码存储在不同的列 ...

  5. Friday the Thirteenth 黑色星期五 USACO 模拟 超级简单做法

    1003: 1.1.3 Friday the Thirteenth 黑色星期五 时间限制: 1 Sec  内存限制: 128 MB提交: 8  解决: 8[提交] [状态] [讨论版] [命题人:外部 ...

  6. 解决el-tree lazy懒加载时,连续勾选前两个子节点后第二次进入默认选中时,将父节点也勾选的问题

    在用到el-tree的懒加载和默认勾选功能时,若第一次勾选前几个连续节点,第二次进入默认勾选时,由于el-tree子节点尚未完全加载(只加载出来前几个),默认勾选已经开始(已加载出来的子节点被默认勾选 ...

  7. FFT 入门

    推荐博客 :https://oi.men.ci/fft-notes/ 卷积的理解 : https://www.zhihu.com/question/22298352?rf=21686447 题目链接 ...

  8. java: integer number is too large

    今天想定义一个类常量,结果如下面那样定义,确报错了.error is: Integer number too large public static final Long STARTTIME = 14 ...

  9. rhel

    1.查看硬盘大小 df -h 2.查看内存大小 free -h 3.配置主键名称 vim /etc/hostname# 查看 hostnamehostname 4.挂载镜像 mkdir -p /med ...

  10. 高通量计算框架HTCondor(五)——分布计算

    目录 1. 正文 1.1. 任务描述文件 1.2. 提交任务 1.3. 返回结果 2. 相关 1. 正文 1.1. 任务描述文件 前文提到过,HTCondor是通过condor_submit命令将提交 ...