一,概述  

数据量很大的时用矩阵方式排列比较清晰,此时用网格列表组件,即为GridView组件,可实现多行多列的应用场景。 使用GridView创建网格列表有多种方式:

  • GridView.count 通过单行展示个数创建GridView。
  • GridView.extend通过最大宽度创建GridView。

二,构造函数  

  • GridView

    • 使用场景:使用自定义SliverGridDelegate创建可滚动的2D小部件数组
    • 构造函数
      GridView({Key key, 
      Axis scrollDirection: Axis.vertical,
      bool reverse: false,
      ScrollController controller, bool primary,
      ScrollPhysics physics, bool shrinkWrap: false,
      EdgeInsetsGeometry padding,
      @required SliverGridDelegate gridDelegate,
      bool addAutomaticKeepAlives: true,
      bool addRepaintBoundaries: true,
      bool addSemanticIndexes: true,
      double cacheExtent, List<Widget> children: const [],
      int semanticChildCount
      })
  • GridView.count

    • 使用场景:创建一个可滚动的2D小部件数组,在横轴上具有固定数量的网格块
    • 构造函数
      GridView.count({Key key, Axis scrollDirection: Axis.vertical,
        bool reverse: false, ScrollController controller,
        bool primary, ScrollPhysics physics, bool shrinkWrap: false,
        EdgeInsetsGeometry padding, @required int crossAxisCount,
       double mainAxisSpacing: 0.0, double crossAxisSpacing: 0.0,
      double childAspectRatio: 1.0, bool addAutomaticKeepAlives: true,
      bool addRepaintBoundaries: true,
      bool addSemanticIndexes: true,
      double cacheExtent, List<Widget> children: const [],
      int semanticChildCount
      })
    • 分析和使用
      Widget gridViewDefaultCount(List<BaseBean> list) {
      return GridView.count(
      // padding: EdgeInsets.all(5.0),
      //一行多少个
      crossAxisCount: ,
      //滚动方向
      scrollDirection: Axis.vertical,
      // 左右间隔
      crossAxisSpacing: 10.0,
      // 上下间隔
      mainAxisSpacing: 10.0,
      //宽高比
      childAspectRatio: / , children: initListWidget(list),
      );
      } List<Widget> initListWidget(List<BaseBean> list) {
      List<Widget> lists = [];
      for (var item in list) {
      lists.add(new Container(
      height: 50.0,
      width: 50.0,
      color: Colors.yellow,
      child: new Center(
      child: new Text(
      item.age.toString(),
      )),
      ));
      }
      return lists;
      }
  • GridView.extent

    • 使用场景:使用每个都具有最大横轴范围的 网格块 创建可滚动的2D小部件数组。
    • 构造函数
      GridView.extent({Key key, Axis scrollDirection: Axis.vertical,
      bool reverse: false, ScrollController controller,
      bool primary, ScrollPhysics physics,
      bool shrinkWrap: false, EdgeInsetsGeometry padding,
      @required double maxCrossAxisExtent,
      double mainAxisSpacing: 0.0, double crossAxisSpacing: 0.0,
      double childAspectRatio: 1.0,
      bool addAutomaticKeepAlives: true,
      bool addRepaintBoundaries: true,
      bool addSemanticIndexes: true,
      List<Widget> children: const [],
      int semanticChildCount
      })
    • 分析和使用  
      ///GridView.extent 允许您指定项的最大像素宽度
      Widget gridViewDefaultExtent(List<BaseBean> list) {
      return GridView.extent(
      ///设置item的最大像素宽度 比如 130
      maxCrossAxisExtent: 130.0,
      ///其他属性和count一样
      children: initListWidget(list),
      );
      }
  • GridView.builder

    • 使用场景:创建按需创建的可滚动的2D小部件数组
    • 构造函数
      GridView.builder({Key key, Axis scrollDirection: Axis.vertical,
        bool reverse: false, ScrollController controller,
      bool primary, ScrollPhysics physics,
      bool shrinkWrap: false, EdgeInsetsGeometry padding,
      @required SliverGridDelegate gridDelegate,
      @required IndexedWidgetBuilder itemBuilder,
      int itemCount, bool addAutomaticKeepAlives: true,
      bool addRepaintBoundaries: true,
      bool addSemanticIndexes: true,
      double cacheExtent, int semanticChildCount
      })
    • 分析和使用
      ///GridView.builder  可以定义gridDelegate的模式
      Widget gridViewDefaultBuilder(List<BaseBean> list) {
      return GridView.builder(
      gridDelegate: MyGridViewDefaultCustom(
      crossAxisCount: ,
      mainAxisSpacing: 10.0,
      crossAxisSpacing: 10.0,
      childAspectRatio: 1.0,
      ),
      itemBuilder: (context, i) => new Container(
      child: new Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
      new Text(
      "${list[i].name}",
      style: new TextStyle(fontSize: 18.0, color: Colors.red),
      ),
      new Text(
      "${list[i].age}",
      style: new TextStyle(fontSize: 18.0, color: Colors.green),
      ),
      new Text(
      "${list[i].content}",
      style: new TextStyle(fontSize: 18.0, color: Colors.blue),
      ),
      ],
      ),
      ));
      }
      ///自定义SliverGridDelegate
      class MyGridViewDefaultCustom extends SliverGridDelegate {
      ///横轴上的子节点数。 一行多少个child
      final int crossAxisCount; ///沿主轴的每个子节点之间的逻辑像素数。 默认垂直方向的子child间距 这里的是主轴方向 当你改变 scrollDirection: Axis.vertical,就是改变了主轴发方向
      final double mainAxisSpacing; ///沿横轴的每个子节点之间的逻辑像素数。默认水平方向的子child间距
      final double crossAxisSpacing; ///每个孩子的横轴与主轴范围的比率。 child的宽高比 常用来处理child的适配
      final double childAspectRatio; bool _debugAssertIsValid() {
      assert(mainAxisSpacing >= 0.0);
      assert(crossAxisSpacing >= 0.0);
      assert(childAspectRatio > 0.0);
      return true;
      } const MyGridViewDefaultCustom({
      @required this.crossAxisCount,
      this.mainAxisSpacing = 0.0,
      this.crossAxisSpacing = 0.0,
      this.childAspectRatio = 1.0,
      }) : assert(crossAxisCount != null && crossAxisCount > ),
      assert(mainAxisSpacing != null && mainAxisSpacing >= ),
      assert(crossAxisSpacing != null && crossAxisSpacing >= ),
      assert(childAspectRatio != null && childAspectRatio > ); /// 返回值有关网格中图块大小和位置的信息。这里就是处理怎么摆放 我们可以自己定义
      /// SliverGridLayout是抽象类 SliverGridRegularTileLayout继承于SliverGridLayout是抽象类
      @override
      SliverGridLayout getLayout(SliverConstraints constraints) {
      // TODO: implement getLayout
      assert(_debugAssertIsValid()); ///对参数的修饰 自定义
      final double usableCrossAxisExtent =
      constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - );
      final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
      final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio;
      return MySliverGridLayout(
      crossAxisCount: crossAxisCount,
      mainAxisStride: childMainAxisExtent + mainAxisSpacing,
      crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
      childMainAxisExtent: childMainAxisExtent,
      childCrossAxisExtent: childCrossAxisExtent,
      reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
      );
      } /// 和ListView的 shouldRebuild 作用一样 之前的实例和新进来的实例是相同的就返回true
      @override
      bool shouldRelayout(SliverGridDelegate oldDelegate) {
      // TODO: implement shouldRelayout
      return true;
      }
      }
  • GridView.custom 

    • 使用场景:使用自定义SliverGridDelegate和自定义SliverChildDelegate创建可滚动的2D小部件数组
    • 构造函数
      GridView.custom({Key key, Axis scrollDirection: Axis.vertical,
      bool reverse: false, ScrollController controller,
      bool primary, ScrollPhysics physics,
      bool shrinkWrap: false,
      EdgeInsetsGeometry padding,
      @required SliverGridDelegate gridDelegate,
      @required SliverChildDelegate childrenDelegate,
      double cacheExtent,
      int semanticChildCount })
    • 分析和使用  
       ///GridView.custom 就是自己定制规则
      /// 这里说一下 GridView.count gridDelegate 其实就是内部实现 SliverGridDelegateWithFixedCrossAxisCount
      /// GridView.extent gridDelegate 其实就是内部实现 SliverGridDelegateWithMaxCrossAxisExtent
      Widget gridViewDefaultCustom(List<BaseBean> list) {
      return GridView.custom(
      gridDelegate: MyGridViewDefaultCustom(
      crossAxisCount: ,
      mainAxisSpacing: 10.0,
      crossAxisSpacing: 10.0,
      childAspectRatio: 1.0,
      ),
      childrenDelegate: MyGridChildrenDelegate(
      (BuildContext context, int i) {
      return new Container(
      child: new Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
      new Text(
      "${list[i].name}",
      style: new TextStyle(fontSize: 18.0, color: Colors.red),
      ),
      new Text(
      "${list[i].age}",
      style: new TextStyle(fontSize: 18.0, color: Colors.green),
      ),
      new Text(
      "${list[i].content}",
      style: new TextStyle(fontSize: 18.0, color: Colors.blue),
      ),
      ],
      ));
      },
      childCount: list.length,
      ),
      );
      }
      /**
      * 继承SliverChildBuilderDelegate 可以对列表的监听
      */
      class MyGridChildrenDelegate extends SliverChildBuilderDelegate {
      MyGridChildrenDelegate(
      Widget Function(BuildContext, int) builder, {
      int childCount,
      bool addAutomaticKeepAlive = true,
      bool addRepaintBoundaries = true,
      }) : super(builder,
      childCount: childCount,
      addAutomaticKeepAlives: addAutomaticKeepAlive,
      addRepaintBoundaries: addRepaintBoundaries); ///监听 在可见的列表中 显示的第一个位置和最后一个位置
      @override
      void didFinishLayout(int firstIndex, int lastIndex) {
      print('firstIndex: $firstIndex, lastIndex: $lastIndex');
      } ///可不重写 重写不能为null 默认是true 添加进来的实例与之前的实例是否相同 相同返回true 反之false
      ///listView 暂时没有看到应用场景 源码中使用在 SliverFillViewport 中
      @override
      bool shouldRebuild(SliverChildBuilderDelegate oldDelegate) {
      // TODO: implement shouldRebuild
      print("oldDelegate$oldDelegate");
      return super.shouldRebuild(oldDelegate);
      }
      }

三,参数详解

  • gridDelegate:

   构造 GridView 的委托者,GridView.count 就相当于指定 gridDelegate 为 SliverGridDelegateWithFixedCrossAxisCount,GridView.extent 就相当于指定 gridDelegate 为 SliverGridDelegateWithMaxCrossAxisExtent,它们相当于对普通构造方法的一种封装。它的值是一个 SliverGridDelegate 对象,参考 2.1 SliverGridDelegate。

  • cacheExtent:同 ListView,预加载的区域。
  • controller:同 ListView,滑动监听,值为一个 ScrollController 对象,这个属性应该可以用来做下拉刷新和上垃加载,后面详细研究。
  • padding:同 ListView,整个 GridView 的内间距。
  • physics:同 ListView,设置 GridView 如何响应用户的滑动行为,值为一个 ScrollPhysics 对象,它的实现类常用的有:
    • AlwaysScrollableScrollPhysics:总是可以滑动。
    • NeverScrollableScrollPhysics:禁止滚动。
    • BouncingScrollPhysics:内容超过一屏,上拉有回弹效果。
    • ClampingScrollPhysics:包裹内容,不会有回弹,感觉跟 AlwaysScrollableScrollPhysics 差不多。
  • reverse:Item 的顺序是否反转,若为 true 则反转,这个翻转只是行翻转,即第一行变成最后一行,但是每一行中的子组件还是从左往右摆放的,用到该属性的开发情景较少。
  • scrollDirection:GirdView 的方向,为 Axis.vertical 表示纵向,为 Axis.horizontal 表示横向,横向的话 CrossAxis 和 MainAxis 表示的轴也会调换,为 Axis.Horizontal 的情况也较少。
  • semanticChildCount:不太清楚。
  • shrinkWrap:不太清楚。
  • children:子组件,不用多说。

四,关于SliverGridDelegate

构造 GridView 的委托者,它有两个实现类:

  • SliverGridDelegateWithFixedCrossAxisCount

      该委托者通常用于每一行的子组件个数固定的情况,它可以指定如下几个属性:

    • crossAxisCount:必传参数,Cross 轴(在 GridView 中通常是横轴,即每一行)子组件个数。

    • childAspectRatio:子组件宽高比,如 2 表示宽:高=2:1,如 0.5 表示宽:高=0.5:1=1:2,简单来说就是值大于 1 就会宽大于高,小于 1 就会宽小于高。

    • crossAxisSpacing:Cross 轴子组件的间隔,一行中第一个子组件左边不会添加间隔,最后一个子组件右边不会添加间隔,这一点很棒。

    • mainAxisSpacing:Main 轴(在 GridView 中通常是纵轴,即每一列)子组件间隔,也就是每一行之间的间隔,同样第一行的上边和最后一行的下边不会添加间隔。

  • SliverGridDelegateWithMaxCrossAxisExtent

    • maxCrossAxisExtent:必传参数,
    • Cross 轴(在 GridView 中通常是横轴,即每一行)子组件最大宽度,会根据该值来决定一行摆放几个子组件。

    其余属性 childAspectRatio、crossAxisSpacing、mainAxisSpacing 同 SliverGridDelegateWithFixedCrossAxisCount。

五,示例demo  

import 'package:flutter/material.dart';
import 'package:flutter/src/rendering/sliver.dart';
import 'package:flutter/src/rendering/sliver_grid.dart';
import 'package:flutter_vscode/listview_demo.dart'; class GridViewDemo extends StatefulWidget {
@override
_GridViewDemoState createState() => new _GridViewDemoState();
} class _GridViewDemoState extends State<GridViewDemo> {
List<BaseBean> gridList; @override
void initState() {
// TODO: implement initState
super.initState();
gridList = new List<BaseBean>.generate(
, (i) => new BaseBean("name$i", i, "content=$i"));
} @override
Widget build(BuildContext context) {
return new MaterialApp(
title: "",
home: new Scaffold(
appBar: new AppBar(
centerTitle: true,
title: new Text("GridView"),
),
body: gridViewDefaultCount(gridList),
),
);
} List<Widget> initListWidget(List<BaseBean> list) {
List<Widget> lists = [];
for (var item in list) {
lists.add(new Container(
height: 50.0,
width: 50.0,
color: Colors.yellow,
child: new Center(
child: new Text(
item.age.toString(),
)),
));
}
return lists;
} Widget gridViewDefaultCount(List<BaseBean> list) {
return GridView.count(
// padding: EdgeInsets.all(5.0),
crossAxisCount: ,
//一行多少个
scrollDirection: Axis.vertical,
//滚动方向
crossAxisSpacing: 10.0,
// 左右间隔
mainAxisSpacing: 10.0,
// 上下间隔
childAspectRatio: / ,
//宽高比
children: initListWidget(list),
);
} ///GridView.extent 允许您指定项的最大像素宽度
Widget gridViewDefaultExtent(List<BaseBean> list) {
return GridView.extent(
///设置item的最大像素宽度 比如 130
maxCrossAxisExtent: 130.0, ///其他属性和count一样
children: initListWidget(list),
);
} ///GridView.custom 就是自己定制规则
/// 这里说一下 GridView.count gridDelegate 其实就是内部实现 SliverGridDelegateWithFixedCrossAxisCount
/// GridView.extent gridDelegate 其实就是内部实现 SliverGridDelegateWithMaxCrossAxisExtent
Widget gridViewDefaultCustom(List<BaseBean> list) {
return GridView.custom(
gridDelegate: MyGridViewDefaultCustom(
crossAxisCount: ,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 1.0,
),
childrenDelegate: MyGridChildrenDelegate(
(BuildContext context, int i) {
return new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Text(
"${list[i].name}",
style: new TextStyle(fontSize: 18.0, color: Colors.red),
),
new Text(
"${list[i].age}",
style: new TextStyle(fontSize: 18.0, color: Colors.green),
),
new Text(
"${list[i].content}",
style: new TextStyle(fontSize: 18.0, color: Colors.blue),
),
],
));
},
childCount: list.length,
),
);
} ///GridView.builder 可以定义gridDelegate的模式
Widget gridViewDefaultBuilder(List<BaseBean> list) {
return GridView.builder(
gridDelegate: MyGridViewDefaultCustom(
crossAxisCount: ,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 1.0,
),
itemBuilder: (context, i) => new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Text(
"${list[i].name}",
style: new TextStyle(fontSize: 18.0, color: Colors.red),
),
new Text(
"${list[i].age}",
style: new TextStyle(fontSize: 18.0, color: Colors.green),
),
new Text(
"${list[i].content}",
style: new TextStyle(fontSize: 18.0, color: Colors.blue),
),
],
),
));
}
} ///自定义SliverGridDelegate
class MyGridViewDefaultCustom extends SliverGridDelegate {
///横轴上的子节点数。 一行多少个child
final int crossAxisCount; ///沿主轴的每个子节点之间的逻辑像素数。 默认垂直方向的子child间距 这里的是主轴方向 当你改变 scrollDirection: Axis.vertical,就是改变了主轴发方向
final double mainAxisSpacing; ///沿横轴的每个子节点之间的逻辑像素数。默认水平方向的子child间距
final double crossAxisSpacing; ///每个孩子的横轴与主轴范围的比率。 child的宽高比 常用来处理child的适配
final double childAspectRatio; bool _debugAssertIsValid() {
assert(mainAxisSpacing >= 0.0);
assert(crossAxisSpacing >= 0.0);
assert(childAspectRatio > 0.0);
return true;
} const MyGridViewDefaultCustom({
@required this.crossAxisCount,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
this.childAspectRatio = 1.0,
}) : assert(crossAxisCount != null && crossAxisCount > ),
assert(mainAxisSpacing != null && mainAxisSpacing >= ),
assert(crossAxisSpacing != null && crossAxisSpacing >= ),
assert(childAspectRatio != null && childAspectRatio > ); /// 返回值有关网格中图块大小和位置的信息。这里就是处理怎么摆放 我们可以自己定义
/// SliverGridLayout是抽象类 SliverGridRegularTileLayout继承于SliverGridLayout是抽象类
@override
SliverGridLayout getLayout(SliverConstraints constraints) {
// TODO: implement getLayout
assert(_debugAssertIsValid()); ///对参数的修饰 自定义
final double usableCrossAxisExtent =
constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - );
final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio;
return MySliverGridLayout(
crossAxisCount: crossAxisCount,
mainAxisStride: childMainAxisExtent + mainAxisSpacing,
crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
childMainAxisExtent: childMainAxisExtent,
childCrossAxisExtent: childCrossAxisExtent,
reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
);
} /// 和ListView的 shouldRebuild 作用一样 之前的实例和新进来的实例是相同的就返回true
@override
bool shouldRelayout(SliverGridDelegate oldDelegate) {
// TODO: implement shouldRelayout
return true;
}
} ///自定义SliverGridLayout
class MySliverGridLayout extends SliverGridLayout {
final int crossAxisCount; final double mainAxisStride; final double crossAxisStride; final double childMainAxisExtent; final double childCrossAxisExtent; final bool reverseCrossAxis; const MySliverGridLayout({
@required this.crossAxisCount,
@required this.mainAxisStride,
@required this.crossAxisStride,
@required this.childMainAxisExtent,
@required this.childCrossAxisExtent,
@required this.reverseCrossAxis,
}) : assert(crossAxisCount != null && crossAxisCount > ),
assert(mainAxisStride != null && mainAxisStride >= ),
assert(crossAxisStride != null && crossAxisStride >= ),
assert(childMainAxisExtent != null && childMainAxisExtent >= ),
assert(childCrossAxisExtent != null && childCrossAxisExtent >= ),
assert(reverseCrossAxis != null); ///如果有,则完全显示所有图块所需的滚动范围
///“childCount”儿童总数。
///
///子计数永远不会为空。
@override
double computeMaxScrollOffset(int childCount) {
// TODO: implement computeMaxScrollOffset
return null;
} ///具有给定索引的子项的大小和位置。
@override
SliverGridGeometry getGeometryForChildIndex(int index) {
// TODO: implement getGeometryForChildIndex
return null;
} ///在此滚动偏移处(或之前)可见的最大子索引。
@override
int getMaxChildIndexForScrollOffset(double scrollOffset) {
// TODO: implement getMaxChildIndexForScrollOffset
return null;
} ///在此滚动偏移处(或之后)可见的最小子索引。
@override
int getMinChildIndexForScrollOffset(double scrollOffset) {
// TODO: implement getMinChildIndexForScrollOffset
return null;
}
} // ignore: slash_for_doc_comments
/**
* 继承SliverChildBuilderDelegate 可以对列表的监听
*/
class MyGridChildrenDelegate extends SliverChildBuilderDelegate {
MyGridChildrenDelegate(
Widget Function(BuildContext, int) builder, {
int childCount,
bool addAutomaticKeepAlive = true,
bool addRepaintBoundaries = true,
}) : super(builder,
childCount: childCount,
addAutomaticKeepAlives: addAutomaticKeepAlive,
addRepaintBoundaries: addRepaintBoundaries); ///监听 在可见的列表中 显示的第一个位置和最后一个位置
@override
void didFinishLayout(int firstIndex, int lastIndex) {
print('firstIndex: $firstIndex, lastIndex: $lastIndex');
} ///可不重写 重写不能为null 默认是true 添加进来的实例与之前的实例是否相同 相同返回true 反之false
///listView 暂时没有看到应用场景 源码中使用在 SliverFillViewport 中
@override
bool shouldRebuild(SliverChildBuilderDelegate oldDelegate) {
// TODO: implement shouldRebuild
print("oldDelegate$oldDelegate");
return super.shouldRebuild(oldDelegate);
}
}

五,官方文档

  官方文档

【Flutter学习】基本组件之基本网格Gradview组件的更多相关文章

  1. Flutter学习笔记(15)--MaterialApp应用组件及routes路由详解

    如需转载,请注明出处:Flutter学习笔记(15)--MaterialApp应用组件及routes路由详解 最近一段时间生病了,整天往医院跑,也没状态学东西了,现在是好了不少了,也该继续学习啦!!! ...

  2. Flutter学习笔记(18)--Drawer抽屉组件

    如需转载,请注明出处:Flutter学习笔记(18)--Drawer抽屉组件 Drawer(抽屉组件)可以实现类似抽屉拉出和推入的效果,可以从侧边栏拉出导航面板.通常Drawer是和ListView组 ...

  3. Flutter学习笔记(24)--SingleChildScrollView滚动组件

    如需转载,请注明出处:Flutter学习笔记(23)--多 在我们实际的项目开发中,经常会遇到页面UI内容过多,导致手机一屏展示不完的情况出现,以Android为例,在Android中遇到这类情况的做 ...

  4. 【Flutter学习】页面布局之基础布局组件

    一,概述 Flutter中拥有30多种预定义的布局widget,常用的有Container.Padding.Center.Flex.Row.Colum.ListView.GridView.按照< ...

  5. Flutter学习笔记(13)--表单组件

    如需转载,请注明出处:Flutter学习笔记(13)--表单组件 表单组件是个包含表单元素的区域,表单元素允许用户输入内容,比如:文本区域,下拉表单,单选框.复选框等,常见的应用场景有:登陆.注册.输 ...

  6. Flutter学习笔记(12)--列表组件

    如需转载,请注明出处:Flutter学习笔记(12)--列表组件 在日常的产品项目需求中,经常会有列表展示类的需求,在Android中常用的做法是收集数据源,然后创建列表适配器Adapter,将数据源 ...

  7. Flutter学习笔记(14)--StatefulWidget简单使用

    如需转载,请注明出处:Flutter学习笔记(14)--StatefulWidget简单使用 今天上班没那么忙,突然想起来我好像没StatefulWidget(有状态组件)的demo,闲来无事,写一个 ...

  8. Flutter学习笔记(21)--TextField文本框组件和Card卡片组件

    如需转载,请注明出处:Flutter学习笔记(21)--TextField文本框组件和Card卡片组件 今天来学习下TextField文本框组件和Card卡片组件. 只要是应用程序就少不了交互,基本上 ...

  9. Flutter学习笔记(9)--组件Widget

    如需转载,请注明出处:Flutter学习笔记(9)--组件Widget 在Flutter中,所有的显示都是Widget,Widget是一切的基础,我们可以通过修改数据,再用setState设置数据(调 ...

随机推荐

  1. HTTP详解教程 / HTTP 响应头信息 HTTP 响应头信息

    HTTP请求头提供了关于请求,响应或者其他的发送实体的信息. 在本章节中我们将具体来介绍HTTP响应头信息.直线电机哪家好 应答头 说明 Allow 服务器支持哪些请求方法(如GET.POST等). ...

  2. Service系统服务(二):补充应用技巧、软连接与硬连接、man手册、zip备份、vim效率操作、自定义yum软件仓库、发布及测试yum仓库、编译安装软件包

    一.补充应用技巧 目标: 本例要求掌握在运维中比较常用的一些扩展命令技巧的使用,完成下列小技巧操作: 1> 采用数值形式将目录/root的权限调整为 rwx------   2> 将记录的 ...

  3. 处理post上传的文件;并返回路径

    /** * 处理post上传的文件:并返回路径 * @param string $path 字符串 保存文件路径示例: /Upload/image/ * @param string $format 文 ...

  4. 基于Tomcat如何显示服务器上的图片或文件?

    修改tomcat中conf文件夹下的server.xml文件,在 <Valve className="org.apache.catalina.valves.AccessLogValve ...

  5. EFK搜集MySQL慢日志

    前提已经安装好EFK 1.在MySQL节点安装td-agent http://packages.treasuredata.com.s3.amazonaws.com/3/redhat/7/x86_64/ ...

  6. 多条件异步搜索+分页(PHP、 AJAX、ThinkPHP)

    项目中遇到的多条件异步查询及数据分页问题,做了数次尝试,最终虽目的达到,略有繁琐,希望能有更好的处理方式 基于 tp框架 1.html页面代码 <div class="h_cityNa ...

  7. win10 打开 sql sever配置管理器

    !找到解决办法啦!WIN10系统 此电脑->右击->管理弹出以上界面啊哈哈哈还有一些解决办法在这个贴吧里...http://tieba.baidu.com/p/3000709047

  8. Java finally块

    try块也可以有零个或一个finally块. finally块总是与try块一起使用. 语法 finally块的语法是: 1 2 3 finally  {     // Code for finall ...

  9. Spring Data JPA one to one 共享主键关联

    /** * Created by xiezhiyan on 17-9-13. */@Entitypublic class Token { @Id @Column(name = "store_ ...

  10. 7G