Flutter之常用组件的使用举例(中)

一、Swiper
   #轮播组件
  flutter_swiper: ^1.1.6

基本使用

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

class Loginpage extends StatefulWidget {
  const Loginpage({Key key}) : super(key: key);

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

class _LoginpageState extends State<Loginpage> {
  List<Map> _imglist = [
    {"url": "https://img-blog.csdnimg.cn/0c89c01ee6594c839e79122b724c40f9.png"},
    {"url": "https://img-blog.csdnimg.cn/420fdd67f9db4ccfb5e69b5b20ec6ee9.png"},
    {"url": "https://img-blog.csdnimg.cn/09c48a7e62bf4b4b938efc25b57d1900.png"},
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Swiper"),
      ),
      body: new Swiper(
        itemBuilder: (BuildContext context, int index) {
          return new Image.network(
            this._imglist[index]["url"],
            fit: BoxFit.fill,
          );
        },
        itemCount:this._imglist.length,
        pagination: new SwiperPagination(),
        control: new SwiperControl(),
      ),
    );
  }
}

封装轮播

import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:myshop_flutter/config/index.dart';
import 'package:myshop_flutter/model/home_model.dart';
import 'package:myshop_flutter/widgets/cached_image_widget.dart';

class HomeBannerWidget extends StatelessWidget {
  //轮播图数据
   List<BannerModel> bannerData ;
//  List bannerData = List();
  //数量
  int size;
  //视图高度
  HomeBannerWidget(this.bannerData, this.size, this.viewHeight);
  double viewHeight;
  @override
  Widget build(BuildContext context) {
    return Container(
        height: viewHeight,
        width: double.infinity,
        child: bannerData == null || bannerData.length == 0
            //没有数据提示
            ? Container(
                height: 400,
                color: Colors.grey,
                //居中显示
                alignment: Alignment.center,
                //没有数据文本提示
                child: Text(KString.NO_DATA_TEXT),
              )
            //轮播组件
            : Swiper(
                //点击跳转
                //   onTap: (index) {
                // NavigatorUtil.goWebView(context, bannerData[index].name, bannerData[index].link);
                //  },
                //轮播图数量
                itemCount: size,
                //指定滚动方向
                scrollDirection: Axis.horizontal,
                //滚动方向,设置为Axis.vertical如果需要垂直滚动
                loop: true,
                //无限轮播模式开关
                index: 0,
                //初始的时候下标位置
                autoplay: false,
                itemBuilder: (BuildContext buildContext, int index) {
                  //使用缓存图片组件显示轮播图
                  // return CachedImageWidget(
                  //     double.infinity, double.infinity, bannerData[index].url);
                  return Container(
                    width: double.infinity,
                    child: CachedImageWidget(
    double.infinity, double.infinity, bannerData[index].url)

                  );
                },
                //滚动时长
                duration: 40000,
                //指定分页组件
                pagination: SwiperPagination(
                    //底部居中展示
                    alignment: Alignment.bottomCenter,
                    //构建小圆点
                    builder: DotSwiperPaginationBuilder(
                        size: 8.0,
                        //未点击颜色
                        color: KColor.bannerDefaultColor,
                        //点击颜色
                        activeColor: KColor.bannerActiveColor)),
              ));
  }
}

Widget _buildBanner() {
    return Container(
      child: bannerList.length == 0
          ? Container()
          : Container(
              height: 162,
              child: Swiper(
                itemBuilder: (BuildContext context, int index) {
                  return _createBanner(index);
                },
                pagination: SwiperPagination(
                  margin: EdgeInsets.only(bottom: 10),
                  builder: DotSwiperPaginationBuilder(
                    color: Colors.white30,
                    activeColor: Colors.white,
                    size: 8,
                    activeSize: 8,
                  ),
                ),
                itemCount: bannerList.length,
                viewportFraction: 1,
                autoplayDelay: 3000,
                scale: 1,
                autoplay: true,
                onTap: (index) {},
              ),
            ),
    );
  }
   _createBanner(int index) {
    return GestureDetector(
      onTap: () {},
      child: Container(
        width: double.infinity,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(bannerList[index]),
            fit: BoxFit.cover,
          ),
          borderRadius: BorderRadius.circular(8),
        ),
      ),
    );
  }
      List bannerList = [
    'https://tse1-mm.cn.bing.net/th/id/R-C.65398d6ad86129f9628c0ad80da4040c?rik=C3qNS9mZOQk%2b5A&riu=http%3a%2f%2fwww.shijuepi.com%2fuploads%2fallimg%2f200918%2f1-20091Q10420.jpg&ehk=QBNuJIbVP1qo%2bwUD3YzXcvL4H5iHivOHXUnzzRw%2bWfU%3d&risl=&pid=ImgRaw&r=0',
    'https://tse1-mm.cn.bing.net/th/id/R-C.65398d6ad86129f9628c0ad80da4040c?rik=C3qNS9mZOQk%2b5A&riu=http%3a%2f%2fwww.shijuepi.com%2fuploads%2fallimg%2f200918%2f1-20091Q10420.jpg&ehk=QBNuJIbVP1qo%2bwUD3YzXcvL4H5iHivOHXUnzzRw%2bWfU%3d&risl=&pid=ImgRaw&r=0',
    'https://tse1-mm.cn.bing.net/th/id/R-C.65398d6ad86129f9628c0ad80da4040c?rik=C3qNS9mZOQk%2b5A&riu=http%3a%2f%2fwww.shijuepi.com%2fuploads%2fallimg%2f200918%2f1-20091Q10420.jpg&ehk=QBNuJIbVP1qo%2bwUD3YzXcvL4H5iHivOHXUnzzRw%2bWfU%3d&risl=&pid=ImgRaw&r=0,'
  ];

AppBar 和 SliverAppBar 都是继承至 StatefulWidget 类,都代表 Toobar,二则的区别在于 AppBar 位置的固定的应用最上面的;而 SliverAppBar 是可以跟随内容滚动的。
leading:在标题前面显示的一个控件,在首页通常显示应用的 logo;在其他界面通常显示为返回按钮。
title: Toolbar 中主要内容,通常显示为当前界面的标题文字。
actions:一个 Widget 列表,代表 Toolbar 中所显示的菜单,对于常用的菜单,通常使用 IconButton 来表示;对于不常用的菜单通常使用PopupMenuButton 来显示为三个点,点击后弹出二级菜单。
bottom:一个 AppBarBottomWidget 对象,通常是 TabBar。用来在 Toolbar 标题下面显示一个 Tab 导航栏。
elevation:纸墨设计中控件的 z 坐标顺序,默认值为 4,对于可滚动的 SliverAppBar,当 SliverAppBar 和内容同级的时候,该值为 0, 当内容滚动
SliverAppBar 变为 Toolbar 的时候,修改 elevation 的值。
flexibleSpace:一个显示在 AppBar 下方的控件,高度和 AppBar 高度一样,可以实现一些特殊的效果,该属性通常在 SliverAppBar 中使用
backgroundColor:Appbar 的颜色,默认值为 ThemeData.primaryColor。该值通常和下面的三个属性一起使用:
brightness:App bar 的亮度,有白色和黑色两种主题,默认值为 ThemeData.primaryColorBrightness
iconTheme:App bar 上图标的颜色、透明度、和尺寸信息。默认值为 ThemeData.primaryIconTheme
textTheme:App bar 上的文字样式。默认值为 ThemeData.primaryTextTheme
centerTitle: 标题是否居中显示,默认值根据不同的操作系统,显示方式不一样

二、CustomScrollView

CustomScrollView是使用Sliver组件创建自定义滚动效果的滚动组件。使用场景: ListView和GridView相互嵌套场景,ListView嵌套GridView时,需要给GridView指定高度,但我们希望高度随内容而变化(不指定),ListView和GridView使用同一个滚动效果。一个页面顶部是AppBar,然后是GridView,最后是ListView,这3个区域以整体来滚动,AppBar具有吸顶效果。CustomScrollView就像一个粘合剂,将多个组件粘合在一起,具统一的滚动效果。Sliver系列组件有很多,比如SliverList、SliverGrid、SliverFixedExtentList、SliverPadding、SliverAppBar等。

相互嵌套场景

在实际业务场景中经常见到这样的布局,顶部是网格布局(GridView),然后是列表布局(ListView),滚动的时候做为一个整体,此场景是无法使用GridView+ListView来实现的,而是需要使用CustomScrollView+SliverGrid+SliverList来实现,实现代码如下

CustomScrollView(
  slivers: <Widget>[
    SliverGrid.count(crossAxisCount: 4,children: List.generate(8, (index){
      return Container(
        color: Colors.primaries[index%Colors.primaries.length],
        alignment: Alignment.center,
        child: Text('$index',style: TextStyle(color: Colors.white,fontSize: 20),),
      );
    }).toList(),),
    SliverList(
      delegate: SliverChildBuilderDelegate((content, index) {
        return Container(
          height: 85,
          alignment: Alignment.center,
          color: Colors.primaries[index % Colors.primaries.length],
          child: Text('$index',style: TextStyle(color: Colors.white,fontSize: 20),),
        );
      }, childCount: 25),
    )
  ],
)

controller为滚动控制器,可以监听滚到的位置

_scrollController = ScrollController();

//监听滚动位置
    _scrollController.addListener((){
      print('${_scrollController.position}');
    });
    //滚动到指定位置
    _scrollController.animateTo(20.0);

CustomScrollView(
	controller: _scrollController,
	...
) 

顶部跳转

import 'dart:math';

import 'package:flutter/material.dart';

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

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

class _MessagepageState extends State<Messagepage> {
  bool isshowBtn = false;
  ScrollController _Controller = ScrollController(initialScrollOffset: 100);
  @override
  void initState() {
    super.initState();
    _Controller.addListener(() {
      setState(() {
        isshowBtn = _Controller.offset >= 1000;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: this.isshowBtn?FloatingActionButton(
        onPressed: () {
          _Controller.animateTo(0,
              duration: Duration(seconds: 1), curve: Curves.easeIn);
        },
        child: Icon(Icons.arrow_upward),
      ):null,
      body: ListView.builder(
        controller: _Controller,
        itemCount: 100,
        itemBuilder: (BuildContext ctx, int index) {
          return ListTile(
            leading: Icon(Icons.people),
            title: Text("联系$index"),
          );
        },
      ),
    );
  }
}

监听开始滑动事件

import 'dart:math';

import 'package:flutter/material.dart';

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

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

class _MessagepageState extends State<Messagepage> {
  bool isshowBtn = false;
  ScrollController _Controller = ScrollController(initialScrollOffset: 100);
  @override
  void initState() {
    super.initState();
    _Controller.addListener(() {
      setState(() {
        //_Controller不能监听开始滚动和结束滚动
        isshowBtn = _Controller.offset >= 1000;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: this.isshowBtn
          ? FloatingActionButton(
              onPressed: () {
                _Controller.animateTo(0,
                    duration: Duration(seconds: 1), curve: Curves.easeIn);
              },
              child: Icon(Icons.arrow_upward),
            )
          : null,
      body: NotificationListener(
        //监听是否开始或者结束滚动
        onNotification: (ScrollNotification notification) {
          if (notification is ScrollNotification) {
            print("开始滚动");
          } else if (notification is ScrollUpdateNotification) {
            print("正在滚动,总滚动距离${notification.metrics.maxScrollExtent},当前滚动位置:${notification.metrics.pixels}");
          } else if (notification is ScrollNotification) {
            print("结束滚动");
          }
          return true;
        },
        child: ListView.builder(
          controller: _Controller,
          itemCount: 100,
          itemBuilder: (BuildContext ctx, int index) {
            return ListTile(
              leading: Icon(Icons.people),
              title: Text("联系$index"),
            );
          },
        ),
      ),
    );
  }
}

实例

import 'dart:math';

import 'package:flutter/material.dart';

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

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

class _MessagepageState extends State<Messagepage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        //安全区域
        slivers: [
          SliverAppBar(
            expandedHeight: 300, //扩展导航条的高度
            flexibleSpace: FlexibleSpaceBar(
              title: Text("helloword"),
              background: Image.network("https://img-blog.csdnimg.cn/77b16c81bfea42b39feb940c694ee41a.png"),
            ),
            pinned: true, //固定导航条
          ),
          //不能存放普通的widget
          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 int) {
                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("aaa"),
              );
            }, childCount: 20),
          )
        ],
      ),
    );
  }
}

·

三、 ListView

ListView.builder()

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('day_2',
              textDirection: TextDirection.ltr,
              style: TextStyle(fontSize: 10, color: Colors.purpleAccent),
              textAlign: TextAlign.center,
              maxLines: 1),
        ),
        body: HomeContent(),
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  List listData = [
    {
      "title": 'Candy Shop',
      "author": "Mohamed",
      "imagesUrl":
          "https://img-blog.csdnimg.cn/07bec00ef4d54b66a856ca14f222001b.png"
    },
    {
      "title": 'Candy Shop2',
      "author": "Mohamed2",
      "imagesUrl":
          "https://img-blog.csdnimg.cn/07bec00ef4d54b66a856ca14f222001b.png"
    },
    {
      "title": 'Candy Shop3',
      "author": "Mohamed3",
      "imagesUrl":
          "https://img-blog.csdnimg.cn/07bec00ef4d54b66a856ca14f222001b.png"
    }
  ];
  Widget _getListData(context,index) {
    return Container(
      child: Column(
        children: <Widget>[
          Image.network(listData[index]["imagesUrl"]),
          SizedBox(height: 4),
          Text(
            listData[index]["title"],
            textAlign: TextAlign.center,
            style: TextStyle(fontSize: 20),
          )
        ],
      ),
      decoration:
          BoxDecoration(border: Border.all(color: Colors.deepPurple, width: 2)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2, //一行多少个组件
        mainAxisSpacing: 10,
        crossAxisSpacing: 10,
      ),
      itemCount: listData.length,
      itemBuilder: this._getListData,
    );
  }
}

ListView.count

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('day_2',
              textDirection: TextDirection.ltr,
              style: TextStyle(fontSize: 10, color: Colors.purpleAccent),
              textAlign: TextAlign.center,
              maxLines: 1),
        ),
        body: HomeContent(),
      ),
    );
  }
}

class HomeContent extends StatelessWidget {
  List<Widget> _getListData() {
    List listData = [
      {
        "title": 'Candy Shop',
        "author": "Mohamed",
        "imagesUrl":
            "https://img-blog.csdnimg.cn/07bec00ef4d54b66a856ca14f222001b.png"
      },
      {
        "title": 'Candy Shop2',
        "author": "Mohamed2",
        "imagesUrl":
            "https://img-blog.csdnimg.cn/07bec00ef4d54b66a856ca14f222001b.png"
      },
      {
        "title": 'Candy Shop3',
        "author": "Mohamed3",
        "imagesUrl":
            "https://img-blog.csdnimg.cn/07bec00ef4d54b66a856ca14f222001b.png"
      }
    ];
    var tempList = listData.map((value) {
      return Container(
        child: Column(
          children: <Widget>[
            Image.network(value["imagesUrl"]),
            SizedBox(height: 4),
            Text(value["title"],
            textAlign: TextAlign.center,
            style: TextStyle(
              fontSize: 20
            ),
            )
          ],
        ),
        decoration: BoxDecoration(
          border: Border.all(
            color: Colors.deepPurple,
            width: 2
          )
        ),
      );
    });
    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
        padding: EdgeInsets.all(10),
        crossAxisCount: 2, //一行多少个组件
        mainAxisSpacing: 10,
        crossAxisSpacing: 10,
        // childAspectRatio: 0.7, //宽度和高度的比例是0.7
        children: this._getListData());
  }
}
四、showDialog

builder通常返回Dialog组件,比如SimpleDialog和AlertDialog。
useRootNavigator参数用于确定是否将对话框推送到给定“context”最远或最接近的Navigator。默认情况下,useRootNavigator为“true”,被推送到根Navigator。如果应用程序有多个Navigator,关闭对话框需要使用


     return showDialog(
      context: context,
        barrierDismissible: true,
        //barrierDismissible可以控制点击对话框以外的区域是否隐藏对话框。
      builder: (BuildContext context){
        return AlertDialog(
          //提示
          title: Text("是否删除"),
          content: Text("内容"),
          actions: [
            FlatButton(
              child: Text("取消") ,
              onPressed: (){
                Navigator.pop(context);
              },
            ),
            FlatButton(
              child: Text("确定"),
            )
            
          ],
        );
      }
    );
  }

Flutter之常用组件的使用举例(中)_第1张图片

barrierDismissible:是否可以点击背景关闭。

barrierColor:背景颜色

transitionDuration:动画时长,
transitionBuilder是构建进出动画,默认动画是渐隐渐显,构建缩放动画

showMenu

  _showMuneDialog(){
    return showMenu(
        context: context,
        position: RelativeRect.fromLTRB(20, 100, 0, 30),
        items: <PopupMenuEntry>[
          PopupMenuItem(child: Text('语文')),
          PopupMenuDivider(),
          CheckedPopupMenuItem(
            child: Text('数学'),
            checked: true,
          ),
          PopupMenuDivider(),
          PopupMenuItem(child: Text('英语')),
        ]);
  }

Flutter之常用组件的使用举例(中)_第2张图片

五、showSearch

在一般的 App 页面,可能都需要搜索功能,常见的就是在主页上面有一个搜索栏,点击会跳转到一个搜索页面。 在一般的 App
页面,可能都需要搜索功能,常见的就是在主页上面有一个搜索栏,点击会跳转到一个搜索页面。

使用showSearch,首先需要重写一个SearchDelegate,实现其中的4个方法。

buildActions 显示在最右边的图标列表。
buildLeading 搜索栏左边的图标,一般都是返回。
buildResults 这个回调里进行搜索和并返回自己的搜索结果。
buildSuggestions 返回建议搜索结果。

showSearch(context: context, delegate: CustomSearchDelegate());

class CustomSearchDelegate extends SearchDelegate<String>{
  @override
  List<Widget> buildActions(BuildContext context) {
    return null;
  }

  @override
  Widget buildLeading(BuildContext context) {
    return null;
  }

  @override
  Widget buildResults(BuildContext context) {
    return null;
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    return null;
  }
}

Flutter之常用组件的使用举例(中)_第3张图片

import 'package:flutter/material.dart';
//继承SearchDelegate
class search extends SearchDelegate{
  //数据内容
  final List list=[
   "1","11","111"
  ];
  final rege=[
    "flutter",
    "Android"
  ];

  @override
  List<Widget> buildActions(BuildContext context) {
  return [
    //放置按钮,点击时,将搜索框清空
    IconButton(
      icon:Icon(Icons.clear),
      onPressed: (){
        query="";
      },
    )
  ];
  }

  @override
  Widget buildLeading(BuildContext context) {
  return IconButton( //返回动态按钮
    icon:AnimatedIcon(
      icon:AnimatedIcons.menu_arrow,
      progress: transitionAnimation,
    ),
    onPressed: (){ //回调中调用close方法,关闭搜索页面
      close(context, null);
    },
  );
  }
//搜索页面的结果线束
  @override
  Widget buildResults(BuildContext context) {
    return Container( //点击确认后会关闭搜索页面,并显示如下组件内容
      child:  Text(query),
    );
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    final sugList = query.isEmpty ? rege:list.where((input)=>input.startsWith(query)).toList();
    return ListView.builder(
      itemCount: sugList.length,
      itemBuilder: (context,index)=>ListTile(
        //利用富文本组件,将字符串变成可以设置各个片段样式以及事件的字符串
        title: RichText(
          text: TextSpan(
            //截取数组中已经输入的内容的长度的字符串,并修改其样式
              text: sugList[index].substring(0,query.length),
              style: TextStyle(
                  color: Colors.black,
                  fontWeight: FontWeight.w900
              ),
              children: [
                TextSpan(
                  //截取数组中的每条字符串输入内容长度之后的字符,并修改其样式
                  text: sugList[index].substring(query.length),
                  style: TextStyle(color: Colors.grey),

                )
              ]
          ),
        ),
      ),
    );
  }

}

query是内置函数等同于动态获取当前文本框中的值
Flutter之常用组件的使用举例(中)_第4张图片

六、TextSpan

文本片段,html里有个span这里有个TextSpan,作用基本相同,文字放一行,text与children任选一样填写。
TextSpan与RichText配合使用可以实现不同样式文字布局。

TextSpan({
    this.text,
    this.children,//是一个TextSpan的数组,也就是说TextSpan可以包括其他TextSpan
    TextStyle style,
    this.recognizer,//它是点击链接后的一个处理器,用于对该文本片段上用于手势进行识别处理,设定手势识别器
    this.semanticsLabel,
}) 
RichText(text: TextSpan(
              style: DefaultTextStyle.of(context).style,
              children: [
                TextSpan(
                  text: "我已接受并阅读",
                  style: TextStyle(
                    color: Colors.grey[200]
                  )
                ),
                TextSpan(
                  text: "《用户协议》",
                  style: TextStyle(
                    color: Colors.red
                  )
                ),
                TextSpan(
                  text: "与",
                  style: TextStyle(
                    color: Colors.black
                  )
                ),
                TextSpan(
                  text: "《隐私协议》",
                  style: TextStyle(
                    color: Colors.red
                  )
                )
              ]
            ))

在这里插入图片描述

七、聊天气泡、ConstrainedBox

Flutter中尺寸限制类容器组件包括ConstrainedBox、UnconstrainedBox、SizedBox、AspectRatio、FractionallySizedBox、LimitedBox、Container。这些组件可以约束子组件的尺寸

嵌套使用等于多个BoxConstraints约束中的最小值。同理嵌套约束最小值等于多个BoxConstraints约束中的最大值

ConstrainedBox(
  constraints: BoxConstraints(maxHeight: 60, maxWidth: 200),
  child: ConstrainedBox(
    constraints: BoxConstraints(maxHeight: 100, maxWidth: 240),
    child: Container(height: 300, width: 300, color: Colors.red),
  ),
)

Flutter之常用组件的使用举例(中)_第5张图片

  ConstrainedBox(
              //没有下面的最小高度的话,当只有一行文字的时候.9图片无法显示
              constraints: BoxConstraints(minHeight: 50),
              child: Container(
                  margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
                  padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
                  decoration: BoxDecoration(
                      image: DecorationImage(
                        centerSlice: Rect.fromLTRB(20, 20, 38, 38),
                        image: AssetImage(
                          'images/bg.png',
                        ),
                      )),
                  child: ConstrainedBox(
                    constraints: BoxConstraints(maxWidth: 200),
                    child: Text(
                      "3333333354555444444444444433",
                    ),
                  )),
            )

Flutter之常用组件的使用举例(中)_第6张图片
加载不出网络图片时默认显示

Image.network(
      'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
      height: 150,
      width: 150,
      fit: BoxFit.cover,
      frameBuilder: (
          BuildContext context,
          Widget child,
          int frame,
          bool wasSynchronouslyLoaded,
          ) {
        if (frame == null) {
          return Container(
            height: 150,
            width: 150,
            decoration: BoxDecoration(
              color: Colors.grey
            ),
          );
        }
        return child;
      },
    )

Flutter之常用组件的使用举例(中)_第7张图片SizedBox非常适合控制2个组件之间的空隙
aspectRatio参数是宽高比,可以直接写成分数的形式,也可以写成小数的形式,但建议写成分数的形式,可读性更高。

AspectRatio(
  aspectRatio: 2 / 1,
  child: Container(color: Colors.red),
)

Flutter之常用组件的使用举例(中)_第8张图片

  Icon(IconData(0xe610,fontFamily: 'appIconFonts')
八、权重组建、手势识别组件、 PageView
Spacer 是通过 Expanded 实现的,Expanded继承自Flexible。
填满剩余空间直接使用Expanded更方便。
Spacer 用于撑开 Row、Column、Flex 的子组件的空隙。
FractionallySizedBox
Container(
  height: 200,
  width: 200,
  color: Colors.blue,
  child: FractionallySizedBox(
    widthFactor: .8,
    heightFactor: .3,
    child: Container(
      color: Colors.red,
    ),
  ),
)

GestureDetector 是手势识别的组件,可以识别点击、双击、长按事件、拖动、缩放等手势

onTap(){}
onDoubleTap(){}
//按下然后抬起调用顺序:
onTapDown-> onTapUp-> onTap
//按下后移动的调用顺序:
onTapDown-> onTapCancel

当同时监听onTap和onDoubleTap事件时,只会触发一个事件,如果触发onTap事件,onTap将会延迟触发(延迟时间为系统判断是onDoubleTap事件的间隔),因为系统将会等待一段时间来判断是否为onDoubleTap事件,如果用户只监听了onTap事件则没有延迟
长按事件

长按事件(LongPress)包含长按开始、移动、抬起、结束事件,说明如下:

onLongPressStart:长按开始事件回调。

onLongPressMoveUpdate:长按移动事件回调。

onLongPressUp:长按抬起事件回调。

onLongPressEnd:长按结束事件回调。

onLongPress:长按事件回调

水平/垂直拖动事件

垂直/水平拖动事件包括按下、开始、移动更新、结束、取消事件,以垂直为例说明如下:

onVerticalDragDown:垂直拖动按下事件回调

onVerticalDragStart:垂直拖动开始事件回调

onVerticalDragUpdate:指针移动更新事件回调

onVerticalDragEnd:垂直拖动结束事件回调

onVerticalDragCancel:垂直拖动取消事件回调

缩放事件

缩放(Scale)包含缩放开始、更新、结束。说明如下:

onScaleStart:缩放开始事件回调。

onScaleUpdate:缩放更新事件回调。

onScaleEnd:缩放结束事件回调。

水波纹”超出的了圆角边框。Ink控件控制“水波纹”效果在其上面显示。

PageView

PageView 控件可以实现一个“图片轮播”的效果,PageView 不仅可以水平滑动也可以垂直滑动。

九、Sliver

要同时滚动ListView和GridView可以使用SliverList和SliverGrid。

1.SliverList、SliverGrid
    SliverList(
                delegate: SliverChildBuilderDelegate((context, index) {
              return Container(
                decoration: BoxDecoration(color: Colors.primaries[index]),
                height: 30,
                child: Text("${index}"),
              );
            }, childCount: 10)),
            SliverGrid(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3, crossAxisSpacing: 5, mainAxisSpacing: 3),
              delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
                return Container(
                  color: Colors.primaries[index % Colors.primaries.length],
                );
              }, childCount: 20),
            )
2.SliverAppBar

Flutter之常用组件的使用举例(中)_第9张图片
floating
如果设置 floating 属性为 true,AppBar会在你做出下拉手势时就立即展开(即使ListView并没有到达顶部),该展开状态不显示flexibleSpace:
如果同时设置 floating 和 snap 属性为 true
,那么AppBar会在你做出下拉手势时就立即全部展开(即使ListView并没有到达顶部),该展开状态显示flexibleSpace:
如果同时设置 floating 和 snap 属性为 true
,那么AppBar会在你做出下拉手势时就立即全部展开(即使ListView并没有到达顶部),该展开状态显示flexibleSpace:

          SliverAppBar(
              title: Text("Sliver"),
              backgroundColor: Colors.red,
                leading:  Icon(Icons.arrow_back),
              actions: [
                Icon(Icons.search),
              ],
              expandedHeight: 200,
              pinned: true,
              flexibleSpace: FlexibleSpaceBar(
                background:  Image.network(
                  'https://img-blog.csdnimg.cn/831fd662f2004b89a2d4654e78d1ffbb.png',
                  fit: BoxFit.cover,
                ),
              ),
            ),

Flutter之常用组件的使用举例(中)_第10张图片

3.SliverToBoxAdapter

SliverPersistentHeader一般来说都是会展开/收起的(除非minExtent和maxExtent值相同),那么如果想要在滚动视图中添加一个普通的控件,那么就可以使用 SliverToBoxAdapter 来将各种视图组合在一起,放在CustomListView中。

  SliverToBoxAdapter(
              child: Container(
                height:45,
                margin: EdgeInsets.fromLTRB(20, 10, 20, 10),
                decoration: BoxDecoration(
                  color: Colors.white,
                  boxShadow:[
                    BoxShadow(
                      blurRadius: 4,
                      spreadRadius: 1,
                      color: Colors.grey
                    )
                  ],
                  borderRadius: BorderRadius.circular(30)
                ),
                child:
                TextFormField(
                  decoration: InputDecoration(
                      prefixIcon:Icon(Icons.search,color: Colors.grey,),
                      enabledBorder: InputBorder.none,
                      focusedBorder: InputBorder.none,
                      hintText: "Search category",
                      hintStyle: TextStyle(
                          color: Colors.grey.withOpacity(0.5)
                      )
                  ),
                )

              ),
            )

Flutter之常用组件的使用举例(中)_第11张图片

4.SliverPersistentHeader

SliverPersistentHeader控件当滚动到边缘时根据滚动的距离缩小高度,有点类似 SliverAppBar 的背景效果。
SliverPersistentHeader的delegate需要我们自定义,build返回显示的内容,maxExtent和minExtent表示最大和最小值,滚动的时候高度在这个范围内变化。
shouldRebuild表示是否需要更新,如果内容需要变化需要设置为true。
Flutter之常用组件的使用举例(中)_第12张图片

SliverPersistentHeader(delegate: MySliverPersistentHeaderDelegate()),
import 'package:flutter/material.dart';
class MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return  Container(
        color: Colors.blue,
        alignment: Alignment.center,
        child: Text('我是一个SliverPersistentHeader',
            style: TextStyle(color: Colors.white)));
  }

  @override
  double get maxExtent => 200.0;

  @override
  // TODO: implement minExtent
  double get minExtent => 100.0;

  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) => false;
  //如果内容更新设置为true

}

NestedScrollView
NestedScrollView 可以在其内部嵌套其他滚动视图的滚动视图
滚动隐藏AppBar
Flutter之常用组件的使用举例(中)_第13张图片

NestedScrollView(
       headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
         return <Widget>[SliverAppBar(
           title: Text('Sliver'),
         )];
       },
       body: ListView.builder(itemBuilder: (BuildContext context,int index){
         return Container(
           height: 80,
           color: Colors.primaries[index % Colors.primaries.length],
           alignment: Alignment.center,
           child: Text(
             '$index',
             style: TextStyle(color: Colors.white, fontSize: 20),
           ),
         );
       },itemCount: 20,),
     )

Flutter之常用组件的使用举例(中)_第14张图片

你可能感兴趣的:(Flutter移动开发,flutter,android,android,studio)