这篇文章的目的是给纯flutter萌新回答一些基础问题,ctrl+f/cmd+f 搜索关键字 控件名
本篇会持续更新
最后更新时间 2018-08-02android
flutter中 控件各司其职,基础控件中基本只包含本身的功能
显示内容的负责显示内容,如Text负责文字,Image负责图片
容器的负责容器,Row,Column,ListView等
尺寸位置的负责本身,Padding,Container,SizedBox等
触摸手势触摸相关:GestureDetectorbash
flutter中在widget层级提倡组合模式,而不提倡继承模式
好比你不该该有一个class TextButton extend Text/RaisedButton
这样的方案出现
而应该是app
class TextButton extends StatelessWidget {
final Function onPressed;
final String text;
final Color color;
final double fontSize;
final EdgeInsets padding;
const TextButton({
Key key,
this.onPressed,
this.text = "",
this.color = Colors.black87,
this.fontSize = 14.0,
this.padding = EdgeInsets.zero,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return new Material(
color: Colors.transparent,
child: InkWell(
onTap: onPressed,
child: Padding(
padding: padding,
child: new Text(
text,
style: new TextStyle(fontSize: fontSize, color: color),
),
),
),
);
}
}
复制代码
相似于这样的方案less
外面包一个SizedBox,设置height,Container也能够,还能加padding,背景颜色等
child能够是任意属性ide
这样的问题,一般归结为不会划分,整体来讲有如下几点函数
GestureDetector包含了丰富的手势,包上你的控件就行了布局
GestureDetector(onTap:()=>print('点击点击'),child:Text('点击'));
复制代码
behavior
表明控件透明时是否能够响应手势测试
Container控件中有decoration
属性能够设置,要注意的一点是 这个属性自己和color是互斥的,一旦设置decoration,须要去掉color属性
BoxDecoration有不少属性能够用
动画
Scaffold.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 ->buttonui
import 'package:flutter/material.dart';
import 'package:kappbar/kappbar.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppBar(
title: Text('测试'),
elevation: 0.0,
),
body: Container(
child: Builder(
// 这里套一层
builder: (ctx) => RaisedButton(
onPressed: () => _click(ctx), //把builder给的ctx传递给方法
)),
),
);
}
void _click(BuildContext context) {
// 这里使用传入的context就行了
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('内容'),
));
}
}
复制代码
这个是由于ListView是会占满父布局的控件,你须要给内部的ListView加一个高度/宽度限制,若是外部是纵向,则须要高度,外部是横向,须要宽度
能够看你的状况,可使用SizedBox,Container,AspectRatio这样的控件
我我的理解的最佳适配方案是当年那套.文字流式,图片宽高比
图片应该在设计时给定宽高比
文字的话没特殊要求直接自适应
控件弹性的意思,控件高度是固定的,而后占满屏幕,或者百分比,内部的东西左对齐的左对齐,右对齐的右对齐,剩下的占满剩余区域,或者比例分配
先定义一个类,后面用到
class User {
String name;
void print() {
print(this.name);
}
}
复制代码
如下两种写法是等效的
void foo(User user) {
user?.print();
}
复制代码
void foo(User user) {
if (user != null) {
user.print();
}
}
复制代码
如下两种写法是等效的
var text = user?.name ?? "默认名字";
复制代码
String text;
if (user != null && user.name != null) {
text = user.name;
} else {
text = "默认名字";
}
复制代码
User create(User user){
var user ??= User();
return user;
}
复制代码
User create(User user){
if(user == null){
user = User();
}
return user;
}
复制代码
在dart语言中,函数是一等公民,函数自己也是对象
能够被赋值给变量
举个栗子
这个是在Hero动画中用到的
final CreateRectTween createRectTween;
查看下CreateRectTween的定义,会发现有这么一个写法
typedef Tween<Rect> CreateRectTween(Rect begin, Rect end);
简单的说: 这个是一个函数类型,名称是CreateRectTween
,这个函数接收两个Rect值,返回一个Tween对象
使用的时候就是这样的
Hero(
createRectTween:(Rect begin,Rect end){
return MaterialRectArcTween(begin:begin,end:end);
}
);
复制代码
拆开来写
CreateRectTween method = (Rect begin,Rect end){
return MaterialRectArcTween(begin:begin,end:end);
};
Hero(
createRectTween:method,
);
复制代码