Flutter入门04----基础Widget

2022-01-12  本文已影响0人  zyc_在路上

项目案例 -- StatelessWidget

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

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("商品列表"),
      ),
      body: SFContentBody(),
    );
  }
}

class SFContentBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
     return ListView(
       children: [
         SFProductItem("Apple1","MacBook1","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdl.bbs.9game.cn%2Fattachments%2Fforum%2F201507%2F29%2F154250no2g2zqiuiqvaiku.jpg&refer=http%3A%2F%2Fdl.bbs.9game.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1637072364&t=07974f838e1b49ecdecaba22f4af4fa2"),
         SFProductItem("Apple2","MacBook2","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdl.bbs.9game.cn%2Fattachments%2Fforum%2F201507%2F29%2F154250no2g2zqiuiqvaiku.jpg&refer=http%3A%2F%2Fdl.bbs.9game.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1637072364&t=07974f838e1b49ecdecaba22f4af4fa2"),
         SFProductItem("Apple3","MacBook3","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdl.bbs.9game.cn%2Fattachments%2Fforum%2F201507%2F29%2F154250no2g2zqiuiqvaiku.jpg&refer=http%3A%2F%2Fdl.bbs.9game.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1637072364&t=07974f838e1b49ecdecaba22f4af4fa2"),
       ],
     );
  }
}

class SFProductItem extends StatelessWidget {
  final String title;
  final String desc;
  final String imageUrl;

  final titleStyle = TextStyle(fontSize: 25,color: Colors.orange);
  final descStyle = TextStyle(fontSize: 20,color: Colors.green);

  //自定义构造函数
  SFProductItem(this.title,this.desc,this.imageUrl);
  
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(8), //设置内边距
      decoration: BoxDecoration(
        border: Border.all(
          width: 5, //设置边框的宽度
          color: Colors.purple //设置边框的额颜色
        )
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(title,style: titleStyle),
          SizedBox(height: 8),//设置间距
          Text(desc,style: descStyle),
          SizedBox(height: 8),
          Image.network(imageUrl)
        ],
      ),
    );
  }
}
image.png

项目案例 -- StatefulWidget

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.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("商品列表")
      ),
      body: SFHomeContent("上面是一个简单的计数器")
    );
  }
}

class SFHomeContent extends StatefulWidget {
  final String message;

  SFHomeContent(this.message);

  @override
  State<StatefulWidget> createState() {
    return _SFHomeContentState();
  }
}

//
class _SFHomeContentState extends State<SFHomeContent>{

  var _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          _getButtons(),
          Text("当前计数: $_counter",style: TextStyle(fontSize: 20)),
          Text("${widget.message}",style: TextStyle(fontSize: 18))
        ],
      ),
    );
  }

  Widget _getButtons(){
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        RaisedButton(
          child: Text("+",style: TextStyle(fontSize: 20,color: Colors.white)),
          color: Colors.pink,
          onPressed: (){
            print("点击+");
            setState(() {
              _counter++;
            });
          },
        ),
        RaisedButton(
          child: Text("-",style: TextStyle(fontSize: 20,color: Colors.white)),
          color: Colors.purple,
          onPressed: (){
            print("点击-");
            setState(() {
              _counter--;
            });
          },
        )
      ],
    );
  }
}
image.png

StatefulWidget生命周期

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("商品列表")
      ),
      body: SFHomeContent("上面是一个简单的计数器")
    );
  }
}

class SFHomeContent extends StatefulWidget {
  final String message;

  SFHomeContent(this.message){
    print("SFHomeContent 构造方法");
  }

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

class _SFHomeContentState extends State<SFHomeContent>{

  var _counter = 0;

  _SFHomeContentState(){
    print("_SFHomeContentState 构造方法");
  }

  @override
  void initState() {
    super.initState();
    print("_SFHomeContentState initState");
  }

  @override
  Widget build(BuildContext context) {
    print("_SFHomeContentState build");
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          RaisedButton(
            child: Text("+",style: TextStyle(fontSize: 25,color: Colors.white)),
            color: Colors.pinkAccent,
            onPressed: (){
              setState(() {
                _counter++;
              });
            },
          ),
          Text("${widget.message}",style: TextStyle(fontSize: 18))
        ],
      ),
    );
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print("_SFHomeContentState didChangeDependencies");
  }

  @override
  void didUpdateWidget(SFHomeContent oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("_SFHomeContentState didUpdateWidget");
  }

- 

  @override
  void dispose() {
    super.dispose();
    print("_SFHomeContentState dispose");
  }
}
image.png

Flutter的编程范式

final text = new Text();
var title = "Hello World";
text.setContent(title); //主动设置title
var title = "Hello World";
Text(title); //告诉Text内部显示的是title

基础Widget

文本Widget
普通文本
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 TextDemo();
  }
}

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'
      ),
    );
  }
}
富文本
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 TextRichDemo();
  }
}

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))
        ]
      )
    );
  }
}
按钮Widget
RaisedButton
class RaisedButton extends MaterialButton {
  /// Create a filled button.
  ///
  /// The [autofocus] and [clipBehavior] arguments must not be null.
  /// Additionally,  [elevation], [hoverElevation], [focusElevation],
  /// [highlightElevation], and [disabledElevation] must be non-negative, if
  /// specified.
  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
class FlatButton extends MaterialButton {
  /// Create a simple text button.
  ///
  /// The [autofocus] and [clipBehavior] arguments must not be null.
  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
class OutlineButton extends MaterialButton {
  /// Create an outline button.
  ///
  /// The [highlightElevation] argument must be null or a positive value
  /// and the [autofocus] and [clipBehavior] arguments must not be null.
  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
class FloatingActionButton extends StatelessWidget {
  /// Creates a circular floating action button.
  ///
  /// The [mini] and [clipBehavior] arguments must not be null. Additionally,
  /// [elevation], [highlightElevation], and [disabledElevation] (if specified)
  /// must be non-negative.
  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
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();
  }
}

//`ButtonTheme`属性,自定义任意尺寸大小
//通过`padding`属性,去除内容边距
class _SFHomeContentState extends State<SFHomeContent>{
  final imageUrl = "";
  @override
  Widget build(BuildContext context) {
    print("_SFHomeContentState build");
    return Column(
      children: [
        ButtonTheme(
          minWidth: 30,
          height: 15,
          child: FlatButton(
            color: Colors.red,
            materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
            child: Text("FlatButton"),
            textColor: Colors.white,
            padding: EdgeInsets.all(0),
            onPressed: (){
              print("click FlatButton");
            },
          ),
        )
      ],
    );
  }
}

class ButtonExtra01 extends StatelessWidget {
  const ButtonExtra01({
    Key key,
  }) : super(key: key);
  //`materialTapTargetSize`属性,去除间距
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        FlatButton(
          color: Colors.red,
          child: Text("FlatButton"),
          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
          textColor: Colors.white,
          onPressed: (){
            print("click FlatButton");
          },
        ),
        FlatButton(
          color: Colors.red,
          child: Text("FlatButton"),
          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
          textColor: Colors.white,
          onPressed: (){
            print("click FlatButton");
          },
        )
      ],
    );
  }
}
图片Widget
class Image extends StatefulWidget {
  /// Creates a widget that displays an image.
  ///
  /// To show an image from the network or from an asset bundle, consider using
  /// [new Image.network] and [new Image.asset] respectively.
  ///
  /// The [image], [alignment], [repeat], and [matchTextDirection] arguments
  /// must not be null.
  ///
  /// Either the [width] and [height] arguments should be specified, or the
  /// widget should be placed in a context that sets tight layout constraints.
  /// Otherwise, the image dimensions will change as the image is loaded, which
  /// will result in ugly layout changes.
  ///
  /// Use [filterQuality] to change the quality when scaling an image.
  /// Use the [FilterQuality.low] quality setting to scale the image,
  /// which corresponds to bilinear interpolation, rather than the default
  /// [FilterQuality.none] which corresponds to nearest-neighbor.
  ///
  /// If [excludeFromSemantics] is true, then [semanticLabel] will be ignored.
  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,
  })
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加载本地图片
image.png
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 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),
    );
  }
}
Icon图标
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 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));
  }
}
输入框Widget -- TextField
class TextField extends StatefulWidget {
  /// Creates a Material Design text field.
  ///
  /// If [decoration] is non-null (which is the default), the text field requires
  /// one of its ancestors to be a [Material] widget.
  ///
  /// To remove the decoration entirely (including the extra padding introduced
  /// by the decoration to save space for the labels), set the [decoration] to
  /// null.
  ///
  /// The [maxLines] property can be set to null to remove the restriction on
  /// the number of lines. By default, it is one, meaning this is a single-line
  /// text field. [maxLines] must not be zero.
  ///
  /// The [maxLength] property is set to null by default, which means the
  /// number of characters allowed in the text field is not restricted. If
  /// [maxLength] is set a character counter will be displayed below the
  /// field showing how many characters have been entered. If the value is
  /// set to a positive integer it will also display the maximum allowed
  /// number of characters to be entered.  If the value is set to
  /// [TextField.noMaxLength] then only the current length is displayed.
  ///
  /// After [maxLength] characters have been input, additional input
  /// is ignored, unless [maxLengthEnforced] is set to false. The text field
  /// enforces the length with a [LengthLimitingTextInputFormatter], which is
  /// evaluated after the supplied [inputFormatters], if any. The [maxLength]
  /// value must be either null or greater than zero.
  ///
  /// If [maxLengthEnforced] is set to false, then more than [maxLength]
  /// characters may be entered, and the error counter and divider will
  /// switch to the [decoration.errorStyle] when the limit is exceeded.
  ///
  /// The text cursor is not shown if [showCursor] is false or if [showCursor]
  /// is null (the default) and [readOnly] is true.
  ///
  /// The [selectionHeightStyle] and [selectionWidthStyle] properties allow
  /// changing the shape of the selection highlighting. These properties default
  /// to [ui.BoxHeightStyle.tight] and [ui.BoxWidthStyle.tight] respectively and
  /// must not be null.
  ///
  /// The [textAlign], [autofocus], [obscureText], [readOnly], [autocorrect],
  /// [maxLengthEnforced], [scrollPadding], [maxLines], [maxLength],
  /// [selectionHeightStyle], [selectionWidthStyle], and [enableSuggestions]
  /// arguments must not be null.
  ///
  /// See also:
  ///
  ///  * [maxLength], which discusses the precise meaning of "number of
  ///    characters" and how it may differ from the intuitive meaning.
  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,
  })
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
单子布局组件
Align组件
class _SFHomeContentState extends State<SFHomeContent>{
  @override
  Widget build(BuildContext context) {
    print("_SFHomeContentState build");

    return Container(
      color: Colors.red,
      child: Align(
        child: Icon(Icons.pets,size: 50),
        alignment: Alignment(0,0),
        widthFactor: 5,
        heightFactor: 3,
      ),
    );
  }
}
Padding组件
const Padding({
    Key key,
    @required this.padding,
    Widget child,
  })
class _SFHomeContentState extends State<SFHomeContent>{
  @override
  Widget build(BuildContext context) {
    print("_SFHomeContentState build");
    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.only(bottom: 5),
          child: Text("日你啊满满的个单",style: TextStyle(fontSize: 20,backgroundColor: Colors.red)),
        ),
        Padding(
          padding: const EdgeInsets.only(bottom: 5),
          child: Text("日你啊满满的个单",style: TextStyle(fontSize: 20,backgroundColor: Colors.red)),
        ),
        Text("日你啊满满的个单",style: TextStyle(fontSize: 20,backgroundColor: Colors.red))
      ],
    );
  }
}
Container组件
Container({
    Key key,
    this.alignment,
    this.padding,
    this.color,
    this.decoration,
    this.foregroundDecoration,
    double width,
    double height,
    BoxConstraints constraints,
    this.margin,
    this.transform,
    this.child,
    this.clipBehavior = Clip.none,
  })
class _SFHomeContentState extends State<SFHomeContent>{
  @override
  Widget build(BuildContext context) {
    return Container(
      // color: Colors.red,
      width: 200,
      height: 200,
      child: Text("这是一个文本",style: TextStyle(color: Colors.white),),
      alignment: Alignment(0,0),
      padding: EdgeInsets.all(20),
      margin: EdgeInsets.all(10),
      decoration: BoxDecoration(
        color: Colors.red,
        border: Border.all(
          width: 5,
          color: Colors.purple
        ),
        borderRadius: BorderRadius.circular(100),
        boxShadow: [
          BoxShadow(color: Colors.orange,offset: Offset(10,10),spreadRadius: 5,blurRadius: 10),
          BoxShadow(color: Colors.blue,offset: Offset(-10,10),spreadRadius: 5,blurRadius: 10)
        ]
      ),
    );
  }
}
image.png
多子布局组件
Flex组件
Row组件
class _SFHomeContentState extends State<SFHomeContent>{
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.bug_report),
          Text("bug")
        ],
      ),
    );
  }
}
class RowDemo extends StatelessWidget {
  const RowDemo({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.center,
      textBaseline: TextBaseline.alphabetic,
      children: [
        Container(width: 80,height: 60,color: Colors.red),
        Container(width: 80,height: 80,color: Colors.green),
        Container(width: 80,height: 100,color: Colors.blue),
        Container(width: 80,height: 120,color: Colors.orange),
      ],
    );
  }
}
Flexible与Expanded
class RowDemo2 extends StatelessWidget {
  const RowDemo2({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.center,
      textBaseline: TextBaseline.alphabetic,
      children: [
        Flexible(
          child: Container(width: 80,height: 60,color: Colors.red),
          fit: FlexFit.tight,
        ),
        Expanded(
          child: Container(width: 80,height: 80,color: Colors.green),
        ),
        Container(width: 80,height: 100,color: Colors.blue),
        Container(width: 80,height: 120,color: Colors.orange),
      ],
    );
  }
}

这里补充个小知识点: 如果children中出现2个Flexible或者Expand,那么剩余空间会根据两个Expand的Flex比例来填充,如果没有设置Flex,那么默认的Flex值为1

Column组件
Stack组件
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) {
    return StackDemo1();
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
            height: 200,
            child: Image.asset("asset/images/180.png", fit: BoxFit.fill),
            width: double.infinity),
        Positioned(
          child: Container(
            child: Row(
              children: [
                Text("这是一行文本", style: TextStyle(fontSize: 17, color: Colors.white)),
                IconButton(icon: Icon(Icons.favorite),color: Colors.white,onPressed: (){
                })
              ],
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
            ),
            color: Color.fromARGB(150, 0, 0, 0),
            width: double.infinity,
            padding: EdgeInsets.symmetric(horizontal: 8),
          ),
          left: 0,
          right: 0,
          bottom: 0,
        )
      ],
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Image.asset("asset/images/180.png"),
        Positioned(
          child: Container(
            width: 100,
            height: 100,
            color: Colors.green,
          ),
          right: 0,
        ),
        Positioned(
          child: Text("推客图标", style: TextStyle(fontSize: 20)),
          left: 0,
        )
      ],
      alignment: AlignmentDirectional.bottomStart,
      overflow: Overflow.visible,
    );
  }
}
image.png image.png

ListView

ListView创建方式
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 StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      scrollDirection: Axis.vertical,
      itemExtent: 100,//设置Item的高度
      children: List.generate(100, (index) {
        return ListTile(
          leading: Icon(Icons.people),
          trailing: Icon(Icons.delete),
          title: Text("联系人${index+1}"),
          subtitle: Text("联系人电话号码:19991604555"),
        );
      }),
    );
  }
}
image.png
class SFHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: 100,
        itemExtent: 50,
        itemBuilder: (BuildContext ctx, int index){
          return Text("Hello World!!! ${index}",style: TextStyle(fontSize: 20),);
    }
    );
  }
}
class SFHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.separated(
        itemBuilder: (BuildContext ctx, int index){
          return Text("Hello World!!! ${index}",style: TextStyle(fontSize: 20),);
        },
        //分割线
        separatorBuilder: (BuildContext ctx,int index){
          return Divider(color: Colors.red,indent: 20,endIndent: 20,thickness: 5);
        },
        itemCount: 100
    );
  }
}

GridView

class SFHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3,
        childAspectRatio: 1.5,
        crossAxisSpacing: 8,
        mainAxisSpacing: 8
      ),
      children:
        List.generate(100, (index) {
           return Container(
             color: Color.fromARGB(255, Random().nextInt(256), Random().nextInt(256), Random().nextInt(256)),
           );
        }),
    );
  }
}
class SFHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView(
      gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
        maxCrossAxisExtent: 220,
        crossAxisSpacing: 8,
        mainAxisSpacing: 8,
        childAspectRatio: 1.5
      ),
      children: List.generate(100, (index) {
        return Container(
          color: Color.fromARGB(255, Random().nextInt(256), Random().nextInt(256),Random().nextInt(256)),
        );
      })
    );
  }
}
class SFHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
          crossAxisSpacing: 8,
          mainAxisSpacing: 8
        ),
        itemBuilder: (BuildContext ctx,int index){
          return Container(
            color: Color.fromARGB(255, Random().nextInt(256), Random().nextInt(256),Random().nextInt(256)),
          );
        }
    );
  }
}

Slivers -- CustomScrollView

import 'dart:math';
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 StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SliverDemo1();
  }
}

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

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: [
        SliverSafeArea(
          sliver: SliverPadding(
            padding: EdgeInsets.all(8),
            sliver: SliverGrid(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                crossAxisSpacing: 8,
                mainAxisSpacing: 8,
                childAspectRatio: 1.5
              ),
              delegate: SliverChildBuilderDelegate(
                  (BuildContext ctx,int index){
                    return Container(
                      color: Color.fromARGB(255, Random().nextInt(256), Random().nextInt(256),Random().nextInt(256)),
                    );
                  },
                childCount: 100
              ),
            ),
          ),
        )
      ],
    );
  }
}
import 'dart:math';
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 StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: [
        SliverAppBar(
          pinned: true,
          expandedHeight: 200,
          flexibleSpace: FlexibleSpaceBar(
            title: Text("Hello World!!",style: TextStyle(fontSize: 25),),
          ),
        ),
        SliverGrid(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              crossAxisSpacing: 8,
              mainAxisSpacing: 8,
              childAspectRatio: 2.5
          ),
            delegate: SliverChildBuilderDelegate(
                    (BuildContext ctx,int index){
                  return Container(
                    color: Color.fromARGB(255, Random().nextInt(256), Random().nextInt(256),Random().nextInt(256)),
                  );
                },
                childCount: 10
            ),
        ),
        SliverList(
          delegate: SliverChildBuilderDelegate(
              (BuildContext ctx,int index){
                return ListTile(
                  leading: Icon(Icons.people),
                  title: Text("联系人$index"),
                );
              },
            childCount: 20
          ),
        )
      ],
    );
  }
}

滚动组件的监听

controller监听
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 StatefulWidget {
  @override
  _SFHomePageState createState() => _SFHomePageState();
}

class _SFHomePageState extends State<SFHomePage> {
  ScrollController controller = ScrollController(initialScrollOffset: 300);
  bool isShowFloatButton = false;

  @override
  void initState() {
    super.initState();
    controller.addListener(() {
      print("监听到滚动: ${controller.offset}");
      setState(() {
        isShowFloatButton = controller.offset >= 1000;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("基础widget")),
      body: SFHomeContent(controller),
      floatingActionButton: isShowFloatButton ? FloatingActionButton(
        child: Icon(Icons.arrow_upward),
        onPressed: (){
          controller.animateTo(0, duration: Duration(seconds: 1), curve: Curves.easeIn);
        },
      ) : null,
    );
  }
}

class SFHomeContent extends StatelessWidget {
  final ScrollController controller;
  SFHomeContent(this.controller);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      controller: controller,
      itemBuilder: (BuildContext ctx, int index) {
        return ListTile(
          leading: Icon(Icons.people),
          title: Text("联系人$index"),
        );
      },
      itemCount: 100,
    );
  }
}
NotificationListener监听
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 StatefulWidget {
  @override
  _SFHomePageState createState() => _SFHomePageState();
}

class _SFHomePageState extends State<SFHomePage> {
  bool isShowFloatButton = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("基础widget")),
      body: SFHomeContent(),
      floatingActionButton: isShowFloatButton
          ? FloatingActionButton(
              child: Icon(Icons.arrow_upward),
              onPressed: () {

              },
            )
          : null,
    );
  }
}

class SFHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return NotificationListener(
      onNotification: (ScrollNotification notification){
        if(notification is ScrollStartNotification){
          print("开始滚动");
        }else if (notification is ScrollUpdateNotification){
          print("正在滚动 -- 总区域:${notification.metrics.maxScrollExtent} 当前位置: ${notification.metrics.pixels}");
        }else if (notification is ScrollEndNotification){
          print("结束滚动");

        }

        return true;
      },
      child: ListView.builder(
        itemBuilder: (BuildContext ctx, int index) {
          return ListTile(
            leading: Icon(Icons.people),
            title: Text("联系人$index"),
          );
        },
        itemCount: 100,
      ),
    );
  }
}

总结

上一篇 下一篇

猜你喜欢

热点阅读