Flutter基础faq
文章目录
写在前面
这篇文章的目的是给纯 flutter 萌新回答一些基础问题,ctrl+f/cmd+f 搜索关键字 控件名 本篇会持续更新 最后更新时间 2018-08-02
布局篇
flutter 中 控件各司其职,基础控件中基本只包含自己的功能 显示内容的负责显示内容,如 Text 负责文字,Image 负责图片 容器的负责容器,Row,Column,ListView 等 尺寸位置的负责自己,Padding,Container,SizedBox 等 触摸手势触摸相关:GestureDetector
flutter 中在 widget 层级提倡组合模式,而不提倡继承模式
比如你不应该有一个class TextButton extend Text/RaisedButton
这样的方案出现
而应该是
1
2class TextButton extends StatelessWidget {
3 final Function onPressed;
4 final String text;
5 final Color color;
6 final double fontSize;
7 final EdgeInsets padding;
8
9 const TextButton({
10 Key key,
11 this.onPressed,
12 this.text = "",
13 this.color = Colors.black87,
14 this.fontSize = 14.0,
15 this.padding = EdgeInsets.zero,
16 }) : super(key: key);
17
18 @override
19 Widget build(BuildContext context) {
20 return new Material(
21 color: Colors.transparent,
22 child: InkWell(
23 onTap: onPressed,
24 child: Padding(
25 padding: padding,
26 child: new Text(
27 text,
28 style: new TextStyle(fontSize: fontSize, color: color),
29 ),
30 ),
31 ),
32 );
33 }
34}
类似于这样的方案
怎么设置宽度/高度
外面包一个 SizedBox,设置 height,Container 也可以,还能加 padding,背景颜色等 child 可以是任意属性
这样的,我应该怎么布局,那样的我该怎么布局
这样的问题,通常归结为不会划分,总体来说有以下几点
- 横向多控件,用 Row 包起来,顺序排下去
- 纵向多控件,用 Column 包起来,顺序排下去
- 单页显示不下的,用 ListView,默认纵向,修改 scrollDirection 属性,ListView 在 flutter 中就是 scrollView
我要给某某控件加一个点击事件,没有 onTap,onPressed 吗
GestureDetector 包含了丰富的手势,包上你的控件就好了
1GestureDetector(onTap:()=>print('点击点击'),child:Text('点击'));
behavior
代表控件透明时是否可以响应手势
圆角怎么设置,背景图片怎么设置
Container 控件中有decoration
属性可以设置,要注意的一点是 这个属性本身和 color 是互斥的,一旦设置 decoration,需要去掉 color 属性
BoxDecoration 有很多属性可以用
SnackBar 显示没有 scaffold
1Scaffold.of() called with a context that does not contain a Scaffold.
context 层级用错了 这个是由于 flutter 层级中 这个 context 的父布局没有 Scaffold 的原因,大概就是你是直接用的页面级的 context page -> scaffold -> button 你用了 page 级的, 所以找不到了 解决方案就是中间套一个 builder,用于"转换"出一个位于 scaffold 后的 context,然后就可以了 page -> scaffold -> Builder ->button
1import 'package:flutter/material.dart';
2import 'package:kappbar/kappbar.dart';
3
4class HomePage extends StatefulWidget {
5 @override
6 _HomePageState createState() => _HomePageState();
7}
8
9class _HomePageState extends State<HomePage> {
10 @override
11 Widget build(BuildContext context) {
12 return Scaffold(
13 appBar: MyAppBar(
14 title: Text('测试'),
15 elevation: 0.0,
16 ),
17 body: Container(
18 child: Builder( // 这里套一层
19 builder: (ctx) => RaisedButton(
20 onPressed: () => _click(ctx), //把builder给的ctx传递给方法
21 )),
22 ),
23 );
24 }
25
26 void _click(BuildContext context) {
27 // 这里使用传入的context就好了
28 Scaffold.of(context).showSnackBar(SnackBar(
29 content: Text('内容'),
30 ));
31 }
32}
ListView 套 ListView 报错
这个是因为 ListView 是会占满父布局的控件,你需要给内部的 ListView 加一个高度/宽度限制,如果外部是纵向,则需要高度,外部是横向,需要宽度 可以看你的情况,可以使用 SizedBox,Container,AspectRatio 这样的控件
这样的道理也适用于 Column 内部嵌套 ListView 的情况
适配篇
我个人理解的最佳适配方案是当年那套.文字流式,图片宽高比
图片应该在设计时给定宽高比 文字的话没特殊要求直接自适应 控件弹性的意思,控件高度是固定的,然后占满屏幕,或者百分比,内部的东西左对齐的左对齐,右对齐的右对齐,剩下的占满剩余区域,或者比例分配
dart 相关语法篇
先定义一个类,后面用到
1class User{
2 String name;
3 void print(){
4 print(this.name);
5 }
6}
?. 什么意思
以下两种写法是等效的
1void foo(User user){
2 user?.print();
3}
1void foo(User user){
2 if(user != null){
3 user.print();
4 }
5}
??啥意思
以下两种写法是等效的
1var text = user?.name ?? "默认名字";
1String text;
2if(user != null && user.name != null){
3 text = user.name;
4}else{
5 text = "默认名字";
6}
??= 啥意思
1User create(User user){
2 var user ??= User();
3 return user;
4}
1User create(User user){
2 if(user == null){
3 user = User();
4 }
5 return user;
6}
typedef 是啥意思
在 dart 语言中,函数是一等公民,函数本身也是对象 可以被赋值给变量
举个栗子
这个是在 Hero 动画中用到的
final CreateRectTween createRectTween;
查看下 CreateRectTween 的定义,会发现有这么一个写法
typedef Tween<Rect> CreateRectTween(Rect begin, Rect end);
简单的说: 这个是一个函数类型,名称是CreateRectTween
,这个函数接收两个 Rect 值,返回一个 Tween 对象
使用的时候就是这样的
1Hero(
2 createRectTween:(Rect begin,Rect end){
3 return MaterialRectArcTween(begin:begin,end:end);
4 }
5);
拆开来写
1CreateRectTween method = (Rect begin,Rect end){
2 return MaterialRectArcTween(begin:begin,end:end);
3};
4Hero(
5 createRectTween:method,
6);
android studio 中 怎么编辑 android 项目,没有代码提示,还报错