Flutter笔记-控件1

前言

还未安装环境的童鞋可以看下这个flutter环境安装
不错的学习网站:
1.flutter官方中文网站:https://flutterchina.club/docs/
2.Flutter七日游(张风捷特烈):https://juejin.im/user/5b42c0656fb9a04fe727eb37
3.咸鱼官方博客:https://zhuanlan.zhihu.com/xytech
ps:前2个都比较基础,最后一个比较深入

计划将基础控件,布局控件结束后,再进行自定义绘制控件

基础控件

widget: 小器具,装饰品,窗口小部件;这里统一称为控件

要学flutter,肯定要先学会怎么使用控件
统计了一部分控件,做了一个表格:

widgetflutterandroid
文本TextTextView
按钮
漂浮按钮RaisedButtonButton
扁平按钮FlatButton
边框按钮OutlineButton
图片按钮IconButtonImageButton
浮动动作按钮FloatingActionButtonFloatingActionButton
编辑框TextFieldEditText
图片ImageImageView
图标Icon
复选框CheckboxCheckBox
单选框RadioRadioButton
单选开关SwitchSwitch
底部弹框SnackBarSnackBar
滚动控件SingleChildScrollViewScrollView
线性滚动列表ListView RecyclerView(LinearLayoutManager)
网格滚动列表GridView RecyclerViewGridLayoutManager
自定义滚动CustomScrollView RecyclerView(StaggeredGridLayoutManager)
滚动条ScrollBar
弹框DialogAlertDialog
进度条ProgressIndicatorProgressBar
圆形进度条CircularProgressIndicator
线性进度条LinearProgressIndicator
滑动条SliderSeekBar
导航栏AppBarToolBar
选项栏TapBar+TapBarView
底部导航栏BottomNavigationBar
分割线Divider
侧滑菜单DrawerDrawerLayout
底抽屉BottomSheetBottomSheet
流式标签ChipChip
圆形头像CircleAvatar

控件很多,怎么学习来快呢?(ps:自我感觉)

学习之前,我们需要明确2个感念:

  1. StatelessWidget:无中间状态变化的widget,需要更新展示内容就得通过重新new,flutter推荐尽量使用StatelessWidget
  2. StatefullWidget:存在中间状态变化的widget,state类用于存放中间态,通过调用state.setState()进行此节点及以下的整个子树更新
    然后我们了解androidstudio的三个快捷键
快捷键作用
stless创建一个StatelessWidget
stful创建一个StatefullWidget
stanim创建一个StatefullWidget ,且包含动画

准备工作完成
接下来我们以ScrollBar为例,来学习这个控件:

《Flutter笔记-控件1》 工程目录

我们创建一个新的flutter工程时,系统会创建一大堆文件,那么我们的dart代码是在哪呢?
dart代码就在同级目录下的lib文件中
这里会发现同时存在android和ios 2个文件夹,对的,flutter编译后的应用是同时支持双端的(ps:或者说是三端,fuchsia已经在布局了)

enum TargetPlatform {
  /// Android: <https://www.android.com/>
  android,

  /// Fuchsia: <https://fuchsia.googlesource.com/>
  fuchsia,

  /// iOS: <http://www.apple.com/ios/>
  iOS,
}

回归正题,系统会创建一个main.dart文件

import 'package:flutter/material.dart';
//main 程序的主入口
void main() => runApp(MyApp());
//运行一个MaterialApp控件
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //应用的图标名称
      title: 'Flutter Demo',
      //主题
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      //主界面
      home: MainPage()
      );
  }
}

这里代码基本固定了,你肯定要使用MaterialApp控件的,否则不好看(我这里不说不符合规范)

class MainPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //脚手架
    return Scaffold(
        //相当于toolbar,导航栏
        appBar: AppBar(
          title: Text("flutter"),
        ),
        //正文
        body: ScrollBarDemo
    );
  }
}

我们要开始创建一个ScrollBar了,先看下其的源码:

class Scrollbar extends StatefulWidget {
  /// typically a [Scrollable] widget.
  const Scrollbar({
    Key key,
    @required this.child,
  }) : super(key: key);

  /// Typically a [ListView] or [CustomScrollView].
  final Widget child;

  @override
  _ScrollbarState createState() => _ScrollbarState();
}

源码说需要传递一个child,且必须为Scrollable,然后给了2个选择[ListView] 或 [CustomScrollView]
构造函数中的{}表示可选命名参数,@required表示child这个参数必须传递
Scrollable我们可以大胆的猜测,能滚动的控件肯定都包涵这个控件,所以我们选类似android中的那个ScrollView的控件SingleChildScrollView
然后我们写下代码

class ScrollBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scrollbar(
        child: SingleChildScrollView(
          child:Container()
        )
    );
  }
}

接下来看看SingleChildScrollView

class SingleChildScrollView extends StatelessWidget {
  const SingleChildScrollView({
    Key key,
    this.scrollDirection = Axis.vertical,
    this.reverse = false,
    this.padding,
    bool primary,
    this.physics,
    this.controller,
    this.child,
  }) : ...,super(key: key);//省略了断言
  final Axis scrollDirection; //滚动方向,水平和垂直
  final bool reverse; //是否反向,默认不启用
  final EdgeInsetsGeometry padding;//间距
  final ScrollController controller;//滑动控制器
  final bool primary;//默认true
  final ScrollPhysics physics;//超过物理边界后的动画效果
  final Widget child;
  ...
  @override
  Widget build(BuildContext context) {
    ...
    //内部创建了一个Scrollable控件
    final Scrollable scrollable = Scrollable(
      axisDirection: axisDirection,
      controller: scrollController,
      physics: physics,
      viewportBuilder: (BuildContext context, ViewportOffset offset) {
        return _SingleChildViewport(
          axisDirection: axisDirection,
          offset: offset,
          child: contents,
        );
      },
    );
    return primary && scrollController != null
      ? PrimaryScrollController.none(child: scrollable)
      : scrollable;
  }
}

源码可以看出,所有参数都是可选的,也就是说child其实也可以不传的,但这样就整个界面就是空白的

class ScrollBarDemo extends StatelessWidget {
  final String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  @override
  Widget build(BuildContext context) {
    return Scrollbar(
        child: SingleChildScrollView(
          child:Container(
              color: Colors.redAccent,
              width: 360,
              child: Column(
                //创建一个Text控件列表
                children: str.split("").map((c) => Text(c, textScaleFactor: 2.0,)).toList(),
              )
          )
        )
    );
  }
}

关于布局、监听、路由、手势等接下来在介绍

小小的总结一下
1.遇到一个widget,先看它的构造函数(可能有多个)
a. StatelessWidget,看其build方法做了什么
b. StatefulWidget,先找到createState(),然后在state类中看其build方法做了什么
2.配合源码中的英文注释加以理解
3.动手实践一番,测试效果

最后说明一下,flutter生成的代码都封装在libflutter.so中,不再是以前的.class文件

github代码:https://github.com/leaf-fade/flutterDemo

小尾巴:文章有错误的地方请不吝指出,会及时更改

    原文作者:叶落清秋
    原文地址: https://www.jianshu.com/p/2ee96b50785c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞