flutter基礎faq

寫在前面

這篇文章的目的是給純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

這樣的,我應該怎麼佈局,那樣的我該怎麼佈局

這樣的問題,一般歸結爲不會劃分,整體來講有如下幾點函數

  1. 橫向多控件,用Row包起來,順序排下去
  2. 縱向多控件,用Column包起來,順序排下去
  3. 單頁顯示不下的,用ListView,默認縱向,修改scrollDirection屬性,ListView在flutter中就是scrollView

我要給某某控件加一個點擊事件,沒有onTap,onPressed嗎?

GestureDetector包含了豐富的手勢,包上你的控件就行了佈局

GestureDetector(onTap:()=>print('點擊點擊'),child:Text('點擊'));  
複製代碼

GestureDetector

這on開頭的屬性所有都是系統定義好的回調
tap是點擊相關,doubleTap是雙擊,longPress長按
VerticalDrag相關是縱向拖動
HorizontalDrag相關是橫向拖動
pan相關是手指移動
scale是雙指縮放手勢

behavior表明控件透明時是否能夠響應手勢測試

圓角怎麼設置,背景圖片怎麼設置

Container控件中有decoration屬性能夠設置,要注意的一點是 這個屬性自己和color是互斥的,一旦設置decoration,須要去掉color屬性
BoxDecoration有不少屬性能夠用
動畫

image.png

顏色,圖片,邊框,圓角,陰影,漸變色,形狀

SnackBar 顯示沒有scaffold

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 報錯

這個是由於ListView是會佔滿父佈局的控件,你須要給內部的ListView加一個高度/寬度限制,若是外部是縱向,則須要高度,外部是橫向,須要寬度
能夠看你的狀況,可使用SizedBox,Container,AspectRatio這樣的控件

適配篇

我我的理解的最佳適配方案是當年那套.文字流式,圖片寬高比

image.png

原文連接

圖片應該在設計時給定寬高比
文字的話沒特殊要求直接自適應
控件彈性的意思,控件高度是固定的,而後佔滿屏幕,或者百分比,內部的東西左對齊的左對齊,右對齊的右對齊,剩下的佔滿剩餘區域,或者比例分配

dart相關語法篇

先定義一個類,後面用到

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;  
}  
  
複製代碼

typedef 是啥意思

在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,  
);  
複製代碼

android studio 中 怎麼編輯android項目,沒有代碼提示,還報錯

open android module
這裏須要在一個新窗口中打開android項目
相關文章
相關標籤/搜索