Flutter开发(四):Flutter视图(Views)

1.Flutter 中的 View

在 Flutter 中,可以将 Widget 当做 Android 中的 View,但并不是完全等价。Widget 的生命周期是不可变的,每当 Widget 或其状态发生变化时,Flutter 的框架都会创建一个新的实例树。

Flutter 包含了 Material 组件库,这些 widgets 遵循了 Material 设计规范。

2.更新Widgets

在 Flutter 中,Widgets 是不可变的,不会直接更新,相反,可以通过 Widget 的状态更新它们。

StatelessWidgets 适用与当我们秒速的用户界面不依赖于对象中的配置信息时,如 app 的 logo。

如果根据网络或用户交互更新 UI,必须使用 StatefulWidget 告诉 Flutter 框架 Widget 的状态已更新,以便更新改 Widget。

如果 Widget 在 build 之外更新(如用户交互),则它是有状态的。如果 Widget 永远不会改变,一旦创建它就是无状态的。但是,如果它是有状态的,包含它的父窗口小部件本身不对这些更新做出反应,父 Widget 仍然可以是无状态的。

使用 StatelessWidget ,Text就是一个常见的 StatelessWidget :

new Text(
    'Hello';
    style: new TextStyle(fontWeight: fontWeight.bold),
);

如果想让上面文字通过点击按钮发生变化,需要用 StatefulWidget :

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '123',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}


class MyHomePage extends StatefulWidget {

  MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();


}

class _MyHomePageState extends State<MyHomePage> {
  String textShow = "Hello";

  void _updateText() {
    setState(() {
      textShow = "Flutter";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MyApp"),
      ),
      body: Center(
          child: Text(textShow)
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _updateText,
        tooltip: '更新了文字',
        child: const Icon(Icons.update),
      ),
    );
  }
}

3.更新布局

在 Flutter 中,通过写一个 widget 树来声明布局。

实现一个带有 padding 的简单 widget:

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MyApp"),
      ),
      body: Center(
          child: MaterialButton(
            onPressed: (){},
            child: Text('Hello'),
            padding: EdgeInsets.only(left: 10.0,right: 10.0),
          )
      ),
    );
  }

4.布局中添加或删除组件

在 Flutter 中,Widget 是不可变的,所以没有类似的方法,相反,可以传入一个函数或表达式,该函数或表达式返回一个 Widget 给父项,并且通过布尔值控制改 Widget 的创建。

点击一个 FloatingActionButton,在两个 widget 质检切换:
 

class _MyHomePageState extends State<MyHomePage> {
  bool tog = true;

  void _tog() {
    setState(() {
      tog = !tog;
    });
  }

  _getTogChild() {
    if (tog) {
      return Text("Hello");
    } else {
      return MaterialButton(onPressed: () {}, child: Text("你好"));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MyApp"),
      ),
      body: Center(
          child: _getTogChild(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _tog,
        tooltip: '更新文字',
        child: Icon(Icons.update),
      ),
    );
  }
}

5.对 Widget 做动画

在 Flutter 中,使用动画库包裹 widgets,而不是创建一个动画 widget。

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  late AnimationController controller;
  late CurvedAnimation curve;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    controller = AnimationController(
        duration: const Duration(milliseconds: 2000), vsync: this);
    curve = CurvedAnimation(parent: controller, curve: Curves.easeIn);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("123"),
      ),
      body: Center(
          child: Container(
              child: FadeTransition(
              opacity: curve,
              child: FlutterLogo(
                size: 100.0,
              )))),
      floatingActionButton: FloatingActionButton(
        tooltip: 'Fade',
        child: Icon(Icons.brush),
        onPressed: () {
          controller.forward();
        },
      ),
    );
  }
}

6.绘图(Canvas draw/paint)

Flutter 绘制类似于 Android,用到 Canvas API。Flutter可以借助两个类来帮助绘制:CustomPaint和 CustomPaninter 。

下面展示如何用 CustomPaint widget 在绘制阶段绘制。它实现了抽象类 CustomPainter,并将其传递给 CustomPaint 的 painter 属性。CustomPaint 子类必须实现 paint 和 shouldRepaint 方法;

绘制一个圆形和一个长方形:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: 'Flutter bottomNavigationBar',
      theme: new ThemeData.fallback(),
      home: _MyCanvas(),
    );
  }
}

class MyCanvasPainter extends CustomPainter{
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    Paint paint = Paint();
    paint.color = Colors.amber;
    canvas.drawCircle(Offset(100.0,200.0), 40.0, paint);
    Paint paintRect = Paint();
    paintRect.color = Colors.lightBlue;
    Rect rect = Rect.fromPoints(Offset(150.0,300.0), Offset(300.0,400.0));
    canvas.drawRect(rect, paintRect);
  }

  @override
  bool shouldRepaint(MyCanvasPainter oldDelegate) => false;
  @override
  bool shouldRebuildSemantics(MyCanvasPainter oldDelegate) => false;
}

class _MyCanvas extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: CustomPaint(
        painter: MyCanvasPainter(),
      ),
    );
  }
}

7.自定义 Widgets

在 Android 中,可以通过继承 View 或已存在的某个控件,覆盖里面绘制方法实现自定义 View;

在 Flutter 中,推荐组合多个小的 widgets 来构建一个自定义的 widget。

如果想自定义一个 Button,需要组合 RaisedButton 和 label。

void main() {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Center(
      child: new CustomButton("你好"),
    );
  }
}

class CustomButton extends StatelessWidget{
  final String label;
  CustomButton(this.label);
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new RaisedButton(onPressed: (){},child: new Text(label));
  }
}

8.设置 Widget 的透明度

在 Flutter 中想改变透明度,可以给 widget 包裹一个 Opacity widget 来做到:

void main() {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter学习',
      home: Scaffold(
          appBar: AppBar(
            title: Text('一起学习'),
          ),
          body: Opacity(
            opacity: 0.1,
            child: new Center(
              child: Text('HelloWorld'),
            ),
          )),
    );
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值