鸿蒙Harmony-列表组件(List)详解

不要和别人比生活,每个人阶段不同,追求不同,活法自然也不同。只要今天的你能比昨天的你快乐一点点,那你就是自己人生赢家。

目录

一,定义

二,布局与约束

2.1 布局

2.2 约束

三,开发布局

3.1 设置主轴方向

3.2设置交叉轴布局

四,迭代列表内容

五,自定义列表样式

5.1 设置内容间距

5.2 添加分隔线

5.3 添加滚动条

5.4 支持分组列表

5.5 添加粘性标题

5.6 控制滚动位置

5.7 响应列表项侧滑

5.8 给列表项添加标记

一,定义

类似于Android的recyclerview,鸿蒙的列表List是一种复杂的容器,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集,例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求(如通讯录、音乐列表、购物清单等)。

使用列表可以轻松高效地显示结构化、可滚动的信息。通过在List组件中按垂直或者水平方向线性排列子组件ListItemGroup或ListItem,为列表中的行或列提供单个视图,或使用循环渲染迭代一组行或列,或混合任意数量的单个视图和ForEach结构,构建一个列表。List组件支持使用条件渲染、循环渲染、懒加载等渲染控制方式生成子组件。

二,布局与约束

列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件。

在垂直列表中,List按垂直方向自动排列ListItemGroup或ListItem。

ListItemGroup用于列表数据的分组展示,其子组件也是ListItem。ListItem表示单个列表项,可以包含单个子组件。

注意:List的子组件必须是ListItemGroup或ListItem,ListItem和ListItemGroup必须配合List来使用。

2.1 布局

List除了提供垂直和水平布局能力、超出屏幕时可以滚动的自适应延伸能力之外,还提供了自适应交叉轴方向上排列个数的布局能力。

利用垂直布局能力可以构建单列或者多列垂直滚动列表

利用水平布局能力可以是构建单行或多行水平滚动列表

2.2 约束

列表的主轴方向是指子组件列的排列方向,也是列表的滚动方向。垂直于主轴的轴称为交叉轴,其方向与主轴方向相互垂直。

垂直列表的主轴是垂直方向,交叉轴是水平方向;水平列表的主轴是水平方向,交叉轴是垂直方向。

如果List组件主轴或交叉轴方向设置了尺寸,则其对应方向上的尺寸为设置值。

如果List组件主轴方向没有设置尺寸,当List子组件主轴方向总尺寸小于List的父组件尺寸时,List主轴方向尺寸自动适应子组件的总尺寸。

类似于Android的wrap_content

三,开发布局

3.1 设置主轴方向

List组件主轴默认是垂直方向,即默认情况下不需要手动设置List方向,就可以构建一个垂直滚动列表。

若是水平滚动列表场景,将List的listDirection属性设置为Axis.Horizontal即可实现。listDirection默认为Axis.Vertical,即主轴默认是垂直方向。

垂直列表:

@Entry
@Component
struct Index {build() {List(){ListItem(){Text("袁震1").fontSize(24)}ListItem(){Text("袁震2").fontSize(24)}ListItem(){Text("袁震3").fontSize(24)}}.listDirection(Axis.Vertical)}
}

水平列表:

@Entry
@Component
struct Index {build() {List(){ListItem(){Text("袁震1").fontSize(24)}ListItem(){Text("袁震2").fontSize(24)}ListItem(){Text("袁震3").fontSize(24)}}.listDirection(Axis.Horizontal)}
}

3.2设置交叉轴布局

List组件的交叉轴布局可以通过lanes和alignListItem属性进行设置,lanes属性用于确定交叉轴排列的列表项数量,alignListItem用于设置子组件在交叉轴方向的对齐方式。

List组件的lanes属性通常用于在不同尺寸的设备自适应构建不同行数或列数的列表,即一次开发、多端部署的场景,例如歌单列表。lanes属性的取值类型是"number | LengthConstrain",即整数或者LengthConstrain类型。以垂直列表为例,如果将lanes属性设为2,表示构建的是一个两列的垂直列表。lanes的默认值为1,即默认情况下,垂直列表的列数是1。

交叉轴方向列表项是2,对齐方式为居中对齐:

@Entry
@Component
struct Index {build() {List(){ListItem(){Text("袁震1").fontSize(24)}ListItem(){Text("袁震2").fontSize(24)}ListItem(){Text("袁震3").fontSize(24)}ListItem(){Text("袁震4").fontSize(24)}}.listDirection(Axis.Vertical).lanes(2).alignListItem(ListItemAlign.Center)}
}

当其取值为LengthConstrain类型时,表示会根据LengthConstrain与List组件的尺寸自适应决定行或列数。

例如,假设在垂直列表中设置了lanes的值为{ minLength: 200, maxLength: 300 }。此时,

 当List组件宽度为300vp时,由于minLength为200vp,此时列表为一列:

@Entry
@Component
struct Index {@State egLanes: LengthConstrain = { minLength: 200, maxLength: 300 }build() {List(){ListItem(){Text("袁震1").fontSize(24)}ListItem(){Text("袁震2").fontSize(24)}ListItem(){Text("袁震3").fontSize(24)}ListItem(){Text("袁震4").fontSize(24)}}.width(300).lanes(this.egLanes).listDirection(Axis.Vertical).alignListItem(ListItemAlign.Center)}
}

  

当List组件宽度变化至400vp时,符合两倍的minLength,则此时列表自适应为两列:

@Entry
@Component
struct Index {@State egLanes: LengthConstrain = { minLength: 200, maxLength: 200 }build() {List(){ListItem(){Text("袁震1").fontSize(24)}ListItem(){Text("袁震2").fontSize(24)}ListItem(){Text("袁震3").fontSize(24)}ListItem(){Text("袁震4").fontSize(24)}}.width(400).lanes(this.egLanes).listDirection(Axis.Vertical).alignListItem(ListItemAlign.Center)}
}

  

四,迭代列表内容

通常,应用通过数据集合动态地创建列表。使用循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件,降低代码复杂度。

ArkTS通过ForEach提供了组件的循环渲染能力。

新建数据类:

export default class YuanZhen {public name: string = 'YuanZhen';public age: number = 18;constructor(name: string, age: number) {this.name = namethis.age = age}
}

组件:

import YuanZhen from './bean/YuanZhen'@Entry
@Component
struct Index {@State list:Array<YuanZhen>=new ArrayaboutToAppear(){this.list.push(new YuanZhen("袁震1",18))this.list.push(new YuanZhen("袁震2",19))this.list.push(new YuanZhen("袁震3",20))this.list.push(new YuanZhen("袁震4",21))this.list.push(new YuanZhen("袁震5",22))this.list.push(new YuanZhen("袁震6",23))}build() {List(){ForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}.width(400).listDirection(Axis.Vertical)}
}

五,自定义列表样式

5.1 设置内容间距

在初始化列表时,如需在列表项之间添加间距,可以使用space参数。例如,在每个列表项之间沿主轴方向添加10vp的间距

import YuanZhen from './bean/YuanZhen'@Entry
@Component
struct Index {@State list:Array<YuanZhen>=new ArrayaboutToAppear(){this.list.push(new YuanZhen("袁震1",18))this.list.push(new YuanZhen("袁震2",19))this.list.push(new YuanZhen("袁震3",20))this.list.push(new YuanZhen("袁震4",21))this.list.push(new YuanZhen("袁震5",22))this.list.push(new YuanZhen("袁震6",23))}build() {List({space:10}){ForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}.width(400).listDirection(Axis.Vertical)}
}

5.2 添加分隔线

分隔线用来将界面元素隔开,使单个元素更加容易识别。

List提供了divider属性用于给列表项之间添加分隔线。在设置divider属性时,可以通过strokeWidth和color属性设置分隔线的粗细和颜色。

startMargin和endMargin属性分别用于设置分隔线距离列表侧边起始端的距离和距离列表侧边结束端的距离。

import YuanZhen from './bean/YuanZhen'@Entry
@Component
struct Index {@State list:Array<YuanZhen>=new ArrayaboutToAppear(){this.list.push(new YuanZhen("袁震1",18))this.list.push(new YuanZhen("袁震2",19))this.list.push(new YuanZhen("袁震3",20))this.list.push(new YuanZhen("袁震4",21))this.list.push(new YuanZhen("袁震5",22))this.list.push(new YuanZhen("袁震6",23))}build() {List({space:10}){ForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}.divider({strokeWidth:1,startMargin:60,endMargin:10,color: '#ffe9f0f0'}).width(400).listDirection(Axis.Vertical)}
}

5.3 添加滚动条

当列表项高度(宽度)超出屏幕高度(宽度)时,列表可以沿垂直(水平)方向滚动。在页面内容很多时,若用户需快速定位,可拖拽滚动条,

在使用List组件时,可通过scrollBar属性控制列表滚动条的显示。scrollBar的取值类型为BarState,当取值为BarState.Auto表示按需显示滚动条。此时,当触摸到滚动条区域时显示控件,可上下拖拽滚动条快速浏览内容,拖拽时会变粗。若不进行任何操作,2秒后滚动条自动消失。

从API version 10版本开始默认值为BarState.Auto

import YuanZhen from './bean/YuanZhen'@Entry
@Component
struct Index {@State list:Array<YuanZhen>=new ArrayaboutToAppear(){this.list.push(new YuanZhen("袁震1",18))this.list.push(new YuanZhen("袁震2",19))this.list.push(new YuanZhen("袁震3",20))this.list.push(new YuanZhen("袁震4",21))this.list.push(new YuanZhen("袁震5",22))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震6",23))this.list.push(new YuanZhen("袁震8",28))}build() {List({space:10}){ForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}.scrollBar(BarState.On).divider({strokeWidth:1,startMargin:60,endMargin:10,color: '#ffe9f0f0'}).width(400).listDirection(Axis.Vertical)}
}

5.4 支持分组列表

在列表中支持数据的分组展示,可以使列表显示结构清晰,查找方便,从而提高使用效率。

在List组件中使用ListItemGroup对项目进行分组,可以构建二维列表。

在List组件中可以直接使用一个或者多个ListItemGroup组件,ListItemGroup的宽度默认充满List组件。在初始化ListItemGroup时,可通过header参数设置列表分组的头部组件。

如果多个ListItemGroup结构类似,可以将多个分组的数据组成数组,然后使用ForEach对多个分组进行循环渲染。

import YuanZhen from './bean/YuanZhen'@Entry
@Component
struct Index {@State list:Array<YuanZhen>=new Array@Builder itemHead(text: string) {Text(text).fontSize(20).backgroundColor('#345').width('100%').padding(5)}aboutToAppear(){this.list.push(new YuanZhen("袁震1",18))this.list.push(new YuanZhen("袁震2",19))this.list.push(new YuanZhen("袁震3",20))this.list.push(new YuanZhen("袁震4",21))this.list.push(new YuanZhen("袁震5",22))}build() {List({space:10}){ListItemGroup({ header: this.itemHead('A') }) {// 循环渲染分组A的ListItemForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}ListItemGroup({ header: this.itemHead('B') }) {// 循环渲染分组A的ListItemForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}}.scrollBar(BarState.On).divider({strokeWidth:1,startMargin:60,endMargin:10,color: '#ffe9f0f0'}).width(400).listDirection(Axis.Vertical)}
}

5.5 添加粘性标题

粘性标题是一种常见的标题模式,常用于定位字母列表的头部元素。

粘性标题不仅有助于阐明列表中数据的表示形式和用途,还可以帮助用户在大量信息中进行数据定位,从而避免用户在标题所在的表的顶部与感兴趣区域之间反复滚动。

List组件的sticky属性配合ListItemGroup组件使用,用于设置ListItemGroup中的头部组件是否呈现吸顶效果或者尾部组件是否呈现吸底效果。

通过给List组件设置sticky属性为StickyStyle.Header,即可实现列表的粘性标题效果。如果需要支持吸底效果,可以通过footer参数初始化ListItemGroup的底部组件,并将sticky属性设置为StickyStyle.Footer。

5.6 控制滚动位置

控制滚动位置在实际应用中十分常见,例如当新闻页列表项数量庞大,用户滚动列表到一定位置时,希望快速滚动到列表底部或返回列表顶部。此时,可以通过控制滚动位置来实现列表的快速定位

List组件初始化时,可以通过scroller参数绑定一个Scroller对象,进行列表的滚动控制。例如,用户在新闻应用中,点击新闻页面底部的返回顶部按钮时,就可以通过Scroller对象的scrollToIndex方法使列表滚动到指定的列表项索引位置。

import YuanZhen from './bean/YuanZhen'@Entry
@Component
struct Index {@State list:Array<YuanZhen>=new ArraylistScroller: Scroller = new Scroller();@Builder itemHead(text: string) {Text(text).fontSize(20).backgroundColor('#345').width('100%').padding(5)}aboutToAppear(){this.list.push(new YuanZhen("袁震1",18))this.list.push(new YuanZhen("袁震2",19))this.list.push(new YuanZhen("袁震3",20))this.list.push(new YuanZhen("袁震4",21))this.list.push(new YuanZhen("袁震5",22))}build() {Column(){Text("回到顶部").width(50).height(50).onClick(()=>{this.listScroller.scrollToIndex(0)})List({space:10, scroller: this.listScroller}){ListItemGroup({ header: this.itemHead('A') }) {// 循环渲染分组A的ListItemForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}ListItemGroup({ header: this.itemHead('B') }) {// 循环渲染分组A的ListItemForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}ListItemGroup({ header: this.itemHead('C') }) {// 循环渲染分组A的ListItemForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}}.scrollBar(BarState.On).divider({strokeWidth:1,startMargin:60,endMargin:10,color: '#ffe9f0f0'}).sticky(StickyStyle.Header)  // 设置吸顶,实现粘性标题效果.width("100%").listDirection(Axis.Vertical)}.width("100%").height("100%")}
}

5.7 响应列表项侧滑

ListItem的swipeAction属性可用于实现列表项的左右滑动功能。swipeAction属性方法初始化时有必填参数SwipeActionOptions,其中,start参数表示设置列表项右滑时起始端滑出的组件,end参数表示设置列表项左滑时尾端滑出的组件。

在消息列表中,end参数表示设置ListItem左滑时尾端划出自定义组件,即删除按钮。在初始化end方法时,将滑动列表项的索引传入删除按钮组件,当用户点击删除按钮时,可以根据索引值来删除列表项对应的数据,从而实现侧滑删除功能。

import YuanZhen from './bean/YuanZhen'@Entry
@Component
struct Index {@State list:Array<YuanZhen>=new ArraylistScroller: Scroller = new Scroller();@Builder itemHead(text: string) {Text(text).fontSize(20).backgroundColor('#345').width('100%').padding(5)}@Builder itemEnd(index: number) {// 构建尾端滑出组件Button({ type: ButtonType.Circle }) {Image($r('app.media.startIcon')).width(20).height(20)}.onClick(() => {// this.messages为列表数据源,可根据实际场景构造。点击后从数据源删除指定数据项。this.list.splice(index, 1);})}aboutToAppear(){this.list.push(new YuanZhen("袁震1",18))this.list.push(new YuanZhen("袁震2",19))this.list.push(new YuanZhen("袁震3",20))this.list.push(new YuanZhen("袁震4",21))this.list.push(new YuanZhen("袁震5",22))}build() {Column(){List({space:10, scroller: this.listScroller}){ListItemGroup({ header: this.itemHead('A') }) {// 循环渲染分组A的ListItemForEach(this.list,(item:YuanZhen,index)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}.swipeAction({ end: this.itemEnd(index) }) // 设置侧滑属性})}ListItemGroup({ header: this.itemHead('B') }) {// 循环渲染分组A的ListItemForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}ListItemGroup({ header: this.itemHead('C') }) {// 循环渲染分组A的ListItemForEach(this.list,(item:YuanZhen)=>{ListItem(){Row() {Image($r('app.media.startIcon')).width(40).height(40).margin(10)Text(item.name).fontSize(20)Text("  年龄:"+item.age).fontSize(20)}}})}}.scrollBar(BarState.On).divider({strokeWidth:1,startMargin:60,endMargin:10,color: '#ffe9f0f0'}).sticky(StickyStyle.Header)  // 设置吸顶,实现粘性标题效果.width("100%").listDirection(Axis.Vertical)}.width("100%").height("100%")}
}

5.8 给列表项添加标记

添加标记是一种无干扰性且直观的方法,用于显示通知或将注意力集中到应用内的某个区域。例如,当消息列表接收到新消息时,通常对应的联系人头像的右上方会出现标记,提示有若干条未读消息

在ListItem中使用Badge组件可实现给列表项添加标记功能。Badge是可以附加在单个组件上用于信息标记的容器组件。

在消息列表中,若希望在联系人头像右上角添加标记,可在实现消息列表项ListItem的联系人头像时,将头像Image组件作为Badge的子组件。

在Badge组件中,count和position参数用于设置需要展示的消息数量和提示点显示位置,还可以通过style参数灵活设置标记的样式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/410280.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三、Qt Creator 使用

关于Qt的安装及环境配置&#xff0c;在我的上一篇《二、QT下载、安装及问题解决(windows系统)》已经讲过了。 本章节有一个重点&#xff0c;在新建 工程文件时&#xff0c;所在路径不要有中文&#xff0c;否则编译及运行程序不能正常运行。 在使用Qt Creator&#xff08;以下…

Python 布尔类型:了解真假之间的探索

Python 是一种备受欢迎的编程语言&#xff0c;以其简洁、灵活和易学易用而闻名。其中一个重要的数据类型就是布尔类型&#xff08;bool&#xff09;&#xff0c;它代表了逻辑上的真&#xff08;True&#xff09;和假&#xff08;False&#xff09;。在 Python 中&#xff0c;布…

【数据库】聊聊MVCC机制与BufferPool缓存机制

上一篇文章&#xff0c;介绍了隔离级别&#xff0c;MySQL默认是使用可重复读&#xff0c;但是在可重复读的级别下&#xff0c;可能会出现幻读&#xff0c;也就是读取到另一个session添加的数据&#xff0c;那么除了配合使用间隙锁的方式&#xff0c;还使用了MVCC机制解决&#…

【算法分析与设计】跳跃游戏

题目 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - …

vue中使用mpegts.js播放flv的直播视频流

第一步&#xff1a;引入mpegts.js npm install --save mpegts.js 第二步&#xff1a;在vue文件中引入mpegts.js的依赖 第三步&#xff1a;编写展示视频的盒子 我这里是使用循环遍历的方式创建video标签&#xff0c;这样方便后面随机展示视频使用 <template><div>&l…

甄选7款前端动画特效源码资源分享(附在线预览)

分享7款有趣也实用的前端动画特效 其中有CSS动画、canvas动画、js小游戏等等 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 交互式加载动画 基于three.js制作的一款交互式加载动画 鼠标长按时还有环形的过渡到圆圈的效果…

第十二章 Java内存模型与线程(二)

文章目录 12.4 Java与线程12.4.1 线程的实现12.4.2 Java线程调度12.4.3 状态转换 12.5 Java与协程12.5.1 内核线程的局限12.5.2 协程的复苏12.5.3 Java的解决方案 12.4 Java与线程 12.4.1 线程的实现 实现线程主要有三种方式&#xff1a;使用内核线程实现&#xff08;1&#…

LLaMa2 Chat gpt 大模型本地部署初体验

一直想在自己电脑或者测试环境随便找台服务器尝试部署一下“大模型”&#xff0c;但“大模型”对于内存和GPU的要求令人望而却步&#xff0c;层出不穷的各种术语也令人困惑&#xff0c;有点难以下手。 经过一段时间&#xff0c;在百度千帆大模型平台、讯飞星火大模型平台、魔搭…

工业平板定制方案_基于联发科、紫光展锐平台的工业平板电脑方案

工业平板主板采用联发科MT6762平台方案&#xff0c;搭载Android 11.0操作系统&#xff0c; 主频最高2.0GHz&#xff0c;效能有大幅提升;采用12nm先进工艺&#xff0c;具有低功耗高性能的特点。 该工业平板主板搭载了IMG GE8320图形处理器&#xff0c;最高主频为680MHz, 支持108…

RK3566RK3568安卓11隐藏状态栏带接口

文章目录 前言一、创建全局变量二、设置应用添加隐藏导航栏按钮三、添加按钮功能四、动态隐藏还有显示功能五、创建系统导航栏广播接口总结 前言 关于Android系统的状态栏&#xff0c;不同的客户有不同的需求: 有些客户需要永久隐藏状态栏&#xff0c;有些客户需要在设置显示中…

PDF 文档解除密码

PDF 文档解除密码 1. 文件 -> 文档属性 -> 安全 -> 文档限制摘要2. PDF365References 1. 文件 -> 文档属性 -> 安全 -> 文档限制摘要 密码保护《算法设计与分析基础_第3版.pdf》 2. PDF365 https://www.pdf365.cn/ 免费功能 -> PDF 去密码 开始去除 Re…

计算机网络-NAT网络地址转换

今天来回顾下之前所学的知识&#xff0c;将它们串联起来进行巩固。一开始了解了IP编址进行IP设置和划分网段&#xff1b;学习了二层以太网交换&#xff0c;了解了二层通信基础&#xff1b;学习了路由基础知识&#xff0c;大致了解到了路由是什么&#xff1f;静态路由和动态路由…