Flutter常用组件

MaterialApp

表示一个应用了 Material 界面风格的应用程序,它封装了应用程序实现 Material Design 所需要的一些widget,大多数项目的界面都应该基于 MaterialApp 进行呈现。

该组件的基本用法如下:

MaterialApp(
  // 指定应用程序在任务栏上显示的标题
  title: 'Flutter初体验',
  // 指定应用程序的主界面
  home: Text('aaa'),
  // 配置应用程序的主题
  theme: ThemeData(primarySwatch: Colors.red),
)

Text

用于在页面上渲染普通文本字符串,常见用法如下:

Text('文本内容', style: TextStyle(fontSize: 12))

其中,

参数1:将要渲染的文本内容

参数2:文本内容的样式

 

Scaffold

该组件是页面结构的脚手架,包含了页面的基本组成单元,例如:

  • appBar【头部导航条区域】

  • body【页面主题内容区域】

    Flutter常用组件_第1张图片

  • drawer【侧边栏抽屉区域】

    Flutter常用组件_第2张图片

  • bottomNavigationBar【底部tabBar区域】

    Flutter常用组件_第3张图片

  • floatingActionButton【右下角浮动按钮区域】

    Flutter常用组件_第4张图片

基本代码示例:

Scaffold(
    appBar: AppBar(
      title: Text('页面标题'),
    ),
    body: Center(
      child: Text('主体内容'),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: () {},
      child: Icon(Icons.add),
    ),
    drawer: Drawer(),
  ),
  // 主题颜色
  theme: ThemeData(primarySwatch: Colors.red),
)

 

常用的布局组件

Container

常用的属性:

  • child【子节点】

  • padding【内容距离盒子边界的距离】

    举例:padding: EdgeInsets.all(10)

  • margin 【盒子边界之外的距离】

    举例:margin: EdgeInsets.all(10)

  • decoration【盒子的装饰】

    举例:

    decoration: BoxDecoration(
        color: Colors.red,
        border: Border(bottom: BorderSide(width: 5, color: Colors.cyan)))
    

Row

使内部的 children 子元素横向布局

属性:

  • children【子元素】

  • mainAxisAlignment【横向对其方式】

  • crossAxisAlignment【纵向对其方式】

Column

使内部的 children 子元素纵向布局

属性:

  • children【子元素】

  • mainAxisAlignment【纵向对其方式】

  • crossAxisAlignment【横向对其方式】

Expanded

主要用来控制 flex 布局的占位宽度。

需要用在 Row 或 Column 子组件内部。

举例:

Row(
  children: [
    Expanded(child: Text('主体内容1'), flex: 2,),
    Expanded(child: Text('主体内容2'), flex: 1,)
  ]
)

 

AppBar

页面的导航条区域,示例代码如下:

appBar: AppBar(
  // 标题
  title: Text('页面标题'),
  // 标题是否居中显示
  centerTitle: true,
  // 右侧的按钮
  actions: [
    Padding( // 为 IconButton 添加右 padding 为 10px
      padding: EdgeInsets.only(right: 10),
      child: IconButton( // 右侧的搜索按钮
        icon: Icon(Icons.search),
        onPressed: () {},
      ),
    )
  ],
)

 

TabBar

在页面上渲染 TabBar 组件,通常配合 Scaffold 组件的 bottomNavigationBar 属性一起使用,用来渲染底部的 TabBar 效果。

注意:

  1. TabBar 最好和有状态页面配合使用

  2. TabBar 必须指定 TabController 控制器,用来控制 TabBar 的切换

  3. 如若不指定 TabController 控制器,也可以使用 DefaultTabController 组件,把 TabBar 组件包裹起来,同时提供需要切换的页面个数即可,代码示例如下:

    DefaultTabController(
      // 指定需要切换的页面个数
      length: tablist.length,
      child: Scaffold(
        appBar: AppBar(),
        // 被 tabbar 控制切换的页面
        body: TabBarView(),
        // 指定 tab 项
        bottomNavigationBar: TabBar(
          tabs: tablist
        )
      ),
    )
    
  4. TabController 必须用在拥有 TickerProviderStateMixin 或 SingleTickerProviderStateMixin 特征的类中,因此,必须让 TabController 所在的类实现此特征,代码示例如下:

    class _HomePageState extends State with SingleTickerProviderStateMixin { }
    

实现步骤:

  1. 创建对应的 Tab 项:

    List tablist = [
      Tab(
        text: '正在热映',
        icon: Icon(Icons.movie),
      ),
      Tab(
        text: '即将上映',
        icon: Icon(Icons.movie_filter),
      ),
      Tab(
        text: 'Top250',
        icon: Icon(Icons.local_movies),
      ),
    ];
    
  2. 创建 TabController 对象:

    TabController tabCtrl;
    
  3. 在 initState 生命周期函数中,初始化 tabCtrl 对象:

    @override
    void initState() {
      super.initState();
      tabCtrl = TabController(vsync: this, length: tablist.length);
    }
    
  4. 为 Scaffold 添加 bottomNavigationBar 选项如下:

    bottomNavigationBar: Container(
      // 设置 tabbar 的背景色
      decoration: BoxDecoration(color: Colors.black),
      // 设置 tabbar 的高度
      height: 50,
      // 指定 tabbar 组件
      child: TabBar(
        // 指定 tabbar 的控制器,必须提供控制器,否则 tabbar 不能正常工作
        controller: tabCtrl,
        // 设置 tabbar 中文本的样式,注意,height 属性很重要,必须设置为 0,否则文本和图标之间的距离太大,不美观
        labelStyle: TextStyle(height: 0, fontSize: 10),
        // 设置指示器的颜色
        indicatorColor: Colors.red,
        // 指定当前 tabbar 总共有几个按钮
        tabs: tablist,
      ),
    )

 

 

Drawer

侧边栏抽屉区域,用法比较简洁,主要代码示例如下:

drawer: Drawer(
  // 抽屉可能在高度上超出屏幕,所以使用 ListView 组件包裹起来,实现纵向滚动效果
  child: ListView(
    // 干掉顶部灰色区域
    padding: EdgeInsets.all(0),
    // 所有抽屉中的子组件都定义到这里:
    children: [],
  ))

 

UserAccountsDrawerHeader

提供类似于下图这样的效果,一般都用在侧边栏 Drawer 组件中:

 

其中,accountName 和 accountEmail 是必选项。

另外,头像区域使用 currentAccountPicture 进行指定;

背景区域使用 decoration 属性进行指定;

详细代码示例如下:

UserAccountsDrawerHeader(
  accountName: Text('刘龙宾'),
  accountEmail: Text('[email protected]'),
  currentAccountPicture: CircleAvatar(
    backgroundImage: NetworkImage(
        'https://images.gitee.com/uploads/91/465191_vsdeveloper.png'),
  ),
  decoration: BoxDecoration(
      // 设置背景图片
      image: DecorationImage(
          // 控制图片填充效果
          fit: BoxFit.fill,
          // 指定图片地址
          image: NetworkImage(
              'http://www.liulongbin.top:3005/images/bg1.jpg'))),
)

 

ListView

滚动列表,可以很单纯中填充固定个数的内容,也可以循环渲染列表数据。

填充固定内容

用法最简单,将需要的内容节点,直接写入到 ListView 组件的 children 属性中即可,代码示例如下:

ListView(
  children: [
    ListTile(
      title: Text('我要发布'),
      trailing: Icon(Icons.send),
    ),
    Divider(),
    ListTile(
      title: Text('注销'),
      trailing: Icon(Icons.exit_to_app),
    )
  ]
)

循环渲染列表数据

如果要把列表数据,通过循环渲染之后,得到 UI 结构类似的列表页面,推荐使用 ListView.builder(),基础用法如下:

ListView.builder(
  // 必须指定列表项的长度
  itemCount: 列表项的长度,
  // Item 项的构建器
  itemBuilder: (BuildContext ctx, int i) {
    return Text('aaa');
  }
)

保持列表项的数据状态

如果存在多个列表页之间的动态切换,默认无法保持每个列表项的滚动距离、数据状态等信息,此时需要实现 AutomaticKeepAliveClientMixin特征,来保持列表项的滚动状态,示例代码如下:

class _MovieListState extends State
    with AutomaticKeepAliveClientMixin {
      // 重写 wantKeepAlive 函数
      @override
      bool get wantKeepAlive => true;
    }

监听列表是否滚动到页面底部

有时候,需要实现列表滚动到页面底部之后,自动加载下一页数据,此时需要借助于 ScrollController 实现滚动监听,示例代码如下:

// 定义私有变量 _scrollCtrl
ScrollController _scrollCtrl;

// 重写 initState 生命周期函数
@override
void initState() {
  // 此行为默认代码,不能删除
  super.initState();
  // 初始化一个 ScrollController 滚动控制器
  _scrollCtrl = new ScrollController();
  // 为 _scrollCtrl 滚动控制器添加监听事件
  _scrollCtrl.addListener(() {
    // _scrollCtrl.position.pixels 当前列表滚动的距离
    // _scrollCtrl.position.maxScrollExtent 列表的最大滚动距离
    if (_scrollCtrl.position.pixels == _scrollCtrl.position.maxScrollExtent) {
      // 调用 setState 函数,让页码值 +1
      setState(() {
        _page++;
      });
      // 获取新页面的数据
      _getMovieList();
    }
  });
}

为 ListView 组件添加 controller 滚动控制器

如果想监听 ListView 组件的滚动效果,可以为 ListView.builder() 提供 controller 属性,值为 ScrollController 的示例对象,示例代码如下:

ListView.builder(
  controller: _scrollCtrl,
  itemCount: _mlist.length,
  itemBuilder: (BuildContext ctx, int i) {}
)

清理滚动控制器

当页面被销毁的时候,最好主动销毁对应的滚动控制器,主动释放内存,提高性能:

// 重新 dispose 函数
@override
void dispose() {
  super.dispose();
  // 主动销毁滚动控制器
  _scrollCtrl.dispose();
}

获取下一页数据后合并数组

如果分页加载数据,则应该让旧数组主动拼接新数组,代码示例如下:

setState(() {
  _total = result.data['count'];
  // 调用数组的 addAll 方法,可以主动合并另一个数组
  _mlist.addAll(result.data['subjects']);
});

 

CircleAvatar

提供圆形的用户头像区域,使用起来比较简单,示例代码如下:

CircleAvatar(
  backgroundImage: NetworkImage(
      'https://images.gitee.com/uploads/91/465191_vsdeveloper.png'),
)

 

你可能感兴趣的:(flutter)