flutter基礎(chǔ)faq

寫(xiě)在前面

這篇文章的目的是給純flutter萌新回答一些基礎(chǔ)問(wèn)題,ctrl+f/cmd+f 搜索關(guān)鍵字 控件名
本篇會(huì)持續(xù)更新
最后更新時(shí)間 2018-08-02

布局篇

flutter中 控件各司其職,基礎(chǔ)控件中基本只包含自己的功能
顯示內(nèi)容的負(fù)責(zé)顯示內(nèi)容,如Text負(fù)責(zé)文字,Image負(fù)責(zé)圖片
容器的負(fù)責(zé)容器,Row,Column,ListView等
尺寸位置的負(fù)責(zé)自己,Padding,Container,SizedBox等
觸摸手勢(shì)觸摸相關(guān):GestureDetector

flutter中在widget層級(jí)提倡組合模式,而不提倡繼承模式
比如你不應(yīng)該有一個(gè)class TextButton extend Text/RaisedButton這樣的方案出現(xiàn)
而應(yīng)該是


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),
          ),
        ),
      ),
    );
  }
}

類(lèi)似于這樣的方案

怎么設(shè)置寬度/高度

外面包一個(gè)SizedBox,設(shè)置height,Container也可以,還能加padding,背景顏色等
child可以是任意屬性

這樣的,我應(yīng)該怎么布局,那樣的我該怎么布局

這樣的問(wèn)題,通常歸結(jié)為不會(huì)劃分,總體來(lái)說(shuō)有以下幾點(diǎn)

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

我要給某某控件加一個(gè)點(diǎn)擊事件,沒(méi)有onTap,onPressed嗎?

GestureDetector包含了豐富的手勢(shì),包上你的控件就好了

GestureDetector(onTap:()=>print('點(diǎn)擊點(diǎn)擊'),child:Text('點(diǎn)擊'));
GestureDetector

這on開(kāi)頭的屬性全部都是系統(tǒng)定義好的回調(diào)
tap是點(diǎn)擊相關(guān),doubleTap是雙擊,longPress長(zhǎng)按
VerticalDrag相關(guān)是縱向拖動(dòng)
HorizontalDrag相關(guān)是橫向拖動(dòng)
pan相關(guān)是手指移動(dòng)
scale是雙指縮放手勢(shì)

behavior代表控件透明時(shí)是否可以響應(yīng)手勢(shì)

圓角怎么設(shè)置,背景圖片怎么設(shè)置

Container控件中有decoration屬性可以設(shè)置,要注意的一點(diǎn)是 這個(gè)屬性本身和color是互斥的,一旦設(shè)置decoration,需要去掉color屬性
BoxDecoration有很多屬性可以用

image.png

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

SnackBar 顯示沒(méi)有scaffold

Scaffold.of() called with a context that does not contain a Scaffold.

context層級(jí)用錯(cuò)了
這個(gè)是由于flutter層級(jí)中 這個(gè)context的父布局沒(méi)有Scaffold的原因,大概就是你是直接用的頁(yè)面級(jí)的context
page -> scaffold -> button
你用了page級(jí)的, 所以找不到了
解決方案就是中間套一個(gè)builder,用于"轉(zhuǎn)換"出一個(gè)位于scaffold后的context,然后就可以了
page -> scaffold -> Builder ->button

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('測(cè)試'),
        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('內(nèi)容'),
        ));
  }
}

ListView 套ListView 報(bào)錯(cuò)

這個(gè)是因?yàn)長(zhǎng)istView是會(huì)占滿父布局的控件,你需要給內(nèi)部的ListView加一個(gè)高度/寬度限制,如果外部是縱向,則需要高度,外部是橫向,需要寬度
可以看你的情況,可以使用SizedBox,Container,AspectRatio這樣的控件

適配篇

我個(gè)人理解的最佳適配方案是當(dāng)年那套.文字流式,圖片寬高比

image.png

原文鏈接

圖片應(yīng)該在設(shè)計(jì)時(shí)給定寬高比
文字的話沒(méi)特殊要求直接自適應(yīng)
控件彈性的意思,控件高度是固定的,然后占滿屏幕,或者百分比,內(nèi)部的東西左對(duì)齊的左對(duì)齊,右對(duì)齊的右對(duì)齊,剩下的占滿剩余區(qū)域,或者比例分配

dart相關(guān)語(yǔ)法篇

先定義一個(gè)類(lèi),后面用到

class User{
  String name;
  void print(){
    print(this.name);
  }
}

?. 什么意思

以下兩種寫(xiě)法是等效的

void foo(User user){
  user?.print();
}
void foo(User user){
  if(user != null){
    user.print();
  }
}

??啥意思

以下兩種寫(xiě)法是等效的

var text = user?.name ?? "默認(rèn)名字";
String text;
if(user != null && user.name != null){
  text = user.name;
}else{
  text = "默認(rèn)名字";
}

??= 啥意思

User create(User user){
  var user ??= User();
  return user;
}

User create(User user){
  if(user == null){
    user = User();
  }
  return user;
}

typedef 是啥意思

在dart語(yǔ)言中,函數(shù)是一等公民,函數(shù)本身也是對(duì)象
可以被賦值給變量

舉個(gè)栗子
這個(gè)是在Hero動(dòng)畫(huà)中用到的
final CreateRectTween createRectTween;

查看下CreateRectTween的定義,會(huì)發(fā)現(xiàn)有這么一個(gè)寫(xiě)法
typedef Tween<Rect> CreateRectTween(Rect begin, Rect end);

簡(jiǎn)單的說(shuō): 這個(gè)是一個(gè)函數(shù)類(lèi)型,名稱(chēng)是CreateRectTween,這個(gè)函數(shù)接收兩個(gè)Rect值,返回一個(gè)Tween對(duì)象
使用的時(shí)候就是這樣的

Hero(
 createRectTween:(Rect begin,Rect end){ 
   return MaterialRectArcTween(begin:begin,end:end);
  }
);

拆開(kāi)來(lái)寫(xiě)

CreateRectTween method = (Rect begin,Rect end){ 
   return MaterialRectArcTween(begin:begin,end:end);
};
Hero(
 createRectTween:method,
);

android studio 中 怎么編輯android項(xiàng)目,沒(méi)有代碼提示,還報(bào)錯(cuò)

open android module

這里需要在一個(gè)新窗口中打開(kāi)android項(xiàng)目

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容