這篇文章的目的是給純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,
);
複製代碼