Flutter入门05 -- Widget之基础组件类

  • Widget中的基础组件类包括:Text,Button,Image,Icon,TextField,Divider

Text

  • 在Flutter中使用Text组件来显示文本,其构造函数如下:
const Text(
    this.data, {
    Key key,
    this.style,
    this.strutStyle,
    this.textAlign,
    this.textDirection,
    this.locale,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
    this.semanticsLabel,
    this.textWidthBasis,
    this.textHeightBehavior,
})
  • data:文本数据,属于String类型;
  • textAlign:文本的对齐方式,属于TextAlign类型;
  • textDirection:文本的排版方向,TextDirection类型;
  • maxLines:最大显示行数;
  • overflow:文本的截断规则,TextOverflow类型;
  • style:文本的样式设置,属于TextStyle类型,TextStyle的常见属性有如下:
    • fontSize:设置文本大小;
    • color:设置文本颜色,属于Color类型;
    • fontFamily:设置设置字体类型,属于String类型;
    • shaow:设置文本阴影,属于List<ui.Shadow>数组类型;
    • fontWeight:设置文本加粗,属于FontWeight类型,例如:FontWeight.w700
    • fontStyle:设置字体样式,属于FontStyle类型,例如:FontStyle.italic表示斜体;
    • decoration:设置文本装饰,属于TextDecoration类型,
  • 案例代码:
class TextDemo extends StatelessWidget {
  const TextDemo({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text(
      "基础widget \ndasd has发哈就困了打算看是的撒 \n但是开发双卡双待",
      textAlign: TextAlign.center,
      maxLines: 2,
      overflow: TextOverflow.ellipsis,
      style: TextStyle(
        fontSize: 30,
        color: Colors.red,
        fontWeight: FontWeight.bold,
        fontFamily: 'Courier'
      ),
    );
  }
}
  • 在Flutter中使用Text.rich,创建富文本组件,其构造函数如下:
const Text.rich(
    this.textSpan, {
    Key key,
    this.style,
    this.strutStyle,
    this.textAlign,
    this.textDirection,
    this.locale,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
    this.semanticsLabel,
    this.textWidthBasis,
    this.textHeightBehavior,
    @Deprecated(
      'This parameter is a temporary flag to migrate the internal tests and '
      'should not be used in other contexts. For more details, please check '
      'https://github.com/flutter/flutter/issues/59316. '
      'This feature was deprecated after v1.19.0.'
    )
    bool applyTextScaleFactorToWidgetSpan = false,
})
  • textSpan:必传参数,属于InlineSpan类型,是一个抽象类,我们需要传入其子类即可,其子类有:
    • TextSpan:显示文本的;
    • WidgetSpan:显示图片的;
    • placeholderSpace:占位的;
  • style:设置文本样式,属于TextStyle类型;
  • 案例代码如下:
class TextRichDemo extends StatelessWidget {
  const TextRichDemo({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text.rich(
      TextSpan(
        children: [
          TextSpan(text: "Hello World!!", style: TextStyle(fontSize: 20,color: Colors.green)),
          TextSpan(text: "Hello iOS!!", style: TextStyle(fontSize: 20,color: Colors.red)),
          WidgetSpan(child: Icon(Icons.favorite,color: Colors.red)),
          TextSpan(text: "Hello Flutter!!", style: TextStyle(fontSize: 25,color: Colors.orange))
        ]
      )
    );
  }
}
  • 效果图如下:
Snip20220221_2.png

Button

  • 常见的按钮类型有:
    • RaisedButton
    • FlatButton
    • OutlineButton
    • FloatingActionButton
RaisedButton
  • RaisedButton是带有一定圆角和阴影以及灰色背景的按钮,并且在点击的时候有动画效果,其构造函数如下:
class RaisedButton extends MaterialButton {
  const RaisedButton({
    Key key,
    @required VoidCallback onPressed,
    VoidCallback onLongPress,
    ValueChanged<bool> onHighlightChanged,
    MouseCursor mouseCursor,
    ButtonTextTheme textTheme,
    Color textColor,
    Color disabledTextColor,
    Color color,
    Color disabledColor,
    Color focusColor,
    Color hoverColor,
    Color highlightColor,
    Color splashColor,
    Brightness colorBrightness,
    double elevation,
    double focusElevation,
    double hoverElevation,
    double highlightElevation,
    double disabledElevation,
    EdgeInsetsGeometry padding,
    VisualDensity visualDensity,
    ShapeBorder shape,
    Clip clipBehavior = Clip.none,
    FocusNode focusNode,
    bool autofocus = false,
    MaterialTapTargetSize materialTapTargetSize,
    Duration animationDuration,
    Widget child,
  })
FlatButton
  • FlatButton:默认没有背景颜色,不带阴影,高亮状态下有背景,构造函数如下:
class FlatButton extends MaterialButton {
  const FlatButton({
    Key key,
    @required VoidCallback onPressed,
    VoidCallback onLongPress,
    ValueChanged<bool> onHighlightChanged,
    MouseCursor mouseCursor,
    ButtonTextTheme textTheme,
    Color textColor,
    Color disabledTextColor,
    Color color,
    Color disabledColor,
    Color focusColor,
    Color hoverColor,
    Color highlightColor,
    Color splashColor,
    Brightness colorBrightness,
    EdgeInsetsGeometry padding,
    VisualDensity visualDensity,
    ShapeBorder shape,
    Clip clipBehavior = Clip.none,
    FocusNode focusNode,
    bool autofocus = false,
    MaterialTapTargetSize materialTapTargetSize,
    @required Widget child,
  })
OutlineButton
  • OutlineButton:带有边框的按钮,构造函数如下:
class OutlineButton extends MaterialButton {
  const OutlineButton({
    Key key,
    @required VoidCallback onPressed,
    VoidCallback onLongPress,
    MouseCursor mouseCursor,
    ButtonTextTheme textTheme,
    Color textColor,
    Color disabledTextColor,
    Color color,
    Color focusColor,
    Color hoverColor,
    Color highlightColor,
    Color splashColor,
    double highlightElevation,
    this.borderSide,
    this.disabledBorderColor,
    this.highlightedBorderColor,
    EdgeInsetsGeometry padding,
    VisualDensity visualDensity,
    ShapeBorder shape,
    Clip clipBehavior = Clip.none,
    FocusNode focusNode,
    bool autofocus = false,
    Widget child,
  })
FloatingActionButton
  • FloatingActionButton:悬浮按钮,构造函数如下:
class FloatingActionButton extends StatelessWidget {
  const FloatingActionButton({
    Key key,
    this.child,
    this.tooltip,
    this.foregroundColor,
    this.backgroundColor,
    this.focusColor,
    this.hoverColor,
    this.splashColor,
    this.heroTag = const _DefaultHeroTag(),
    this.elevation,
    this.focusElevation,
    this.hoverElevation,
    this.highlightElevation,
    this.disabledElevation,
    @required this.onPressed,
    this.mouseCursor,
    this.mini = false,
    this.shape,
    this.clipBehavior = Clip.none,
    this.focusNode,
    this.autofocus = false,
    this.materialTapTargetSize,
    this.isExtended = false,
  })
  • 案例代码:
import 'package:flutter/material.dart';

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

class SFMyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SFHomePage()
    );
  }
}

class SFHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("基础widget")
      ),
      body: SFHomeContent()
    );
  }
}

class SFHomeContent extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    print("createState");
    return _SFHomeContentState();
  }
}

class _SFHomeContentState extends State<SFHomeContent>{
  @override
  Widget build(BuildContext context) {
    print("_SFHomeContentState build");
    return ButtonWidget();
  }
}

class ButtonWidget extends StatelessWidget {
  const ButtonWidget({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        RaisedButton(
          child: Text("RaisedButton"),
          textColor: Colors.white,
          onPressed: (){
            print("RaisedButton click");
          },
        ),
        FlatButton(
          child: Text("FlatButton"),
          onPressed: (){
            print("FlatButton click");
          },
        ),
        OutlineButton(
          child: Text("OutlineButton"),
          onPressed: (){
            print("OutlineButton click");
          },
        ),
        FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: (){
            print("FloatingActionButton click");
          },
        ),
        //自定义button
        FlatButton(
          color: Colors.green,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8)
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(Icons.favorite,color: Colors.red),
              Text("喜欢作者")
            ],
          ),
          onPressed: (){
            print("FlatButton");
          },
        )
      ],
    );
  }
}
  • 执行结果如下图所示:
image.png
  • onPressed:点击事件的回调函数,属于VoidCallback类型,本质就是一个回调函数;
  • onLongPress:长按事件的回调函数,属于VoidCallback类型;
  • child:子组件;
  • ShapeBorder:设置边框,是一个抽象类,其常用子类为RoundedRectangleBorder
  • materialTapTargetSize:默认情况下Button上下会有一定的间距,此属性,去除间距;
  • ButtonTheme:设置按钮主题,Button在没有文本的情况下,会显示默认尺寸大小,可通过此属性,自定义任意尺寸大小;
  • padding:设置内容边距;

Image

  • Image:图片组件,其构造函数如下:
class Image extends StatefulWidget {
  const Image({
    Key key,
    @required this.image,
    this.frameBuilder,
    this.loadingBuilder,
    this.errorBuilder,
    this.semanticLabel,
    this.excludeFromSemantics = false,
    this.width,
    this.height,
    this.color,
    this.colorBlendMode,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.centerSlice,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
    this.isAntiAlias = false,
    this.filterQuality = FilterQuality.low,
  })
  • image:必选参数,参数类型为ImageProvider是一个抽象类,常见子类有:
    • NetworkImage:表示网络图片;
    • AssetImage:表示本地图片;
  • fit:图片的显示模式,等价于OC中的contentMode
  • alignment:图片的对齐方式;
  • repeat:当图片未填充满控件时,可设置重复填充;
NetworkImage加载网络图片
  • 案例代码如下:
class NetWorkImage extends StatelessWidget {
  const NetWorkImage({
    Key key,
    @required this.imageUrl,
  }) : super(key: key);

  final String imageUrl;

  @override
  Widget build(BuildContext context) {
    return Image(
      image: NetworkImage(imageUrl),
      width: 200,
      height: 200,
      fit: BoxFit.fill, 
      alignment: Alignment.bottomLeft,
      repeat: ImageRepeat.repeatY,
    );
  }
}
AssetImage加载本地图片
  • 首先在Flutter项目中引入图片资源;
  • 然后在pub spec.yaml文件中进行配置,然后执行flutter pub get命令;
  • 最后使用图片,流程如下:
image.png
  • 代码案例:
class _SFHomeContentState extends State<SFHomeContent>{
  final imageUrl = "";
  @override
  Widget build(BuildContext context) {
    print("_SFHomeContentState build");
    return Image(
      image: AssetImage("asset/images/180.png"),
    );
  }
}
  • 案例代码:
class ImageExtra extends StatelessWidget {
  const ImageExtra({
    Key key,
    @required this.imageUrl,
  }) : super(key: key);

  final String imageUrl;

  @override
  Widget build(BuildContext context) {
    return FadeInImage(
      placeholder: AssetImage("asset/images/180.png"), //设置占位图
      image: NetworkImage(imageUrl),//设置网络图片
      fadeOutDuration: Duration(milliseconds: 1),//淡入淡出的动画效果
      fadeInDuration: Duration(milliseconds: 1),
    );
  }
}
  • placeholder属性可设置占位图片;

Icon图标

  • Icon可设置字体图片与图片图标;
  • 字体图片与图片图标是矢量图,放大不会失真;
  • 图标可设置颜色;
  • 案例代码:
class _SFHomeContentState extends State<SFHomeContent>{
  final imageUrl = "";
  @override
  Widget build(BuildContext context) {
    print("_SFHomeContentState build");
    //1.Icon可设置字体图片与图片图标
    //2.字体图片与图片图标是矢量图,放大不会失真
    //3.图标可设置颜色
    //4.下面三种写法等价
    return Icon(Icons.pets,size: 200,color: Colors.red);
    // return Icon(IconData(0xe91d, fontFamily: 'MaterialIcons'),size: 200,color: Colors.red);
    // return Text("\ue91d",style: TextStyle(fontSize: 100,fontFamily: 'MaterialIcons',color: Colors.red));
  }
}

TextField

  • TextField:文本输入框,其构造函数如下:
class TextField extends StatefulWidget {
  const TextField({
    Key key,
    this.controller,
    this.focusNode,
    this.decoration = const InputDecoration(),
    TextInputType keyboardType,
    this.textInputAction,
    this.textCapitalization = TextCapitalization.none,
    this.style,
    this.strutStyle,
    this.textAlign = TextAlign.start,
    this.textAlignVertical,
    this.textDirection,
    this.readOnly = false,
    ToolbarOptions toolbarOptions,
    this.showCursor,
    this.autofocus = false,
    this.obscuringCharacter = '•',
    this.obscureText = false,
    this.autocorrect = true,
    SmartDashesType smartDashesType,
    SmartQuotesType smartQuotesType,
    this.enableSuggestions = true,
    this.maxLines = 1,
    this.minLines,
    this.expands = false,
    this.maxLength,
    this.maxLengthEnforced = true,
    this.onChanged,
    this.onEditingComplete,
    this.onSubmitted,
    this.inputFormatters,
    this.enabled,
    this.cursorWidth = 2.0,
    this.cursorRadius,
    this.cursorColor,
    this.selectionHeightStyle = ui.BoxHeightStyle.tight,
    this.selectionWidthStyle = ui.BoxWidthStyle.tight,
    this.keyboardAppearance,
    this.scrollPadding = const EdgeInsets.all(20.0),
    this.dragStartBehavior = DragStartBehavior.start,
    this.enableInteractiveSelection = true,
    this.onTap,
    this.mouseCursor,
    this.buildCounter,
    this.scrollController,
    this.scrollPhysics,
    this.autofillHints,
  })
  • controller:文本输入框的监听者;
  • focusNode:获取输入框的焦点;
  • decoration:设置边框,属于InputDecoration类型;
  • keyboardType:键盘类型;
  • style:设置输入文本的样式,属于TextStyle类型;
  • onChanged:输入框文本变化时的回调,属于void Function(T value)函数类型;
  • onSubmitted:输入框文本提交时的回调,属于void Function(T value)`函数类型;
  • enabled:设置是否点击;
  • onTap:输入框点击时的回调,属于void Function()函数类型;
  • cursorWidth:设置光标的宽度;
  • obscureText:设置输入内容是否隐藏,例如密码格式的输入;
  • 其中设置边框样式的InputDecoration,其构造函数如下:
const InputDecoration({
    this.icon,
    this.labelText,
    this.labelStyle,
    this.helperText,
    this.helperStyle,
    this.helperMaxLines,
    this.hintText,
    this.hintStyle,
    this.hintMaxLines,
    this.errorText,
    this.errorStyle,
    this.errorMaxLines,
    this.hasFloatingPlaceholder = true,
    this.floatingLabelBehavior = FloatingLabelBehavior.auto,
    this.isCollapsed = false,
    this.isDense,
    this.contentPadding,
    this.prefixIcon,
    this.prefixIconConstraints,
    this.prefix,
    this.prefixText,
    this.prefixStyle,
    this.suffixIcon,
    this.suffix,
    this.suffixText,
    this.suffixStyle,
    this.suffixIconConstraints,
    this.counter,
    this.counterText,
    this.counterStyle,
    this.filled,
    this.fillColor,
    this.focusColor,
    this.hoverColor,
    this.errorBorder,
    this.focusedBorder,
    this.focusedErrorBorder,
    this.disabledBorder,
    this.enabledBorder,
    this.border,
    this.enabled = true,
    this.semanticCounterText,
    this.alignLabelWithHint,
})
  • icon:位于装饰器外部和输入框前面的图片;
  • labelText:用于描述输入框,例如这个输入框是用来输入用户名还是密码的,当输入框获取焦点时默认会浮动到上方;
  • hintText:提示文本,位于输入框内部;
  • prefixIcon:位于输入框内部起始位置的图标;
  • suffixIcon:位于输入框后面的图片,例如一般输入框后面会有个眼睛,控制输入内容是否明文;
  • filled:如果为true,则输入使用fillColor指定的颜色填充;
  • fillColor:输入框的背景颜色;
  • 案例代码如下:
import 'package:flutter/material.dart';

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

class SFMyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SFHomePage()
    );
  }
}

class SFHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("基础widget")
      ),
      body: SFHomeContent()
    );
  }
}

class SFHomeContent extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    print("createState");
    return _SFHomeContentState();
  }
}


class _SFHomeContentState extends State<SFHomeContent>{
  final usernameTextEditController = TextEditingController();
  final passwordTextEditController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    print("_SFHomeContentState build");
    return Theme(
      data: ThemeData(
        primaryColor: Colors.red
      ),
      child: Padding(
        padding: EdgeInsets.all(8.0),
        child:Column(
          children: [
            TextField(
              controller: usernameTextEditController,
              decoration: InputDecoration(
                labelText: "username",
                icon: Icon(Icons.people),
                hintText: "请输入用户名",
                border: OutlineInputBorder(),
                filled: true,
                fillColor: Colors.red[100],
              ),
              onChanged: (value){
                print("onChanged:$value");
              },
              onSubmitted: (value){
                print("onSubmitted:$value");
              },
            ),
            SizedBox(height: 10),
            TextField(
              controller: passwordTextEditController,
              decoration: InputDecoration(
                labelText: "password",
                icon: Icon(Icons.lock),
                hintText: "请输入密码",
                border: InputBorder.none,
                filled: true,
                fillColor: Colors.red[100],
              ),
              onChanged: (value){
                print("onChanged:$value");
              },
              onSubmitted: (value){
                print("onSubmitted:$value");
              },
            ),
            SizedBox(height: 20),
            Container(
              width: 300,
              height: 35,
              child: FlatButton(
                child: Text("登 录",style: TextStyle(fontSize: 20,color: Colors.white)),
                color: Colors.blue,
                onPressed: (){
                  print("login");
                  final username = usernameTextEditController.text;
                  final password = passwordTextEditController.text;
                  print("username = $username,password = $password");
                },
              ),
            )
          ],
        )
      )
    );
  }
}
  • 运行结果如下:
image.png
  • Theme:设置整个UI的主题风格;
  • 给目标组件设置宽高,通常是在目标组件外面再包装一层Container,然后设置widthheight属性;
  • onChanged:监听输入框文本变化的回调;
  • onSubmitted:监听输入框提交时的回调;
  • 在登录按钮的点击回调中,获取输入框的文本是通过给输入框绑定一个TextEditingController,然后通过TextEditingController.text获取输入框的文本;

Divider

  • Divider:用来制作分割线的组件,构造函数如下:
const Divider({
    Key key,
    this.height,
    this.thickness,
    this.indent,
    this.endIndent,
    this.color,
})
  • indent:起点缩进距离;
  • endIndent:终点缩进距离;
  • color:分割线颜色;
  • height:分割线区域的高度,并非分割线的高度;
  • thickness:分割线的厚度,真正的分割线的高度;
  • 案例代码:
import 'package:YYShop/core/screenfit/appsize_fit.dart';
import 'package:flutter/material.dart';

class SFMinePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      child: Column(
        children: [
          Container(
            width: SFAppSizeFit.screenWidth,
            height: 100,
            color: Colors.red,
          ),
          Divider(
            color: Colors.black,
            thickness: 5,
            height: 5,
          ),
          Container(
            width: SFAppSizeFit.screenWidth,
            height: 100,
            color: Colors.red,
          ),
        ],
      ),
    );
  }
}
  • 效果图如下:
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容