Android---Jetpack Compose学习002

Compose 布局。Compose 布局的目标:1)实现高性能;2)让开发者能够轻松编写自定义布局;3)在 Compose 中,通过避免多次测量布局子级可实现高性能。如果需要进行多次测量,Compose 具有一个特殊系统,即固有特性测量。

标准布局组件

\bullet 使用 Column 可将多个像垂直地放置在屏幕上;

\bullet 使用 Row 可将多个项水平地放置在屏幕上;

\bullet 使用 Box 可将一个元素放在另一个元素上。类似于 FrameLayout 布局。

修饰符

修饰符的作用类似于xml 布局中的布局参数。借助修饰符,可以修饰或扩充可组合项。我们可以使用修饰符来执行以下操作:

\bullet 更改可组合项的大小、布局、行为和外观;

\bullet 添加信息,如无障碍标签;

\bullet 处理用户输入;

\bullet 添加高级互动,如使元素可点击、可滚动、可拖动或可缩放。

示例:通过标准布局组件修饰符实现如下布局效果

1. 新建一个 PhotoGrapherCard.kt 文件,进行布局

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp/*** @Author HL* @Date 2023/12/26 20:21* @Version 1.0*/
@Composable
fun PhotographerCard(modifier: Modifier = Modifier){// TODO 水平放置,从左到右Row(modifier = Modifier.clip(RoundedCornerShape(4.dp)) // 设置圆角.background(color = MaterialTheme.colors.surface) // surface 是白色.clickable(onClick = {}).padding(all = 16.dp) // 设置点击时,水波纹效果) {Surface (modifier = Modifier.size(50.dp),//设置图片大小shape = CircleShape, // 设置圆形形状// onSurface 是黑色color = MaterialTheme.colors.onSurface.copy(alpha = 0.2f) // 设置颜色。copy()把这个颜色复杂过来,然后设置一个透明度) {Image(painter = painterResource(id = R.drawable.beauty), // 设置图片加载位置contentDescription = null)}// TODO 垂直放置,从上到下Column (modifier = Modifier.padding(start = 8.dp) // 左边设置填充 8dp.align(Alignment.CenterVertically) // 让文字垂直居中) {Text(text = "Alfred Sisley",fontWeight = FontWeight.Bold // 设置字体,bold: 粗体)//LocalContentAlpha provides ContentAlpha.medium == LocalContentAlpha.provides(ContentAlpha.medium)// provides 是一个被 infix 修饰的函数。可以省略链式调用的“." 以及一对圆括号"()"// 隐式传参CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {Text(text = "3 minutes ago",style = MaterialTheme.typography.body2 // 设置字体)}}}
}

2. 在 MainActivity.kt 里调用 PhotoGrapherCard

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {JetpackComposeLayoutsTheme {PhotographerCard()}}}
}

修饰符的顺序

由于每个函数都会对上一个函数返回的 Modifier 进行更改,因此顺序会影响最终结果。

Slots API

Material 组件大量使用槽位 API,这是 Compose 引入的一种模式,它在可组合项之上带来一层自定义设置。这种方法使组件变得更灵活,因为它们接受 可以自行配置的子元素,而不必公开子元素的每个配置参数。槽位会在界面中留出空白区域,让开发者按照自己的意愿来填充。

TopAppBar

scaffold

Scaffold 可以让我们实现具有基本 Material Design 布局结构的界面。Scaffold 可以为最常见的顶级 Material 组件(如 TopAppBar、BottomAppBar、FloatingActionButton 和 Drawer)提供槽位。通过使用 Scaffold,可轻松确保这些组件得到适当放置且正确地协同工作

示例:

创建 LayoutStudy.kt,完成布局

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp/*** @Author HL* @Date 2023/12/26 21:15* @Version 1.0*/
@Composable
fun LayoutStudy(){Scaffold (// topBar 布局顶部topBar = {TopAppBar(// 设置标题title = {Text(text = "LayoutStudy")},// 设置图标actions = {IconButton(onClick = {}) {Icon(imageVector = Icons.Filled.Favorite, contentDescription = null)}})}) { innerPadding ->// 布局 body 部分BodyContent(Modifier.padding(innerPadding))}
}@Composable
fun BodyContent(modifier : Modifier = Modifier){Column(modifier = Modifier.padding(8.dp)) {Text(text = "Hi there!")Text(text = "Thanks for going through the LayoutStudy")}
}

在 MainActivity.kt 里调用

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {JetpackComposeLayoutsTheme {//PhotographerCard()LayoutStudy()}}}
}

使用列表

如果我们知道用例不需要任何滚动,可以使用简单的 Column 或 Row。如果需要显示大量列表项(或长度未知的列表),可以使用 LazyColumnLazyRow

示例:设置一个可滚动的列表。可以通过 LayColumn 实现上下滚动的列表。

1. Lists.kt

@Composable
fun ScrollingList(){val listSize = 100val scrollState = rememberLazyListState()val coroutineScope = rememberCoroutineScope()// 放一个包含2个按钮的顶部布局,再放一个 List,从上到下Column() {//TODO 放两个按钮,从左到右Row {// 第一个按钮Button(modifier = Modifier.weight(1f), // 设置权重onClick = {//Kotlin 携程coroutineScope.launch {// 滚到最顶部scrollState.animateScrollToItem(0)}}) {Text(text = "Scroll to the top")}// 第二个按钮Button(modifier = Modifier.weight(1f),onClick = {coroutineScope.launch {// 滚动最底部scrollState.animateScrollToItem(listSize - 1)}}) {Text(text = "Scroll to the end")}}//TODO 放列表项LazyColumn(state = scrollState){items(listSize){// 列表项ImageListItem(index = it)}}}
}@Composable
fun ImageListItem(index : Int){Row(verticalAlignment = Alignment.CenterVertically) {Image(painter = painterResource(id = R.drawable.beauty),contentDescription = null,modifier = Modifier.size(40.dp))Spacer(modifier = Modifier.width(10.dp))Text(text = "Item $index", style = MaterialTheme.typography.subtitle1)}
}

2. MainActivity.kt

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {JetpackComposeLayoutsTheme {ScrollingList()}}}
}

自定义布局

在 Compose 中,界面元素由可组合函数表示,此类函数在被调用后会发出一部分界面,这部分界面随后会被添加到呈现在屏幕上的界面树中。每个界面元素都有一个父元素,还可能有多个子元素。此外,每个元素在其父元素中都有一个位置,指定为(x, y)位置;也都有一个尺寸,指定为 width 和 height。

使用布局修饰符

你可以使用 layout 修饰符修改元素的测量和布局方式。Layout 是一个 lambda;它的参数包括你可以测量的元素(以 measurable 的形式传递)以及该组合项的传入约束条件(以 constraints 的形式传递)。

示例:我们有如下一个需求:有一个文本 “Hi threr!”,它有一个 firstbaseline(图中红框),正常情况下,firstbaseline 是到图中 1 处的距离。现在的需求是 firstbaseline 是和父元素的距离,也就是下图中 2 处的距离。

FirstBaselineToTop.kt
// firstBaselineToTop 为 Modifier 的扩展函数
fun Modifier.firstBaselineToTop(firstBaselineToTop : Dp) = this.then(// this.then() 的 放回值就是一个 Modifier// TODO 用 layout 修饰符来修改元素的测量和布局位置// measurable 测量元素;constraints 约束条件layout { measurable, constraints ->// 测量元素val placeable = measurable.measure(constraints)// 测量之后,获取元素的基线值,即 firsrBaseline 到元素顶部的值val firstBaseline = placeable[FirstBaseline]// 元素左上角新的 Y 坐标值 = 新基线值 - 旧基线值;firstBaselineToTop 方法传进来的值// roundToPx() 转为像素val Y = firstBaselineToTop.roundToPx() - firstBaseline// 设置元素的宽和高。元素的高是指,元素底部到父容器顶部的位置val height = placeable.height + Ylayout(placeable.width, height){//设置元素的新位置placeable.placeRelative(0, Y)}}
)
@Composable
fun TextWithPaddingToBaseline(){JetpackComposeLayoutsTheme {// 这里我们要 firstBaselineToTop 设置值为 baseline 到 父容器顶部为 24dp,// TODO 这个值由我们自己设定Text(text = "Hi There!",Modifier// 指定 firstBaselineToTop 的值.firstBaselineToTop(24.dp) // 这里需要返回一个 Modifier 才能继续下面的链式调用.background(Color.Red))}
}

firstBaselineToTop

右边的布局中, firstBaselineToTop 值是到父容器顶部的距离,是我们上面代码中设定的 24dp, 然后 measure 可以帮我们测出 Text 的基线高度(firstBaseline),那么 Text 左上角黑点的位置坐标为(0, firstBaselineToTop - firstBaseline)

MyOwnColumn

完成如下布局,模仿 Column 布局,给了4个文本,一列4行的方式排列。 

示例代码:

@Composable
fun MyOwnColumn(modifier: Modifier = Modifier,content : @Composable ()-> Unit){// 有多个元素,所以用 Layout()Layout(modifier = modifier,content = content){ measurables, constraints ->// 测量多个元素val placeables = measurables.map { measurable ->measurable.measure(constraints)}var positionY = 0// 元素布局的大小,设置为父容器的最大高度和宽度layout(constraints.maxWidth, constraints.maxHeight){placeables.forEach { placeable ->//placeable 就是我们测量的每一个子容器placeable.placeRelative(x = 0, y = positionY)// positionY 更新高度,第一个元素的顶部到父容器顶部的距离为0;// 第二个元素顶部到父容器顶部的距离为 第一个元素的高度// 第三个元素顶部到父容器顶部的距离为 第一个元素的高度 + 第二个元的的高度positionY += placeable.height}}}
}@Composable
fun MyOwnColumnSample(){JetpackComposeLayoutsTheme() {MyOwnColumn {Text(text = "MyOwnColumn")Text(text = "places items")Text(text = "vertically.")Text(text = "We've done it by hand!")}}
}

StaggeredGrid

通过 StaggeredGrid 自定义如下布局

StaggeredGrid.kt

// 话题列表
val topics = listOf("Arts & Crafts","Beauty","Books","Business","Comics","Culinary","Design","Fashion","Film","History","maths"
)@Composable
fun StaggeredGrid(modifier: Modifier = Modifier,rows : Int = 3, //指定元素最终传进来,显示多少行。默认3行content : @Composable () -> Unit
){Layout(modifier = modifier,content = content){ measurables, constraints ->// rowWidths 用于保存每行的宽度值val rowWidths = IntArray(rows){ 0 }// rowHeights 用于保存每行的高度值val rowHeights = IntArray(rows){ 0 }// 测量元素,带索引val placeables = measurables.mapIndexed{index, measurable ->// 得到每一个元素val placeable = measurable.measure(constraints)// 计算当前元素该去到数组的那个位置,row = 0, 1, 2var row = index % rows// 每一行的宽度由每一个元素的宽度累加rowWidths[row] += placeable.width// 每一行的高度由每一行中最高的元素代表rowHeights[row] = max(rowHeights[row], placeable.height)placeable}// 计算表格的宽度,即为 rowWidth 中最宽的那一行// 计算表格的高度,即为 rowHeight 中元素之和。也就是rows列之和val gridWidth = rowWidths.maxOrNull() ?: constraints.minWidthval gridHeight = rowHeights.sumOf { it } // rowHeights 里所有元素相加// 设置每一行的 Y 坐标,每一行中的每一个元素的 Y 坐标是一样的val rowY = IntArray(rows){ 0 }// 第一列元素的 Y 坐标都0,第i行(i > 0)元素的 Y 坐标为前面 i - 1 行的高度之和for(i in 1 until rows){rowY[i] = rowY[i - 1] + rowHeights[i - 1]}// TODO 设置表格的宽高layout(gridWidth, gridHeight){//TODO 布局每一个元素,那么就要计算每一个元素的(x, y)坐标// 上面我们已经计算了每个元素的 Y坐标,TODO 这里还需计算每个元素的 X 坐标val rowX = IntArray(rows){ 0 }// 遍历每一个元素placeables.forEachIndexed{ index, placeable ->val row = index % rows// 每一列的第一个元素的 X 值都是0,所以直接先放置,然后再修改 rowX[row]placeable.placeRelative(x = rowX[row],y = rowY[row])// 修改 rowX[row]位置的值,为同一列中下一个元素计算 X 值,即前面元素的 宽度之和rowX[row] += placeable.width}}}}// TODO 每一个条目
@Composable
fun Chip(modifier: Modifier = Modifier,text : String
){// 一个卡片,圆角。里面包含一个 Row,第一列是 Box,第二列是 TextCard (modifier = modifier,border = BorderStroke(color = Color.Black, width = Dp.Hairline),// 设置边框线,Hairline默认1dpshape = RoundedCornerShape(8.dp) // 设置4个圆角) {Row(modifier = Modifier.padding(start = 8.dp, top = 4.dp, end = 8.dp, bottom = 4.dp),verticalAlignment = Alignment.CenterVertically,) {Box(modifier = Modifier.size(16.dp, 16.dp).background(color = MaterialTheme.colors.secondary))Spacer(modifier = Modifier.width(8.dp))Text(text = text)}}
}@Composable
fun StaggeredGridBodyContent(){Row(modifier = Modifier.background(color = Color.LightGray).padding(16.dp).horizontalScroll(rememberScrollState()), // 可以水平滚动content = {StaggeredGrid(modifier = Modifier) {// 放元素for(topic in topics){Chip(modifier = Modifier.padding(8.dp), text = topic)}}})
}

Activity.kt

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {JetpackComposeLayoutsTheme {//PhotographerCard()//LayoutStudy()//SampleList()//LazyList()//ScrollingList()//TextWithPaddingToBaseline()//MyOwnColumnSample()//StaggeredGrid()StaggeredGridBodyContent()}}}
}

约束布局

在实现对齐要求比较复杂的较大布局时,ConstraintLayout 很有用。 

引用

引用是使用 createRefs() 或 createRefFor() 创建的,ConstraintLayout 中的每个可组合项都需要有与之关联的引用。

约束条件

 约束条件是使用 constrainAs() 修饰符提供的,该修饰符将引用作为参数,可让你在主体 lambda 中指定其约束条件。

约束条件是使用 linkTo() 或其它有用的方法指定的。parent 是一个现有的引用,可用于指定对 ConstraintLayout 可组合项本身的约束条件。

案例1:用 ConstraintLayout 布局出如下效果。

1. 导入 ConstraintLayout 的依赖

implementation 'androidx.constraintlayout:constraintlayout-compose:1.0.0-alpha08'

2. ConstraintLayout.kt

@Composable
fun ConstraintLayoutContent(){// TODO 需要在 build.gradle 中引入依赖ConstraintLayout {//TODO 1. 通过 createRefs 创建引用,ConstraintLayout 中的每个元素都需要关联一个引用val (button, text) = createRefs()Button(onClick = { /*TODO*/ },//TODO 2.使用 Modifier.constrainAs 来提供约束,引用作为它的第一个参数// 在 lambda 表达式中指定约束规则modifier = Modifier.constrainAs(button){// TODO 3.约束条件是使用 linkTo(), parent.top表示在父容器顶部,有一个外边距 margintop.linkTo(parent.top, margin = 16.dp)}) {Text(text = "Button")}Text(text = "Text", modifier = Modifier.constrainAs(text) {// 约束条件是使用 linkTo(), button.bottom表示位于button 的底部,有一个外边距 margintop.linkTo(button.bottom, margin = 16.dp)// 在 ConstraintLayout 中水平居中centerHorizontallyTo(parent)})}
}

 案例2:

@Composable
fun ConstraintLayoutContent2(){ConstraintLayout {val (button1, button2, text) = createRefs()Button(onClick = {},modifier = Modifier.constrainAs(button1){top.linkTo(parent.top, margin = 16.dp)}) {Text(text = "Button1")}Text(text = "Text", modifier = Modifier.constrainAs(text) {// 约束条件是使用 linkTo(), button.bottom表示位于button 的底部,有一个外边距 margintop.linkTo(button1.bottom, margin = 16.dp)//TODO 在 text 的中间位置位于 boton1 的 end 位置centerAround(button1.end)})// 将 button1 和 text 组合起来,建立一个屏障val barrier = createEndBarrier(button1, text)Button(onClick = {  },modifier = Modifier.constrainAs(button2){//TODO top: 给顶部设置约束,start: 给左边设置约束top.linkTo(parent.top, margin = 16.dp)start.linkTo(barrier)}) {Text(text = "Button1")}}
}

解耦 API

在某些情况下,最好将约束条件与应用它们的布局分离开来。例如,我们可能会希望根据屏幕配置来更改约束条件,或在两个约束条件集之间添加动画效果。

\bullet 将 ConstraintSet 作为参数传递给 ConstraintLayout。

\bullet 使用 layoutId 修饰符将在 ConstraintSet 中创建的引用分配给可组合项。

如下代码所示:我们系统代码中 margin 是根据屏幕旋转时,动态设置的值,这种就不好弄了。

我们可以通过解耦的方式,将 Button 和 Text 组件之间的约束关系在外部定义,然后传入到 ConstraintLayout 中。而 margin 作为一个其它约束,就作为参数传递。如下代码所示

@Composable
fun DecoupledConstraintLayout2(){// 打包BoxWithConstraints {// maxWidth 和 maxHeight 是 BoxWithConstraints 中的属性val constrains = if(maxWidth < maxHeight){//TODO 返回的是一个 ConstraintSetDecoupledConstraints(16.dp) // 竖屏情况下}else{DecoupledConstraints(64.dp)// 横屏情况下}ConstraintLayout (constrains) {Button(onClick = { },modifier = Modifier.layoutId("button")) {Text(text = "Button")}Text(text = "Text", modifier = Modifier.layoutId("text"))}}
}// TODO 将Button 和 Text 的约束抽离到外部,
private fun DecoupledConstraints(margin : Dp) : ConstraintSet{return ConstraintSet{val button = createRefFor("button")val text = createRefFor("text")constrain(button){top.linkTo(parent.top, margin)}constrain(text){top.linkTo(button.bottom, margin)}}
}

Intrinsics

\bullet Compose 只测量子元素一次,测量两次会引发运行时异常。但是,有时在测量子元素之前,我们需要一些有关子元素的信息。

\bullet Intrinsics 允许你在实际测量之前查询子项。1)(min|max)intrinsicWidth:鉴于此高度,你可以正确绘制内容的最小/最大宽度是多少。2)(min|max)intrinsicHeight:鉴于此宽度,你可以正确绘制内容的最小/最大高度是多少。

示例:如下布局。要在中间做一个分割线,它的高度与左右文本的高度一致

@Composable
fun TwoTexts(modifier: Modifier = Modifier){// 将 Row 的高度限制为文本的高度,通过 Intrinsic 在测量之前来获取文本的高度信息Row (modifier = Modifier.height(IntrinsicSize.Min)) {Text(text = "Hi",modifier = Modifier.padding(start = 4.dp).weight(1f).wrapContentWidth(Alignment.Start))// 两个文本中间的线Divider(color = Color.Black,modifier = Modifier.fillMaxHeight() //fillMaxHeight()获取父容器最大高度.width(1.dp))Text(text = "There",modifier = Modifier.padding(start = 4.dp).weight(1f).wrapContentWidth(Alignment.End))}
}

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

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

相关文章

分享86个表单按钮JS特效,总有一款适合您

分享86个表单按钮JS特效&#xff0c;总有一款适合您 86个表单按钮JS特效下载链接&#xff1a;https://pan.baidu.com/s/1WwQGFPWv8464JBcuEMJZ_Q?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;…

spring boot学习第十二篇:mybatis框架中调用存储过程控制事务性

1、MySQL方面&#xff0c;已经准备好了存储过程&#xff0c;参考&#xff1a;MYSQL存储过程&#xff08;含入参、出参&#xff09;-CSDN博客 2、pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"…

SpringCloud--Eureka注册中心服务搭建注册以及服务发现

注意springboot以及springcloud版本&#xff0c;可能有莫名其妙的错误&#xff0c;这里使用的是springboot-2.6.13&#xff0c;springcloud-2021.0.5 一&#xff0c;Eureka-Server搭建&#xff1a; 1.创建项目&#xff1a;引入依赖 <dependency><groupId>org.sp…

[C/C++] -- Boost库、Muduo库编译安装使用

1.Muduo库 Muduo 是一个基于 C11 的高性能网络库&#xff0c;其核心是事件驱动、非阻塞 I/O、线程池等技术&#xff0c;以实现高并发、高性能的网络通信。Muduo 库主要由陈硕先生开发维护&#xff0c;已经成为 C 服务器程序员的常用工具之一。 Muduo 库的主要特点&#xff1a…

Javaweb之SpringBootWeb案例之事务管理的详细解析

1. 事务管理 1.1 事务回顾 在数据库阶段我们已学习过事务了&#xff0c;我们讲到&#xff1a; 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位。事务会把所有的操作作为一个整体&#xff0c;一起向数据库提交或者是撤销操作请求。所以这组操作要么同时成功&am…

MySQL数据库⑥_内置函数(日期函数+字符串函数+数学函数等)

目录 1. 日期函数 2. 字符串函数 3. 数学函数 4. 其它函数 本篇完。 1. 日期函数 MySQL常用的日期函数如下&#xff1a; 函数名称描述current_date()获取当前日期current_time()获取当前时间current_timestamp()获取当前时间戳now()获取当前日期时间date(datetime)获取d…

深度学习的进展及其在各领域的应用

深度学习&#xff0c;作为人工智能的核心分支&#xff0c;近年来在全球范围内引起了广泛的关注和研究。它通过模拟人脑的学习机制&#xff0c;构建复杂的神经网络结构&#xff0c;从大量数据中学习并提取有用的特征表示&#xff0c;进而解决各种复杂的模式识别问题。 一、深度…

百面嵌入式专栏(面试题)驱动开发面试题汇总1.0

沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍驱动开发面试题 。 1、Linux驱动程序的功能是什么? 对设备初始化和释放。进行内核与硬件的数据交互。检测和处理设备出现的错误。2、内核程序中申请内存使用什么函数? 答案:kmalloc()、kzalloc()、vm…

C++Linux网络编程day02:select模型

本文是我的学习笔记&#xff0c;学习路线跟随Github开源项目&#xff0c;链接地址&#xff1a;30dayMakeCppServer 文章目录 select模型fd_set结构体 timeval结构体文件描述符的就绪条件带外数据与普通数据socket的状态 select模型 select是Linux下的一个IO复用模型&#xff…

Flink基础篇|002_Flink前世今生

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者 &#x1f525; 三连支持&#xff1a;欢迎 ❤️关注、&#x…

latex双列排版下,插入表格但在单独一页出现,换页出现

问题描述&#xff1a; 在双列排版中&#xff0c;由于需要插入单列的整块表格&#xff0c;但表格出现在新的一页&#xff0c;如图&#xff1a; 解决&#xff1a; 注意是hb&#xff0c;不是htbp \begin{figure*}[hb] \centering \includegraphics[scale0.4]{img1.jpg} \caption…

2-2 动手学深度学习v2-损失函数-笔记

损失函数&#xff0c;用来衡量预测值和真实值之间的区别。是机器学习里面一个非常重要的概念。 三个常用的损失函数 L2 loss、L1 loss、Huber’s Robust loss 均方损失 L2 Loss l ( y , y ′ ) 1 2 ( y − y ′ ) 2 l(y,y^{\prime})\frac{1}{2}(y-y^{\prime})^{2} l(y,y′)21…

飞天使-k8s知识点14-kubernetes散装知识点3-Service与Ingress服务发现控制器

文章目录 Service与Ingress服务发现控制器存储、配置与角色 Service与Ingress服务发现控制器 在 Kubernetes 中&#xff0c;Service 和 Ingress 是两种不同的资源类型&#xff0c;它们都用于处理网络流量&#xff0c;但用途和工作方式有所不同。Service 是 Kubernetes 中的一个…

【Flink入门修炼】1-2 Mac 搭建 Flink 源码阅读环境

在后面学习 Flink 相关知识时&#xff0c;会深入源码探究其实现机制。因此&#xff0c;需要现在本地配置好源码阅读环境。 本文搭建环境&#xff1a; Mac M1&#xff08;Apple Silicon&#xff09;Java 8IDEAFlink 官方源码 一、 下载 Flink 源码 github 地址&#xff1a;h…

【设计模式】23中设计模式笔记

设计模式分类 模板方法模式 核心就是设计一个部分抽象类。 这个类具有少量具体的方法&#xff0c;和大量抽象的方法&#xff0c;具体的方法是为外界提供服务的点&#xff0c;具体方法中定义了抽象方法的执行序列 装饰器模式 现在有一个对象A&#xff0c;希望A的a方法被修饰 …

一、基础算法之排序、二分、高精度、前缀和与差分、双指针算法、位运算、离散化、区间合并内容。

1.快速排序 算法思想&#xff1a;选择基准元素&#xff0c;比基准元素小的放左边&#xff0c;比基准元素大的放右边。每趟至少一个元素排好。 每一趟实现步骤&#xff1a; low>high&#xff0c;返回&#xff0c;排序完成选取基准元素xa[low],ilow,jhigh当i<j时&#x…

ZOJ 3537 Cake 【区间DP + 凸多边形三角剖分】

Cake 题意 给定平面坐标上的 n n n 个点&#xff0c;如果是凸多边形的话&#xff0c;就用最少的花费把这个多边形剖分成若干个三角形&#xff0c;剖分的线段端点只能是原多边形的顶点&#xff0c;一条线段的花费为&#xff1a; ∣ x i x j ∣ ∣ y i y j ∣ m o d p |x_i…

部署一个在线OCR工具

效果 安装 1.拉取镜像 # 从 dockerhub pull docker pull mmmz/trwebocr:latest 2.运行容器 # 运行镜像 docker run -itd --rm -p 10058:8089 --name trwebocr mmmz/trwebocr:latest 使用 打开浏览器输入 http://192.168.168.110:10058/ 愉快滴使用吧

亚马逊认证考试系列 - 知识点 - LightSail介绍

一、引言 在当今云计算的时代&#xff0c;亚马逊网络服务&#xff08;AWS&#xff09;已成为业界领先的云服务提供商。其中&#xff0c;LightSail服务是AWS为简化云计算的入门和使用而推出的一项服务。它特别适合那些想要快速搭建网站、开发环境或小型应用的用户。通过LightSa…

Android Graphics 图像显示系统 - 开篇

“ 随着学习的不断深入和工作经验的积累&#xff0c;欲将之前在博客中整理的Android Graphics知识做进一步整理&#xff0c;并纠正一些理解上的错误&#xff0c;故开设Graphics主题系列文章 ” 序言 由于工作需要&#xff0c;也源于个人兴趣&#xff0c;终于下决心花时间整理一…