flutter listview 滚动到底部_(五) Flutter入门学习 之 Widget滚动

2023-11-18

列表是移动端经常使用的一种视图展示方式,在Flutter中提供了ListView和GridView。

为了可能展示出更好的效果,我这里提供了一段Json数据,所以我们可以先学习一下Json解析。

一. JSON读取和解析

在开发中,我们经常会使用本地JSON或者从服务器请求数据后回去到JSON,拿到JSON后通常会将JSON转成Model对象来进行后续的操作,因为这样操作更加的方便,也更加的安全。

所以学习JSON的相关操作以及读取JSON后如何转成Model对象对于Flutter开发也非常重要。

1.1. JSON资源配置

JSON也属于一种资源,所以在使用之前需要先进行相关的配置

我们之前在学习使用Image组件时,用到了本地图片,本地图片必须在pubspec.yaml中进行配置:

1.2. JSON读取解析

JSON资源读取

如果我们希望读取JSON资源,可以使用package:flutter/services.dart包中的rootBundle。

在rootBundle中有一个loadString方法,可以去加载JSON资源

  • 但是注意,查看该方法的源码,你会发现这个操作是一个异步的。
  • 关于Future和async,这里就不再展开讲解,可以去查看之前的dart语法。
Future loadString(String key, { bool cache = true }) async {  ...省略具体代码,可以自行查看源码}

代码如下:(不要试图拷贝这个代码去运行,是没办法运行的)

import 'package:flutter/services.dart' show rootBundle;// 打印读取的结果是一个字符串rootBundle.loadString("assets/yz.json").then((value) => print(value));

JSON字符串转化

拿到JSON字符串后,我们需要将其转成成我们熟悉的List和Map类型。

我们可以通过dart:convert包中的json.decode方法将其进行转化

代码如下:

// 1.读取json文件String jsonString = await rootBundle.loadString("assets/yz.json");// 2.转成List或Map类型final jsonResult = json.decode(jsonString);

对象Model定义

将JSON转成了List和Map类型后,就可以将List中的一个个Map转成Model对象,所以我们需要定义自己的Model

class Anchor {  String nickname;  String roomName;  String imageUrl;  Anchor({    this.nickname,    this.roomName,    this.imageUrl  });  Anchor.withMap(Map parsedMap) {    this.nickname = parsedMap["nickname"];    this.roomName = parsedMap["roomName"];    this.imageUrl = parsedMap["roomSrc"];  }}

1.3. JSON解析代码

上面我们给出了解析的一个个步骤,下面我们给出完整的代码逻辑

这里我单独创建了一个anchor.dart的文件,在其中定义了所有的相关代码:

  • 之后外界只需要调用我内部的getAnchors就可以获取到解析后的数据了
import 'package:flutter/services.dart' show rootBundle;import 'dart:convert';import 'dart:async';class Anchor {  String nickname;  String roomName;  String imageUrl;  Anchor({    this.nickname,    this.roomName,    this.imageUrl  });  Anchor.withMap(Map parsedMap) {    this.nickname = parsedMap["nickname"];    this.roomName = parsedMap["roomName"];    this.imageUrl = parsedMap["roomSrc"];  }}Future getAnchors() async {  // 1.读取json文件  String jsonString = await rootBundle.loadString("assets/yz.json");  // 2.转成List或Map类型  final jsonResult = json.decode(jsonString);  // 3.遍历List,并且转成Anchor对象放到另一个List中  List anchors = new List();  for (Map map in jsonResult) {    anchors.add(Anchor.withMap(map));  }  return anchors;}

二. ListView组件

移动端数据量比较大时,我们都是通过列表来进行展示的,比如商品数据、聊天列表、通信录、朋友圈等。

在Android中,我们可以使用ListView或RecyclerView来实现,在iOS中,我们可以通过UITableView来实现。

在Flutter中,我们也有对应的列表Widget,就是ListView。

2.1. ListView基础

2.1.1 ListView基本使用

ListView可以沿一个方向(垂直或水平方向,默认是垂直方向)来排列其所有子Widget。

一种最简单的使用方式是直接将所有需要排列的子Widget放在ListView的children属性中即可。

我们来看一下直接使用ListView的代码演练:

  • 为了让文字之间有一些间距,我使用了Padding Widget
class MyHomeBody extends StatelessWidget {  final TextStyle textStyle = TextStyle(fontSize: 20, color: Colors.redAccent);  @override  Widget build(BuildContext context) {    return ListView(      children: [        Padding(          padding: const EdgeInsets.all(8.0),          child: Text("人的一切痛苦,本质上都是对自己无能的愤怒。", style: textStyle),        ),        Padding(          padding: const EdgeInsets.all(8.0),          child: Text("人活在世界上,不可以有偏差;而且多少要费点劲儿,才能把自己保持到理性的轨道上。", style: textStyle),        ),        Padding(          padding: const EdgeInsets.all(8.0),          child: Text("我活在世上,无非想要明白些道理,遇见些有趣的事。", style: textStyle),        )      ],    );  }}

2.2.2. ListTile的使用

在开发中,我们经常见到一种列表,有一个图标或图片(Icon),有一个标题(Title),有一个子标题(Subtitle),还有尾部一个图标(Icon)。

这个时候,我们可以使用ListTile来实现:

class MyHomeBody extends StatelessWidget {  @override  Widget build(BuildContext context) {    return ListView(      children: [        ListTile(          leading: Icon(Icons.people, size: 36,),          title: Text("联系人"),          subtitle: Text("联系人信息"),          trailing: Icon(Icons.arrow_forward_ios),        ),        ListTile(          leading: Icon(Icons.email, size: 36,),          title: Text("邮箱"),          subtitle: Text("邮箱地址信息"),          trailing: Icon(Icons.arrow_forward_ios),        ),        ListTile(          leading: Icon(Icons.message, size: 36,),          title: Text("消息"),          subtitle: Text("消息详情信息"),          trailing: Icon(Icons.arrow_forward_ios),        ),        ListTile(          leading: Icon(Icons.map, size: 36,),          title: Text("地址"),          subtitle: Text("地址详情信息"),          trailing: Icon(Icons.arrow_forward_ios),        )      ],    );  }}

2.2.3. 垂直方向滚动

我们可以通过设置 scrollDirection 参数来控制视图的滚动方向。

我们通过下面的代码实现一个水平滚动的内容:

  • 这里需要注意,我们需要给Container设置width,否则它是没有宽度的,就不能正常显示。
  • 或者我们也可以给ListView设置一个itemExtent,该属性会设置滚动方向上每个item所占据的宽度。
class MyHomeBody extends StatelessWidget {  @override  Widget build(BuildContext context) {    return ListView(      scrollDirection: Axis.horizontal,      itemExtent: 200,      children: [        Container(color: Colors.red, width: 200),        Container(color: Colors.green, width: 200),        Container(color: Colors.blue, width: 200),        Container(color: Colors.purple, width: 200),        Container(color: Colors.orange, width: 200),      ],    );  }}

2.2. ListView.build

通过构造函数中的children传入所有的子Widget有一个问题:默认会创建出所有的子Widget。

但是对于用户来说,一次性构建出所有的Widget并不会有什么差异,但是对于我们的程序来说会产生性能问题,而且会增加首屏的渲染时间。

我们可以ListView.build来构建子Widget,提供性能。

2.2.1. ListView.build基本使用

ListView.build适用于子Widget比较多的场景,该构造函数将创建子Widget交给了一个抽象的方法,交给ListView进行管理,ListView会在真正需要的时候去创建子Widget,而不是一开始就全部初始化好。

该方法有两个重要参数:

  • itemBuilder:列表项创建的方法。当列表滚动到对应位置的时候,ListView会自动调用该方法来创建对应的子Widget。类型是IndexedWidgetBuilder,是一个函数类型。
  • itemCount:表示列表项的数量,如果为空,则表示ListView为无限列表。

我们还是通过一个简单的案例来认识它:

class MyHomeBody extends StatelessWidget {  @override  Widget build(BuildContext context) {    return ListView.builder(      itemCount: 100,      itemExtent: 80,      itemBuilder: (BuildContext context, int index) {        return ListTile(title: Text("标题$index"), subtitle: Text("详情内容$index"));      }    );  }}

2.2.2. ListView.build动态数据

在之前,我们搞了一个yz.json数据,我们现在动态的来通过JSON数据展示一个列表。

思考:这个时候是否依然可以使用StatelessWidget:

答案:不可以,因为当前我们的数据是异步加载的,刚开始界面并不会展示数据(没有数据),后面从JSON中加载出来数据(有数据)后,再次展示加载的数据。

  • 这里是有状态的变化的,从无数据,到有数据的变化。
  • 这个时候,我们需要使用StatefulWidget来管理组件。

展示代码如下:

import 'model/anchor.dart';...省略中间代码class MyHomeBody extends StatefulWidget {  @override  State createState() {    return MyHomeBodyState();  }}class MyHomeBodyState extends State {  List anchors = [];  // 在初始化状态的方法中加载数据  @override  void initState() {    getAnchors().then((anchors) {      setState(() {        this.anchors = anchors;      });    });    super.initState();  }  @override  Widget build(BuildContext context) {    return ListView.builder(      itemBuilder: (BuildContext context, int index) {        return Padding(          padding: EdgeInsets.all(8),          child: Column(            crossAxisAlignment: CrossAxisAlignment.start,            children: [              Image.network(                anchors[index].imageUrl,                fit: BoxFit.fitWidth,                width: MediaQuery.of(context).size.width,              ),              SizedBox(height: 8),              Text(anchors[index].nickname, style: TextStyle(fontSize: 20),),              SizedBox(height: 5),              Text(anchors[index].roomName)            ],          ),        );      },    );  }}

2.2.3. ListView.separated

ListView.separated可以生成列表项之间的分割器,它除了比ListView.builder多了一个separatorBuilder参数,该参数是一个分割器生成器。

下面我们看一个例子:奇数行添加一条蓝色下划线,偶数行添加一条红色下划线:

class MySeparatedDemo extends StatelessWidget {  Divider blueColor = Divider(color: Colors.blue);  Divider redColor = Divider(color: Colors.red);  @override  Widget build(BuildContext context) {    return ListView.separated(      itemBuilder: (BuildContext context, int index) {        return ListTile(          leading: Icon(Icons.people),          title: Text("联系人${index+1}"),          subtitle: Text("联系人电话${index+1}"),        );      },      separatorBuilder: (BuildContext context, int index) {        return index % 2 == 0 ? redColor : blueColor;      },      itemCount: 100    );  }}

三. GridView组件

GridView用于展示多列的展示,在开发中也非常常见,比如直播App中的主播列表、电商中的商品列表等等。

在Flutter中我们可以使用GridView来实现,使用方式和ListView也比较相似。

3.1. GridView构造函数

我们先学习GridView构造函数的使用方法

一种使用GridView的方式就是使用构造函数来创建,和ListView对比有一个特殊的参数:gridDelegate

gridDelegate用于控制交叉轴的item数量或者宽度,需要传入的类型是SliverGridDelegate,但是它是一个抽象类,所以我们需要传入它的子类:

SliverGridDelegateWithFixedCrossAxisCount

SliverGridDelegateWithFixedCrossAxisCount({  @required double crossAxisCount, // 交叉轴的item个数  double mainAxisSpacing = 0.0, // 主轴的间距  double crossAxisSpacing = 0.0, // 交叉轴的间距  double childAspectRatio = 1.0, // 子Widget的宽高比})

代码演练:

class MyGridCountDemo extends StatelessWidget {  List getGridWidgets() {    return List.generate(100, (index) {      return Container(        color: Colors.purple,        alignment: Alignment(0, 0),        child: Text("item$index", style: TextStyle(fontSize: 20, color: Colors.white)),      );    });  }  @override  Widget build(BuildContext context) {    return GridView(      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(        crossAxisCount: 3,        mainAxisSpacing: 10,        crossAxisSpacing: 10,        childAspectRatio: 1.0      ),      children: getGridWidgets(),    );  }}

SliverGridDelegateWithMaxCrossAxisExtent

SliverGridDelegateWithMaxCrossAxisExtent({  double maxCrossAxisExtent, // 交叉轴的item宽度  double mainAxisSpacing = 0.0, // 主轴的间距  double crossAxisSpacing = 0.0, // 交叉轴的间距  double childAspectRatio = 1.0, // 子Widget的宽高比})

代码演练:

class MyGridExtentDemo extends StatelessWidget {  List getGridWidgets() {    return List.generate(100, (index) {      return Container(        color: Colors.purple,        alignment: Alignment(0, 0),        child: Text("item$index", style: TextStyle(fontSize: 20, color: Colors.white)),      );    });  }  @override  Widget build(BuildContext context) {    return GridView(      gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(        maxCrossAxisExtent: 150,        mainAxisSpacing: 10,        crossAxisSpacing: 10,        childAspectRatio: 1.0      ),      children: getGridWidgets(),    );  }}

前面两种方式也可以不设置delegate

可以分别使用:GridView.count构造函数和GridView.extent构造函数实现相同的效果,这里不再赘述。

3.2. GridView.build

和ListView一样,使用构造函数会一次性创建所有的子Widget,会带来性能问题,所以我们可以使用GridView.build来交给GridView自己管理需要创建的子Widget。

我们直接使用之前的数据来进行代码演练:

class _GridViewBuildDemoState extends State {  List anchors = [];  @override  void initState() {    getAnchors().then((anchors) {      setState(() {        this.anchors = anchors;      });    });    super.initState();  }  @override  Widget build(BuildContext context) {    return Padding(      padding: const EdgeInsets.all(8.0),      child: GridView.builder(        shrinkWrap: true,        physics: ClampingScrollPhysics(),        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(          crossAxisCount: 2,          mainAxisSpacing: 10,          crossAxisSpacing: 10,          childAspectRatio: 1.2        ),        itemCount: anchors.length,        itemBuilder: (BuildContext context, int index) {          return Container(            child: Column(              crossAxisAlignment: CrossAxisAlignment.start,              children: [                Image.network(anchors[index].imageUrl),                SizedBox(height: 5),                Text(anchors[index].nickname, style: TextStyle(fontSize: 16),),                Text(anchors[index].roomName, maxLines: 1, overflow: TextOverflow.ellipsis,)              ],            ),          );        }      ),    );  }}

四. Slivers

我们考虑一个这样的布局:一个滑动的视图中包括一个标题视图(HeaderView),一个列表视图(ListView),一个网格视图(GridView)。

我们怎么可以让它们做到统一的滑动效果呢?使用前面的滚动是很难做到的。

Flutter中有一个可以完成这样滚动效果的Widget:CustomScrollView,可以统一管理多个滚动视图。

在CustomScrollView中,每一个独立的,可滚动的Widget被称之为Sliver。

补充:Sliver可以翻译成裂片、薄片,你可以将每一个独立的滚动视图当做一个小裂片。

4.1. Slivers的基本使用

因为我们需要把很多的Sliver放在一个CustomScrollView中,所以CustomScrollView有一个slivers属性,里面让我们放对应的一些Sliver:

  • SliverList:类似于我们之前使用过的ListView;
  • SliverFixedExtentList:类似于SliverList只是可以设置滚动的高度;
  • SliverGrid:类似于我们之前使用过的GridView;
  • SliverPadding:设置Sliver的内边距,因为可能要单独给Sliver设置内边距;
  • SliverAppBar:添加一个AppBar,通常用来作为CustomScrollView的HeaderView;
  • SliverSafeArea:设置内容显示在安全区域(比如不让齐刘海挡住我们的内容)

我们简单演示一下:SliverGrid+SliverPadding+SliverSafeArea的组合

class HomeContent extends StatelessWidget {  @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,              ),              delegate: SliverChildBuilderDelegate(                (BuildContext context, int index) {                  return Container(                    alignment: Alignment(0, 0),                    color: Colors.orange,                    child: Text("item$index"),                  );                },                childCount: 20              ),            ),          ),        )      ],    );  }}

4.2. Slivers的组合使用

这里我使用官方的示例程序,将SliverAppBar+SliverGrid+SliverFixedExtentList做出如下界面:

class HomeContent extends StatelessWidget {  @override  Widget build(BuildContext context) {    return showCustomScrollView();  }  Widget showCustomScrollView() {    return new CustomScrollView(      slivers: [        const SliverAppBar(          expandedHeight: 250.0,          flexibleSpace: FlexibleSpaceBar(            title: Text('Coderwhy Demo'),            background: Image(              image: NetworkImage(                "https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg",              ),              fit: BoxFit.cover,            ),          ),        ),        new SliverGrid(          gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent(            maxCrossAxisExtent: 200.0,            mainAxisSpacing: 10.0,            crossAxisSpacing: 10.0,            childAspectRatio: 4.0,          ),          delegate: new SliverChildBuilderDelegate(                (BuildContext context, int index) {              return new Container(                alignment: Alignment.center,                color: Colors.teal[100 * (index % 9)],                child: new Text('grid item $index'),              );            },            childCount: 10,          ),        ),        SliverFixedExtentList(          itemExtent: 50.0,          delegate: SliverChildBuilderDelegate(                (BuildContext context, int index) {              return new Container(                alignment: Alignment.center,                color: Colors.lightBlue[100 * (index % 9)],                child: new Text('list item $index'),              );            },            childCount: 20          ),        ),      ],    );  }}

五. 监听滚动事件

对于滚动的视图,我们经常需要监听它的一些滚动事件,在监听到的时候去做对应的一些事情。

比如视图滚动到底部时,我们可能希望做上拉加载更多;

比如滚动到一定位置时显示一个回到顶部的按钮,点击回到顶部的按钮,回到顶部;

比如监听滚动什么时候开始,什么时候结束;

在Flutter中监听滚动相关的内容由两部分组成:ScrollController和ScrollNotification。

5.1. ScrollController

在Flutter中,Widget并不是最终渲染到屏幕上的元素(真正渲染的是RenderObject),因此通常这种监听事件以及相关的信息并不能直接从Widget中获取,而是必须通过对应的Widget的Controller来实现。

ListView、GridView的组件控制器是ScrollController,我们可以通过它来获取视图的滚动信息,并且可以调用里面的方法来更新视图的滚动位置。

另外,通常情况下,我们会根据滚动的位置来改变一些Widget的状态信息,所以ScrollController通常会和StatefulWidget一起来使用,并且会在其中控制它的初始化、监听、销毁等事件。

我们来做一个案例,当滚动到1000位置的时候,显示一个回到顶部的按钮:

  • jumpTo(double offset)、animateTo(double offset,...):这两个方法用于跳转到指定的位置,它们不同之处在于,后者在跳转时会执行一个动画,而前者不会。
  • ScrollController间接继承自Listenable,我们可以根据ScrollController来监听滚动事件。
class MyHomePage extends StatefulWidget {  @override  State createState() => MyHomePageState();}class MyHomePageState extends State {  ScrollController _controller;  bool _isShowTop = false;    @override  void initState() {    // 初始化ScrollController    _controller = ScrollController();        // 监听滚动    _controller.addListener(() {      var tempSsShowTop = _controller.offset >= 1000;      if (tempSsShowTop != _isShowTop) {        setState(() {          _isShowTop = tempSsShowTop;        });      }    });        super.initState();  }  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text("ListView展示"),      ),      body: ListView.builder(        itemCount: 100,        itemExtent: 60,        controller: _controller,        itemBuilder: (BuildContext context, int index) {          return ListTile(title: Text("item$index"));        }      ),      floatingActionButton: !_isShowTop ? null : FloatingActionButton(        child: Icon(Icons.arrow_upward),        onPressed: () {          _controller.animateTo(0, duration: Duration(milliseconds: 1000), curve: Curves.ease);        },      ),    );  }}

5.2. NotificationListener

如果我们希望监听什么时候开始滚动,什么时候结束滚动,这个时候我们可以通过NotificationListener。

  • NotificationListener是一个Widget,模板参数T是想监听的通知类型,如果省略,则所有类型通知都会被监听,如果指定特定类型,则只有该类型的通知会被监听。
  • NotificationListener需要一个onNotification回调函数,用于实现监听处理逻辑。
  • 该回调可以返回一个布尔值,代表是否阻止该事件继续向上冒泡,如果为true时,则冒泡终止,事件停止向上传播,如果不返回或者返回值为false 时,则冒泡继续。

案例: 列表滚动, 并且在中间显示滚动进度

class MyHomeNotificationDemo extends StatefulWidget {  @override  State createState() => MyHomeNotificationDemoState();}class MyHomeNotificationDemoState extends State {  int _progress = 0;  @override  Widget build(BuildContext context) {    return NotificationListener(      onNotification: (ScrollNotification notification) {        // 1.判断监听事件的类型        if (notification is ScrollStartNotification) {          print("开始滚动.....");        } else if (notification is ScrollUpdateNotification) {          // 当前滚动的位置和总长度          final currentPixel = notification.metrics.pixels;          final totalPixel = notification.metrics.maxScrollExtent;          double progress = currentPixel / totalPixel;          setState(() {            _progress = (progress * 100).toInt();          });          print("正在滚动:${notification.metrics.pixels} - ${notification.metrics.maxScrollExtent}");        } else if (notification is ScrollEndNotification) {          print("结束滚动....");        }        return false;      },      child: Stack(        alignment: Alignment(.9, .9),        children: [          ListView.builder(            itemCount: 100,            itemExtent: 60,            itemBuilder: (BuildContext context, int index) {              return ListTile(title: Text("item$index"));            }          ),          CircleAvatar(            radius: 30,            child: Text("$_progress%"),            backgroundColor: Colors.black54,          )        ],      ),    );  }}


原文来自:https://mp.weixin.qq.com/s/rdmfeUECLtnZz6GeQKzOqA(侵权删除)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

flutter listview 滚动到底部_(五) Flutter入门学习 之 Widget滚动 的相关文章

  • 数据库分库分表中间件 Sharding-JDBC 源码分析 —— SQL 路由(二)之分库分表路由

    关注微信公众号 芋道源码 有福利 1 RocketMQ MyCAT Sharding JDBC 所有源码分析文章列表 2 RocketMQ MyCAT Sharding JDBC 中文注释源码 GitHub 地址 3 您对于源码的疑问每条留
  • c++学习之pair对组创建

    功能描述 成对出现的数据 利用队组可以反回两个数据 函数原型 pair
  • C# 项目没有.sln文件的解决办法:

    什么是sln文件 sln文件开发中使用的解决方案文件 使用解决方案文件 后缀为sln的文件 表示一个项目组 他通常包含一个项目中所有的工程文件信息 包括文件版本 工程信息 全局设置 通过打开sln文件就可以加载整个项目 但是我新建的一个项目
  • Win11总是出现BitLocker恢复,想要彻底关闭它该如何操作?

    win11解除bitlocker加密方法一 1 首先按下键盘 Win R 打开运行 如图所示 2 打开运行后 在其中输入 control 并点击 确定 打开控制面板 如图所示 3 打开后 进入 bitlocker驱动器加密 如图所示 4 随
  • 【计算机视觉

    文章目录 一 ResNeSt 二 ShuffleNet v2 三 FBNet 四 Inception v4 五 ResNet D 六 MetaFormer 七 PyramidNet 八 RevNet 九 Convolutional Visi
  • Shell脚本运行中的停止方法

    Linux系统Shell中提交了一个脚本 但是需要停止这个进程 如何处理 方式1 killall file flume kafka 说明 killall是一个命令 不是kill all file flume kafka是脚本名 此方法简单粗
  • C++ 发送http太慢导致数据积压问题分析(Linux)

    问题现象 程序接收数据 对数据进行简单地处理 处理完之后发送到其他平台 程序在接收到数据到在其他平台上面显示时间差了将近一个小时 存放要发送到其他平台的数据的容器积压了大概一百五十多万条的数据 问题排查过程 1 接收数据与发送数据到其他平台
  • 列出所有共享的文件夹权限或 NTFS 权限 (PowerShell)

    列出所有共享的文件夹权限或 NTFS 权限 PowerShell 此 PowerShell 脚本说明如何列出所有共享的文件夹权限或 NTFS 权限 下载 ListAllSharedFolderPermission zip 出所有共享的文件夹
  • HTML5网页设计常用标记-链接标记和列表标记

    链接标记 在HTML语言中 利用 a 标记在网页中创建超链接 语法格式 a href 跳转目标 target self 文本或图像 a 文字设置为超链接后 默认显示为加下划线的蓝色字体 图片设置为超链接后 会自动加一个黑色的边框 a 标记常
  • 内存的堆分配和栈分配 & 字符数组,字符指针,Sizeof总结

    程序占用的内存分为几个部分 各个部分起什么作用 字符数组 字符指针在实现上有什么区别等等 本文对此做了详细阐述 特转载于此 供大家学习参考之用 一个由C C 编译的程序占用的内存分为以下几个部分 1 栈区 stack 由编译器自动分配释放
  • 数据驱动性能体验优化

    本专题共10篇内容 包含淘宝APP基础链路过去一年在用户体验数据科学领域 包括商详 物流 性能 消息 客服 旅程等 一些探索和实践经验 在商详页基于用户动线和VOC挖掘用户决策因子带来浏览体验提升 在物流侧洞察用户求助时间与实际物流停滞时长
  • Ceph Pool操作总结

    Ceph Pool操作总结 一个ceph集群可以有多个pool 每个pool是逻辑上的隔离单位 不同的pool可以有完全不一样的数据处理方式 比如Replica Size 副本数 Placement Groups CRUSH Rules 快
  • bazel的使用

    bazel的使用 bazel是google开源的构建工具 可以支持多种语言的构建 这里来尝试一下如何在C 项目中使用bazel构建 安装就不介绍了 在官网很详细 输入bazel help Usage bazel
  • AD中如何对圆形PCB板进行铺铜

    因为之前做了一块圆形的PCB板子 所以在铺铜时候发现圆形铺铜我该怎么快速去铺 于是查了一下网上 大部分人是推荐先圈出一个圆弧 然后在通过快捷键TVG或者是按下 shift 空格 但是我发现不适合我 于是我分享一下自己的方法 我们如果要对圆形
  • 调参小技巧-DBSCAN参数选取方法

    利用循环迭代一些参数变量选取最适合的参数 1 初始数据处理部分 请自行对照调整 此处仅作为保持流程完整使用 读入第三方包 from sklearn import preprocessing 选取建模的变量 predictors Birth
  • 不得不引起足够重视的anonymous用户!

    连日的阴雨 使原本炎热的天气突然变得潮湿起来 烦躁的心情也慢慢地平复了下来 像往常一下 借用CuteFtp工具登录自己的VPS 检查一下文件异常 突然之间 几个刺眼的 exe文件呈现在我的眼前 顿时惊出我一身冷汗 下意识到 网站被黑客入侵了
  • C#使用Npgsql或SqlClient连接数据库

    目录 SqlClient连接SQL Server 安装SqlClient SqlConnection SqlCommand SqlConnection 和 SqlCommand的区别 Npgsql连接PostgreSQL 安装Npgsql
  • Asp.net core

    Startup类 以配置应用所需的服务 应用的请求处理管道定义为一系列中间件组件 public class Startup public void ConfigureServices IServiceCollection services
  • prototype.js 和json.js 冲突

    1 冲突简述和分析 prototype js与json js并不是完全兼容的 主要冲突在于json js为Object的原型增加了一个toJSONString的方法 冲突之一 是prototype中发送ajax请求时 遍历了一个header

随机推荐

  • 微众银行发布区块链“善度”,提出区块链优化社会治理参考框架

    2019年9月17日 以 区块链新经济 新十年 新起点 为主题的第五届区块链全球峰会在上海召开 微众银行副行长兼首席信息官马智涛受邀发表演讲 在峰会主论坛上 微众银行正式发布区块链优化社会治理模式参考框架 善度 为区块链行业发展提出新的发展
  • (Linux) ----> Centos7.X+配置MySQL(亲测,详细步骤)

    目录 一 创建虚拟机 1 1 新建虚拟机 编辑 1 2 虚拟机配置 二 使用外部工具连接服务器操作 XShell MobaXterm1 CHS1 根据自己习惯选择 2 1 设置Ip地址 编辑 2 2 连接虚拟机 三 下载相关的压缩包并配置连
  • VQGAN(Vector Quantized Generative Adversarial Network)模型简介

    论文 Taming Transformers for High Resolution Image Synthesis VQGAN Vector Quantized Generative Adversarial Network 是一种基于 G
  • Rocky Linux 9.1 新手入门指南

    文章目录 安装系统 配置网络 NetworkManager 配置 默认 ipaddress 配置文件 nmtui 配置 ipaddress nmcli 配置 ipaddress 网络管理 网关配置 检查网络连接 配置 bond 设置主机名
  • cmd怎么实现隐藏DOS窗口运行程序

    写个xxx vbs调用执行aaa bat即可 CreateObject WScript Shell Run cmd c aaa bat 0
  • spring gateway 的搭建与配置

    步骤 建项目 给主启动类添加Eureka的注解 EnableEurekaClient 添加并配置application yml 第一步 新建gateway的项目 gateway 8205 需要用到的组件
  • el-descriptions的使用

    el descriptions的使用 解释 我们页面有很多无序的列表展示 为了高效得去开发我们得页面 可以借助于这个组件进行适应 图片 代码 template部分
  • MIPI D-PHY介绍(二) FPGA

    MIPI D PHY介绍 二 FPGA 随着移动设备的广泛普及 MIPI D PHY作为其最主要的物理层标准之一 被越来越多地使用在各种嵌入式系统中 本文将详细介绍MIPI D PHY的工作原理和在FPGA设计中的实现方法 MIPI D P
  • 在k8s集群内搭建Prometheus监控平台

    基本架构 Prometheus由SoundCloud发布 是一套由go语言开发的开源的监控 报警 时间序列数据库的组合 Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态 任意组件只要提供对应的HTTP接口就可以接入
  • .NetCore技术研究-ConfigurationManager在单元测试下的坑

    最近在将原有代码迁移 NET Core 代码的迁移基本很快 当然也遇到了不少坑 重构了不少 后续逐步总结分享给大家 今天总结分享一下ConfigurationManager遇到的一个问题 先说一下场景 迁移 NET Core后 已有的配置文
  • 如何使用Visual Studio Code运行C/C++程序

    与Visual Studio 2008 2010 集成开发工具不同 Visual Studio Code只是一个代码编辑器 在Windows环境下 需下载安装 C C 编译器 配置环境等 VS Code才可以编译代码和运行程序 1 下载安装
  • javaScript基础面试题 --- 原型链

    1 原型可以解决什么问题 对象共享属性和共享方法 2 谁有原型 函数有prototype 对象有 proto 3 查找顺序 当查询一个对象的属性时 JavaScript 会首先检查对象自身是否有这个属性 如果对象本身没有该属性 那么 JS
  • 使用python和snapshot备份ElasticSearch索引数据

    该python备份snapshot的索引数据脚本 通过Elasticsearch连接es 然后通过es indices get alias函数获取所有索引名称 通过列表的startswith函数剔除 开头的自带索引名称 然后把所有索引名称放
  • 多边形的面积

    1 三角形面积 xy平面内 有三角形123 如下图所示 图1 借助矢量叉积和点积 这个三角形的面积公式非常简单 这个面积是有符号的 1 2 3逆时针排列 则面积为正 1 2 3顺时针排列 则面积为负 这是对右手系的总结 如果从背面看这个坐标
  • 11月11日 自定义Events,将自定义Events分配给UI,给UI添加动画 UE4斯坦福 学习笔记

    自定义Events 在AttributeComponent的 h头文件上加上代码 自定义Event DECLARE DYNAMIC MULTICAST DELEGATE FourParams FOnHealthChanged AActor
  • 思科模拟器简单校园网设计,期末作业难度

    文章简介 本文用思科模拟器设计和规划了一个校园网络 相当于计算机网络相关专业期末作业难度 作者简介 网络工程师 希望能认识更多的小伙伴一起交流 可私信或QQ号 1686231613 一 网络需求分析 1 学校建有办公室 实验室 教学楼 学生
  • 【STM32】RS485通信使用DMA串口发送数据出现数据丢失、断包问题排查方法

    最近在搞这个Modbus协议 由于485协议是半双工的 区别于RS 232的全双工 考虑不周导致调试modbus协议时候出了不少问题 第一 大多数开发板上的485芯片是MAX485 发送和接收状态的切换是通过IO给到这个两个引脚不同的电平进
  • win 11又更新,新功能简直绝了!

    很早之前 咱就知道微软下半年将会有一次大动作 没错 就是发布Win11 22H2正式版 之前有说过9月份发 现在也确实做到了 微软现在已经面向190多个国家 地区推送了Windows 11 22H2正式版更新 更新之后版本号为22621 5
  • linux中通过sed命令通过正则表达式过滤出中文[^[\u4E00-\u9FA5A-Za-z0-9_]+$]

    linux中通过sed命令通过正则表达式过滤出中文 sed r s u4E00 u9FA5A Za z0 9 lt gt 0 9 a z A Z g zz txt gt a txt
  • flutter listview 滚动到底部_(五) Flutter入门学习 之 Widget滚动

    列表是移动端经常使用的一种视图展示方式 在Flutter中提供了ListView和GridView 为了可能展示出更好的效果 我这里提供了一段Json数据 所以我们可以先学习一下Json解析 一 JSON读取和解析 在开发中 我们经常会使用