flutter基础faq

作者: 做人要简单 | 来源:发表于2018-08-02 16:49 被阅读31次

    写在前面

    这篇文章的目的是给纯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这样的方案出现
    而应该是

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

    类似于这样的方案

    怎么设置宽度/高度

    外面包一个SizedBox,设置height,Container也可以,还能加padding,背景颜色等
    child可以是任意属性

    这样的,我应该怎么布局,那样的我该怎么布局

    这样的问题,通常归结为不会划分,总体来说有以下几点

    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 ->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('测试'),
            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){
      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项目

    相关文章

      网友评论

        本文标题:flutter基础faq

        本文链接:https://www.haomeiwen.com/subject/mwodpftx.html