美文网首页
Widget详解

Widget详解

作者: 乌龟漫漫 | 来源:发表于2020-04-02 17:32 被阅读0次

介绍

Flutter Widget采用现代响应式框架构建,这是从 React 中获得的灵感,中心思想是用widget构建你的UI。 Widget描述了他们的视图在给定其当前配置和状态时应该看起来像什么。当widget的状态发生变化时,widget会重新构建UI,Flutter会对比前后变化的不同, 以确定底层渲染树从一个状态转换到下一个状态所需的最小更改。


从Flutter的架构图中不难看出Widget是整个视图描述的基础。Flutter 的核心设计思想便是Everything‘s a Widget

StatelessWidget 和 StatefulWidget

StatelessWidget 表示不可变的 widget,例如一些固定的标题、Icon 等等,widget 的特征不会在运行时发生变化。
StatefulWidget 相反,其属性可能会在运行时发生变化,如要根据HTTP网络请求或用户交互后收到的数据动态更改UI,则必须使用StatefulWidget并告诉Flutter框架Widget的状态已更新,以便更新该Widget,例如进度条、输入框等等。
在使用上,StatelessWidget 会通过 build 方法创建一个不可变的 widget,这样 widget 只需要绘制一次,我们在使用时直接继承它然后实现 build 方法既可。

class StatelessText extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Text("Hello World");
  }
}

而 StatefulWidget 中需要包含一个 State 对象来表现不同的状态,首先使用 createState 方法创建一个 State 对象,再通过 State 中的 build 方法创建一个 widget,后面每次状态变化时都会调用 build 方法重新绘制一个 widget。我们可以使用 setState 方法来触发 widget 更新。

import 'package:flutter/material.dart';

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

class SampleAPP extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primaryColor: Colors.blue,
      ),
      home: SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  @override
  _SampleAppPageState createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  //Default placeholder text
  String textToShow = 'Hello World';
  void _updateText() {
    setState(() {
      //update the text
      textToShow = 'I Like Flutter.';
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sample App'),
      ),
      body: Center(child: Text(textToShow)),
      floatingActionButton: FloatingActionButton(
          onPressed: _updateText,
          tooltip: 'Update Text',
          child: Icon(Icons.update),
      ),
    );
  }
}

常用 Widget

1. Text(文本框)

Text几乎在UI开发中随处可见,是最为基础及重要的组件之一,UI上面文字的展示基本上都要靠Text组件来完成。

Text(
        'hello world',
        textAlign: TextAlign.center, //文本居中模式
        textDirection: TextDirection.ltr, //文本方向,默认为ltr。对于一些习惯于从右至左阅读的国家来说可以设置为rtl
        maxLines: 1, //最大行数
        overflow: TextOverflow.ellipsis, //溢出显示...
        style: TextStyle(
          fontSize: 30.0, //文字大小
          color: Colors.red, //文字颜色
        ),
      ),

2. Image(图片)

Image用于展示一张图片,图片源可以是文件、资源、内存及网络。通过不同的方法加载不同的图片源:
//网络获取图片
Image.network(
          'Http://www.devio.org/img/avatar.png', //url
          width: 150, //宽
          height: 150, //高
          fit: BoxFit.contain, //缩放方式
        ),

重点说明几种缩放方式:

  • fill:不考虑宽高比,只保证图片完全填满。


  • contain:在不缩放的情况下保证至少有一个方向充满且图片完全能显示出来。


  • cover:在不缩放的情况下保证至少一个方向上充满但不保证图片完全显示。


  • fitWidth:保证宽度填满,即使高度溢出。


  • fitHeight:保证高度填满,即使宽度溢出。


  • none:不应用任何设置,按照图片原有尺寸居中。


  • scaleDown:等同 none,但如果尺寸超出则缩放填满。


3. Container

Container是个布局控件,提供了对基础widget的封装,提高了UI基础装饰能力的表达效率。

Container(
        width: 300,  //宽
        height: 150, //高
        alignment: Alignment.topLeft, //child布局位置
        padding: const EdgeInsets.all(10.0), //内间距
        margin: const EdgeInsets.all(10.0), //边距
        decoration: BoxDecoration(
          border: Border.all(
            color: Colors.red,
          ), //边框
          image: DecorationImage(
            image: const NetworkImage('Http://www.devio.org/img/avatar.png'),
            fit: BoxFit.contain,
          ), //背景图
          borderRadius: const BorderRadius.only(
            topLeft: const Radius.circular(5.0),
            topRight: const Radius.circular(5.0),
            bottomLeft: const Radius.circular(10.0),
            bottomRight: const Radius.circular(10.0),
          ), //圆角
        ),
        child: Text('hello world'),
      ),

效果如下图所示:


4.Stack

Stack即层叠布局控件,能够将子控件层叠排列。
Stack控件的每一个子控件都是定位或不定位,定位的子控件是被Positioned控件包裹的。Stack控件本身包含所有不定位的子控件,其根据alignment定位(默认为左上角)。然后根据定位的子控件的top、right、bottom和left属性将它们放置在Stack控件上。

Stack(
        alignment: AlignmentDirectional.bottomEnd,
//        fit: StackFit.loose,
        overflow: Overflow.visible,
        children: <Widget>[
          Positioned.fill(
            child: Container(
              color: Colors.grey,
            ),
          ),
          Positioned(
            left: 0,
            top: 100,
            right: 20,
            child: Container(
              color: Colors.red,
              child: Text('first widget'),
            ),
          ),
          Positioned(
            top: 200,
            bottom: 20,
            child: Container(
              color: Colors.green,
              child: Text('second widget'),
            ),
          ),
          Positioned(
            left: 0,
            right: 0,
            bottom: 0,
            child: Container(
              color: Colors.blue,
              child: Text('third widget'),
            ),
          ),
        ],
      ),
  • alignment : 指的是子Widget的对其方式,默认情况是以左上角为开始点。
  • fit :用来决定没有Positioned方式时候子Widget的大小,StackFit.loose 指的是子Widget 尽可能大,StackFit.expand指子Widget的大小和父组件一样大。
  • overflow :指子Widget 超出Stack时候如何显示,默认值是Overflow.clip,子Widget超出Stack会被截断,Overflow.visible超出部分还会显示的。
  • Positioned 用来控制Widget的位置,通过它可以约束Widget的left,top,right,bottom相对于Stack的距离。

top、bottom决定了垂直方向上的位置,left、right决定了水平方向上的位置,不管水平方向上还是垂直方向上只要设定了一个值该方向上位置就已经确定,aligment对这这个方向上就不会起作用,如果Positioned 设置了其中任意三个方向的值,这个Widget的位置就是固定的,aligment对它不会起任何作用。

5. GestureDetector(手势)

手势操作是最常见的UI交互操作。通常来说可以通过GestureDetector类来完成点击事件的处理。使用时只需要将GestureDetector包裹在目标widget外面,再实现对应事件的函数即可。从点击到长按,从缩放到拖动,这个类基本上都有相应的实现。

更多

关于Widget更多详细介绍可以阅读flutter官方文档

相关文章

网友评论

      本文标题:Widget详解

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