Flutter 系列(四)基础UI实践

您好,欢迎关注我,本篇文章是关于 Flutter 的系列文,从简单的 Flutter 介绍开始,一步步带你了解进入 Flutter 的世界。你最好有一定的移动开发经验,如果没有也不要担心,在我的专栏底部给我留言,我会尽我的能力给你解答。

上篇文章我们介绍了Flutter的整体架构,相信大家一定印象深刻,本篇文章介绍 Flutter UI的基础构建,从主题、提示、图片加载和动画四个方向介绍。

一.使用主题管理颜色和字体样式

使用主题可以在应用中采用统一的颜色和样式。定义主题有两种方式:内建主题自定义Theme类
1.内建主题

new MaterialApp(
  title: title,
  theme: new ThemeData(
    brightness: Brightness.dark,
    primaryColor: Colors.lightBlue[800],
    accentColor: Colors.cyan[600],
  ),
);

2.自定义主题

new Theme(
  // Create a unique theme with "new ThemeData"
  data: new ThemeData(
    accentColor: Colors.yellow,
  ),
);

3.使用主题

通过以上两种方式创建主题后,我们可以在Widget的build方法中通过Theme.of(context)函数使用主题。

new Container(
  color: Theme.of(context).accentColor,
  child: new Text(
    ‘Text with a background color‘,
    style: Theme.of(context).textTheme.title,
  ),
);

通过ThemeData文档可以查看到主题里面支持预定义的颜色

通过TextTheme可以查看系统预制的字体样式。例如示例中提到的theme.textTheme.title就是这个样子的:

SnackBar
在Android中有Toast弹出提示这个概念,但是在Flutter中没有Toast,取而代之的是SnackBar。

想要创建一个SnackBar,我们需要用到Scaffold容器,之前文章有讲过Scaffold是一个包含Material Design的容器。

Scaffold(
  appBar: AppBar(
    title: Text(‘SnackBar Demo‘),
  ),
  body: SnackBarPage(), // We‘ll fill this in below!
);

接下来创建一个按钮:

return Center(
      child: RaisedButton(
        onPressed: _showSnackBar,
        child: Text(‘Show SnackBar‘),
      ),
    );

点击按钮的时候显示SnackBar:

void _showSnackBar() {
    final snackBar = SnackBar(
            content: Text(‘Yay! A SnackBar!‘),
            action: SnackBarAction(
              label: ‘Undo‘,
              onPressed: () {
                // Some code to undo the change!
              },
            ),
          );

    Scaffold.of(context).showSnackBar(snackBar);
}

二.从网络加载图片

在Flutter中直接使用Image.network就可以加载图片了

import ‘package:flutter/material.dart‘;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var title = ‘Web Images‘;

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: Image.network(
          ‘https://github.com/flutter/website/blob/master/_includes/code/layout/lakes/images/lake.jpg?raw=true‘,
        ),
      ),
    );
  }
}

该方法还可以直接加载GIF图片

Image.network(
  ‘https://github.com/flutter/plugins/raw/master/packages/video_player/doc/demo_ipod.gif?raw=true‘,
);

通过placeholder属性可以增加一个占位图:

FadeInImage.assetNetwork(
  placeholder: ‘assets/loading.gif‘,
  image: ‘https://github.com/flutter/website/blob/master/_includes/code/layout/lakes/images/lake.jpg?raw=true‘,
);

值得注意的是用Image.network加载的图片并没有缓存,如果想加载图片并缓存,需要使用:

CachedNetworkImage(
  placeholder: CircularProgressIndicator(),
  imageUrl: ‘https://github.com/flutter/website/blob/master/_includes/code/layout/lakes/images/lake.jpg?raw=true‘,
);

如果对Flutter的图片缓存策略感兴趣,请继续关注本专栏,之后的文章中我会分享给大家

三.动画

本段只简单的介绍动画入门,之后有文章会详细介绍Flutter动画。
上篇文章说到过在Flutter中所有的东西都是Widget,包括动画也不例外,如果你想让某个Widget包含动画属性,那么你需要用AnimatedOpacity将其包裹起来,AnimatedOpacity也是一个Widget。

AnimatedOpacity(
  // If the Widget should be visible, animate to 1.0 (fully visible). If
  // the Widget should be hidden, animate to 0.0 (invisible).
  opacity: _visible ? 1.0 : 0.0,
  duration: Duration(milliseconds: 500),
  // The green box needs to be the child of the AnimatedOpacity
  child: Container(
    width: 200.0,
    height: 200.0,
    color: Colors.green,
  ),
);

我们使用一个StatefulWidget来调用setState()方法刷新_visible的值,就能显示动画了,是不是很简单?

import ‘package:flutter/material.dart‘;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = ‘Opacity Demo‘;
    return MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}

// The StatefulWidget‘s job is to take in some data and create a State class.
// In this case, our Widget takes in a title, and creates a _MyHomePageState.
class MyHomePage extends StatefulWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

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

// The State class is responsible for two things: holding some data we can
// update and building the UI using that data.
class _MyHomePageState extends State<MyHomePage> {
  // Whether the green box should be visible or invisible
  bool _visible = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: AnimatedOpacity(
          // If the Widget should be visible, animate to 1.0 (fully visible). If
          // the Widget should be hidden, animate to 0.0 (invisible).
          opacity: _visible ? 1.0 : 0.0,
          duration: Duration(milliseconds: 500),
          // The green box needs to be the child of the AnimatedOpacity
          child: Container(
            width: 200.0,
            height: 200.0,
            color: Colors.green,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Make sure we call setState! This will tell Flutter to rebuild the
          // UI with our changes!
          setState(() {
            _visible = !_visible;
          });
        },
        tooltip: ‘Toggle Opacity‘,
        child: Icon(Icons.flip),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}


本篇文章从主题、提示、图片加载和动画四个方面简单的介绍了Flutter的UI创建过程,为了避免文章太长导致可读性较差,所以只简单的讲了这四个方面,还有更多内容会在之后的文章里介绍。相信本篇文章读完之后,你已经知道如何使用Flutter Widget了,下一篇专栏来点实战,我会教大家如何实现一个轮播指示器。

原文地址:https://blog.51cto.com/14295695/2413781

时间: 2024-11-06 07:36:08

Flutter 系列(四)基础UI实践的相关文章

SQL Server 2008空间数据应用系列四:基础空间对象与函数应用

原文:SQL Server 2008空间数据应用系列四:基础空间对象与函数应用 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 R2调测. 2.具备 Transact-SQL 编程经验和使用 SQL Server Management Studio 的经验. 3.熟悉或了解Microsoft SQL Server 2008中的空间数据类型. 4.具备相应(比如OGC)的GIS专业理论知识. 5.其他相关知识. SQL Server 2

Flutter系列(三) 整体架构

您好,欢迎关注我的专栏,本篇是关于 Flutter 系列的第三篇,从简单的 Flutter 介绍开始,一步步带你了解进入 Flutter 的世界.你最好有一定的移动开发经验,如果没有也不要担心,在我的专栏底部给我留言,我会尽我的能力给你解答. 上篇文章我们介绍了用 Flutter 开发第一个跨平台应用程序,相信大家一定印象深刻,本篇文章介绍 Flutter 平台的整体架构. 一.核心原则 之前专栏有提到过,Flutter 的SDK中包括一个现代的响应式框架.一个2D渲染引擎.现成的widget和

iOS流布局UICollectionView系列四——自定义FlowLayout进行瀑布流布局

iOS流布局UICollectionView系列四--自定义FlowLayout进行瀑布流布局 一.引言 前几篇博客从UICollectionView的基础应用到设置UICollectionViewFlowLayout更加灵活的进行布局,但都限制在系统为我们准备好的布局框架中,还是有一些局限性,例如,如果我要进行瀑布流似的不定高布局,前面的方法就很难满足我们的需求了,如下: 这种布局无疑在app的应用中更加广泛,商品的展示,书架书目的展示,都会倾向于采用这样的布局方式,当然,通过自定义FlowL

从零学习Fluter(八):Flutter的四种运行模式--Debug、Release、Profile和test以及命名规范

从零学习Fluter(八):Flutter的四种运行模式--Debug.Release.Profile和test以及命名规范 好几天没有跟新我的这个系列文章,一是因为这两天我又在之前的基础上,重新认识flutter,觉得flutter这个东西越来越有意思.并且水很深 今天简单分享一下开发学习中的小知识点 Flutter有四种运行模式:Debug.Release.Profile和test,这四种模式在build的时候是完全独立的 Debug ??Debug模式可以在真机和模拟器上同时运行:会打开所

Flutter系列博文链接

Flutter系列博文链接 ↓: Flutter基础篇: Flutter基础篇(1)-- 跨平台开发框架和工具集锦 Flutter基础篇(2)-- 老司机用一篇博客带你快速熟悉Dart语法 Flutter基础篇(3)-- Flutter基础全面详解 Flutter基础篇(4)-- Flutter填坑全面总结 Flutter基础篇(5)-- Flutter代码模板,解放双手,提高开发效率必备 Flutter基础篇(6)-- 水平和垂直布局详解 Flutter进阶篇: Flutter进阶篇(1)--

sed修炼系列(四):sed中的疑难杂症

本文目录:1 sed中使用变量和变量替换的问题2 反向引用失效问题3 "-i"选项的文件保存问题4 贪婪匹配问题5 sed命令"a"和"N"的纠葛 1.sed中使用变量和变量替换的问题 在脚本中使用sed的时候,很可能需要在sed中引用shell变量,甚至想在sed命令行中使用变量替换.也许很多人都遇到过这个问题,但引号却死活调试不出正确的位置.其实这不是sed的问题,而是shell的特性.搞懂sed如何解决引号的问题,对理解shell引号问题有

Java-单机版的书店管理系统(练习设计模块和思想_系列 四(2) )

说明: 本博客为补全上篇-Java-单机版的书店管理系统(练习设计模块和思想_系列 四(1) )的,所以如果不懂,请先看上一篇. 本系列都是我一步一步学习来的, 所以,可能比较适合初学设计模块的人来学. 现在补全我目前写的所以代码: 公共类: 用户类型枚举:UserTypeEnum类 package cn.hncu.bookStore.common; /** * 功能:用户类型的枚举!<br/> * 定义在公共模块.<br/> * 变量:<br/> * ADMIN(1,

RX系列四 | RxAndroid | 加载图片 | 提交表单

RX系列四 | RxAndroid | 加载图片 | 提交表单 说实话,学RxJava就是为了我们在Android中运用的更加顺手一点,也就是RxAndroid,我们还是先一步步来,学会怎么去用的比较好,之前的三篇算是铺垫,让你有一点认识,那Rx在Android中有什么好处呢?我们先模拟一些原始功能和他对比下 一.加载图片 很多人说Rx出来之后,是编程思想的一种进阶,实际上我学习了这种思想之后,确实是觉得有了很大的改变,不过,需要一点学习成本再加上,需要对原先的思想有些改观,使得我依旧有点不适应

RxJava入门系列四,Android中的响应式编程

RxJava入门系列四,Android中的响应式编程 在入门系列1,2,3中,我基本介绍了RxJava是如何使用的.但是作为一名Android开发人员,你怎么让RxJava能为你所用呢?这篇博客我将针对Android开发来介绍一下RxJava的使用场景. RxAndroid RxAndroid是为Android打造的RxJava扩展.通过RxAndroid可以让你的Android开发变得更轻松. 首先,RxAndroid中提供了AndroidSchedulers,你可以用它来切换Android线