Compose 布局

news2024/11/16 5:29:33

文章目录

  • Compose 布局
    • Column
      • Column属性
      • 使用
    • Row
      • Row属性
      • 使用
    • Box
      • Box属性
      • 使用
    • ConstraintLayout
    • LazyColumn
      • LazyColumn属性
      • 使用
      • 使用多类型
      • 使用粘性标题
      • 回到顶部
    • LazyRow
      • LazyRow属性
      • 使用
    • LazyVerticalGrid
      • LazyVerticalGrid属性
      • 使用

Compose 布局

Column

Compose中的”垂直线性布局“。

Column属性

@Composable
inline fun Column(
    // 修饰符
    modifier: Modifier = Modifier,
    // 子元素的垂直排列方式
    // Arrangement.Top:子元素靠近顶部
    // Arrangement.Center:子元素靠近中间
    // Arrangement.Bottom:子元素靠近底部
    // Arrangement.SpaceEvenly:子元素均匀分布,中间间隔是均匀分布的
    // Arrangement.SpaceAround:子元素均匀分布,子元素前后间隔是相同的
    // Arrangement.SpaceBetween:前后无间隔,子元素均匀分布
    // Arrangement.spacedBy:指定子元素间隔
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    // 子元素的水平对齐方式
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    content: @Composable ColumnScope.() -> Unit
) 

使用

简单使用:

在这里插入图片描述

Column(
    modifier = Modifier.fillMaxSize(),
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Text("one", color = Color.Red)
    Text("two", color = Color.Green)
    Text("three", color = Color.Blue)
}

使用Arrangement.SpaceEvenly:

在这里插入图片描述

@Composable
fun MyText(text: String) {
    Box(
        modifier = Modifier
            .size(150.dp)
            .background(Color.Gray),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text,
            fontSize = 30.sp
        )
    }
}

@Composable
fun MyColumn() {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.SpaceEvenly,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        MyText("one")
        MyText("two")
        MyText("three")
    }
}

使用Arrangement.SpaceAround:

在这里插入图片描述

@Composable
fun MyColumn() {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.SpaceAround,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        MyText("one")
        MyText("two")
        MyText("three")
    }
}

使用Arrangement.SpaceBetween:

在这里插入图片描述

@Composable
fun MyColumn() {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.SpaceBetween,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        MyText("one")
        MyText("two")
        MyText("three")
    }
}

使用Arrangement.spacedBy:

在这里插入图片描述

@Composable
fun MyColumn() {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.spacedBy(20.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        MyText("one")
        MyText("two")
        MyText("three")
    }
}

Row

Compose中的”水平线性布局“。

Row属性

@Composable
inline fun Row(
    // 修饰符
    modifier: Modifier = Modifier,
    // 子元素水平排列方式
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    // 子元素垂直对齐方式
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    content: @Composable RowScope.() -> Unit
) 

使用

在这里插入图片描述

@Composable
fun MyRow() {
    Row(
        modifier = Modifier.fillMaxSize(),
        horizontalArrangement = Arrangement.SpaceAround,
        verticalAlignment = Alignment.CenterVertically
    ) {
        MyText("one")
        MyText("two")
        MyText("three")
    }
}

Box

Compose中的”帧布局“。

Box属性

@Composable
inline fun Box(
    // 修饰符
    modifier: Modifier = Modifier,
    // 子元素对齐方式
    contentAlignment: Alignment = Alignment.TopStart,
    // 是否开启最小尺寸约束
    // 如果设置true,表示开启,则子元素会有最小尺寸约束
    propagateMinConstraints: Boolean = false,
    content: @Composable BoxScope.() -> Unit
)

使用

简单使用:

在这里插入图片描述

@Composable
fun MyBox() {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Row {
            Box(
                contentAlignment = Alignment.TopStart,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0xFF, 0, 0, 0xFF))
            ) {
                Text("1")
            }
            Box(
                contentAlignment = Alignment.TopCenter,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0xFF, 0, 0, 0x99))
            ) {
                Text("2")
            }
            Box(
                contentAlignment = Alignment.TopEnd,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0xFF, 0, 0, 0x33))
            ) {
                Text("3")
            }
        }
        Row {
            Box(
                contentAlignment = Alignment.CenterStart,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0, 0xFF, 0, 0xFF))
            ) {
                Text("4")
            }
            Box(
                contentAlignment = Alignment.Center,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0, 0xFF, 0, 0x99))
            ) {
                Text("5")
            }
            Box(
                contentAlignment = Alignment.CenterEnd,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0, 0xFF, 0, 0x33))
            ) {
                Text("6")
            }
        }
        Row {
            Box(
                contentAlignment = Alignment.BottomStart,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0, 0, 0xFF, 0xFF))
            ) {
                Text("7")
            }
            Box(
                contentAlignment = Alignment.BottomCenter,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0, 0, 0xFF, 0x99))
            ) {
                Text("8")
            }
            Box(
                contentAlignment = Alignment.BottomEnd,
                modifier = Modifier
                    .size(50.dp)
                    .background(Color(0, 0, 0xFF, 0x33))
            ) {
                Text("9")
            }
        }
    }
}

使用propagateMinConstraints:

在这里插入图片描述

@Composable
fun MyBox() {
    Box(modifier = Modifier.padding(10.dp)) {
        Box(
            modifier = Modifier
                .size(50.dp)
                .background(Color(0, 0, 0xFF)),
            propagateMinConstraints = true
        ) {
            Box(
                modifier = Modifier
                    .background(Color(0xFF, 0, 0)),
            ) {
                Text("aaa")
            }
        }
    }
}

说明:因为第2个Box开启了propagateMinConstraints = true,因此第3个Box有了最小约束也就是50x50,因此会填充父容器。

ConstraintLayout

Compose中的”约束布局“。

添加依赖库:

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

使用:

  • createRefs():创建多个引用。
  • createRef():创建一个引用。
  • constrainAs:定义约束。
  • linkTo:约束关系。

在这里插入图片描述

ConstraintLayout(modifier = Modifier.fillMaxSize()) {
    val (one, two) = createRefs()  
    val three = createRef() 
    DefaultText(text = "One", modifier = Modifier.constrainAs(one) {
        start.linkTo(parent.start)
        end.linkTo(parent.end)
        top.linkTo(parent.top, margin = 16.dp)
    })
    DefaultText(text = "Two", modifier = Modifier.constrainAs(two) {
        start.linkTo(parent.start)
        end.linkTo(parent.end)
        top.linkTo(one.bottom, margin = 16.dp)
    })
    DefaultText(text = "Three", modifier = Modifier.constrainAs(three) {
        start.linkTo(parent.start)
        end.linkTo(parent.end)
        bottom.linkTo(parent.bottom, margin = 16.dp)
    })
}

LazyColumn

Compose中的“垂直RecyclerView”。

LazyColumn属性

@Composable
fun LazyColumn(
    modifier: Modifier = Modifier, // 修饰符
    state: LazyListState = rememberLazyListState(), // 列表状态
    contentPadding: PaddingValues = PaddingValues(0.dp), // 内边距
    reverseLayout: Boolean = false, // 是否反转
    verticalArrangement: Arrangement.Vertical =
        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, // 垂直排列方式
    horizontalAlignment: Alignment.Horizontal = Alignment.Start, // 水平对齐方式
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), // fling逻辑
    userScrollEnabled: Boolean = true, // 是否开启滚动
    content: LazyListScope.() -> Unit
)
@LazyScopeMarker
@JvmDefaultWithCompatibility
interface LazyListScope {
    // 添加一个项目
    fun item(
        key: Any? = null,
        contentType: Any? = null,
        content: @Composable LazyItemScope.() -> Unit
    ) 

    // 添加多个项目
    fun items(
        count: Int,
        key: ((index: Int) -> Any)? = null,
        contentType: (index: Int) -> Any? = { null },
        itemContent: @Composable LazyItemScope.(index: Int) -> Unit
    )

    // 添加粘性标题
    @ExperimentalFoundationApi
    fun stickyHeader(
        key: Any? = null,
        contentType: Any? = null,
        content: @Composable LazyItemScope.() -> Unit
    )
}
// 通过List添加列表
inline fun <T> LazyListScope.items(
    items: List<T>,
    noinline key: ((item: T) -> Any)? = null,
    noinline contentType: (item: T) -> Any? = { null },
    crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit
) = items(
    count = items.size,
    key = if (key != null) { index: Int -> key(items[index]) } else null,
    contentType = { index: Int -> contentType(items[index]) }
) {
    itemContent(items[it])
}

// 通过List添加列表,含索引值
inline fun <T> LazyListScope.itemsIndexed(
    items: List<T>,
    noinline key: ((index: Int, item: T) -> Any)? = null,
    crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
    crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
) = items(
    count = items.size,
    key = if (key != null) { index: Int -> key(index, items[index]) } else null,
    contentType = { index -> contentType(index, items[index]) }
) {
    itemContent(it, items[it])
}

// 通过数组添加列表
inline fun <T> LazyListScope.items(
    items: Array<T>,
    noinline key: ((item: T) -> Any)? = null,
    noinline contentType: (item: T) -> Any? = { null },
    crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit
) = items(
    count = items.size,
    key = if (key != null) { index: Int -> key(items[index]) } else null,
    contentType = { index: Int -> contentType(items[index]) }
) {
    itemContent(items[it])
}

// 通过数组添加列表,含索引值
inline fun <T> LazyListScope.itemsIndexed(
    items: Array<T>,
    noinline key: ((index: Int, item: T) -> Any)? = null,
    crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
    crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
) = items(
    count = items.size,
    key = if (key != null) { index: Int -> key(index, items[index]) } else null,
    contentType = { index -> contentType(index, items[index]) }
) {
    itemContent(it, items[it])
}

使用

使用items:

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (index in 0..50) {
    dataList.add(index)
}

LazyColumn(modifier = Modifier.fillMaxSize()) {
    items(dataList) { data ->
        Text("hello $data")
    }
}

使用itemsIndexed:

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (index in 0..50) {
    dataList.add(index)
}

LazyColumn(modifier = Modifier.fillMaxSize()) {
    itemsIndexed(dataList) { index, data ->
        Text("hello $index $data")
    }
}

使用多类型

在这里插入图片描述

val chatList = arrayListOf<Chat>()
chatList.apply {
    add(Chat("hello"))
    add(Chat("world", false))
    add(Chat("apple"))
    add(Chat("orange"))
    add(Chat("banana"))
    add(Chat("List", false))
}

LazyColumn(modifier = Modifier
           .fillMaxSize()
           .padding(5.dp)) {
    items(chatList) { item ->
                     if (item.isLeft) {
                         Column(modifier = Modifier.padding(end = 15.dp)) {
                             Spacer(modifier = Modifier.height(5.dp))
                             Text(
                                 item.content,
                                 modifier = Modifier
                                 .fillMaxWidth()
                                 .height(25.dp)
                                 .background(Color.Green)
                             )
                         }
                     } else {
                         Column(modifier = Modifier.padding(start = 15.dp)) {
                             Spacer(modifier = Modifier.height(5.dp))
                             Text(
                                 item.content,
                                 modifier = Modifier
                                 .fillMaxWidth()
                                 .height(25.dp)
                                 .background(Color.Yellow)
                             )
                         }
                     }
    }
}

使用粘性标题

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (i in 0..30) {
    dataList.add(i)
}

LazyColumn(
    modifier = Modifier
    .fillMaxSize()
    .padding(5.dp)
) {
    stickyHeader {
        Text(
            "粘性标题一",
            modifier = Modifier
            .fillMaxWidth()
            .background(Color.Red),
            textAlign = TextAlign.Center
        )
    }
    items(dataList) { data ->
        Text("数据:$data")
    }
    stickyHeader {
        Text(
            "粘性标题二",
            modifier = Modifier
            .fillMaxWidth()
            .background(Color.Green),
            textAlign = TextAlign.Center
        )
    }
    items(dataList) { data ->
        Text("数据:$data")
    }
    stickyHeader {
        Text(
            "粘性标题三",
            modifier = Modifier
            .fillMaxWidth()
            .background(Color.Blue),
            textAlign = TextAlign.Center
        )
    }
    items(dataList) { data ->
        Text("数据:$data")
    }
}

回到顶部

  • firstVisibleItemIndex:可见区域的第一个项的索引值。
  • animateScrollToItem:移动到指定坐标。

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (i in 0..60) {
    dataList.add(i)
}

val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
val context = LocalContext.current

Box {
    LazyColumn(
        modifier = Modifier
        .fillMaxWidth()
        .padding(5.dp), state = listState
    ) {
        items(dataList) { data ->
            Text("数据:$data")
        }
    }

    Box(modifier = Modifier.matchParentSize(), contentAlignment = Alignment.BottomEnd) {
        Button(modifier = Modifier.wrapContentSize(), onClick = {
            coroutineScope.launch {
                listState.animateScrollToItem(0)
            }
        }) {
            Text("返回\n顶部")
        }
    }

    Box(modifier = Modifier.matchParentSize(), contentAlignment = Alignment.BottomCenter) {
        Button(modifier = Modifier.wrapContentSize(), onClick = {
            Toast.makeText(
                context, "firstVisibleItemIndex:${listState.firstVisibleItemIndex}", Toast.LENGTH_SHORT
            ).show()
        }) {
            Text("firstVisibleItemIndex")
        }
    }
}

LazyRow

Compose中的“水平RecyclerView”。

LazyRow属性

fun LazyRow(
    modifier: Modifier = Modifier, // 修饰符
    state: LazyListState = rememberLazyListState(), // 列表状态
    contentPadding: PaddingValues = PaddingValues(0.dp), // 内边距
    reverseLayout: Boolean = false, // 是否反转
    horizontalArrangement: Arrangement.Horizontal =
        if (!reverseLayout) Arrangement.Start else Arrangement.End, // 水平排列方式
    verticalAlignment: Alignment.Vertical = Alignment.Top, // 垂直对齐方式
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), // fling逻辑
    userScrollEnabled: Boolean = true, // 是否开启滚动
    content: LazyListScope.() -> Unit
) 

使用

在这里插入图片描述

val dataList = arrayListOf<Int>()
for (i in 0..60) {
    dataList.add(i)
}
LazyRow(
    modifier = Modifier
    .fillMaxWidth()
    .padding(5.dp)
) {
    items(items = dataList, key = { index -> index }) { data ->
         Text("数据:$data", modifier = Modifier.padding(10.dp))
    }
}

LazyVerticalGrid

Compose中的“垂直网格布局”。

LazyVerticalGrid属性

@Composable
fun LazyVerticalGrid(
    columns: GridCells, // 单元格
    modifier: Modifier = Modifier, // 修饰符
    state: LazyGridState = rememberLazyGridState(), // 网格状态
    contentPadding: PaddingValues = PaddingValues(0.dp), // 内边距
    reverseLayout: Boolean = false, // 是否反转
    verticalArrangement: Arrangement.Vertical =
        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, // 垂直排列方式
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, //水平对齐方式
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), // fling逻辑
    userScrollEnabled: Boolean = true, // 是否开启滚动
    content: LazyGridScope.() -> Unit
)

使用

定义5列:

在这里插入图片描述

val photoList = arrayListOf<Int>()
for (i in 0..20) {
    photoList.add(R.drawable.ic_launcher_background)
}
LazyVerticalGrid(columns = GridCells.Fixed(5)) {
    items(photoList) { photo ->
        Image(painterResource(id = photo), null, Modifier.padding(5.dp))
    }
}

定义网格最小100dp:

在这里插入图片描述

LazyVerticalGrid(columns = GridCells.Adaptive(100.dp)) {
    items(photoList) { photo ->
         Image(painterResource(id = photo), null, Modifier.padding(5.dp))
    }
}

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

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

相关文章

大型网站系统架构演化实例_4.数据库读写分离

1.数据库读写分离 网站在使用缓存后&#xff0c;使对大部分数据读操作访问都可以不通过数据库就能完成&#xff0c;但是仍有一部分操作&#xff08;缓存访问不命中、缓存过期&#xff09;和全部的写操作都需要访问数据库&#xff0c;在网站的用户达到一定规模后&#x…

制作一个RISC-V的操作系统十二-定时器中断

文章目录 CLINT定时器中断mtimemtimecmp机制总体框架流程时间节拍系统时钟代码 CLINT 产生软件中断和定时器中断 定时器中断 mtime 类似计数器&#xff0c;按照硬件对应的固定频率递增 上电后会自动复位为0&#xff0c;有硬件自动完成 mtimecmp 需要自己设置&#xff0…

C++相关概念和易错语法(8)(匿名对象、构造+拷贝构造优化、构造析构顺序)

1.匿名对象 当我们实例化对象后&#xff0c;有的对象可能只使用一次&#xff0c;之后就没用了。这个时候我们往往要主动去析构它&#xff0c;否则会占着浪费空间。但是如果遇到大量的这种情况&#xff0c;我们并不想每次都去创建对象、调用、析构&#xff0c;这样会写出很多重…

【Linux】对system V本地通信的内核级理解

一、system V版本的进程间通信技术 通过之前的学习&#xff0c;我们大致可以感受出来&#xff0c;共享内存&#xff0c;消息队列和信号量在使用的时候是有很多共性的。它们三个的接口&#xff0c;包括接口中传的参数有的都有很大的相似度。其实&#xff0c;共享内存&#xff…

大功率岸电电源技术研究及发展趋势

大功率岸电电源是一种利用海洋潮汐、波浪等可再生能源进行电能充电的设备&#xff0c;也称为海洋能充电器或潮汐能发电机。它通过接收潮汐、波浪等可再生能源&#xff0c;将可再生能源转换为电能进行充电&#xff0c;为港口、岛屿等地区提供清洁、高效的电力。大功率岸电电源对…

SpringSecurity源码4

SecurityContext.class 当前线程关联的最小安全信息&#xff0c;提供Authentication的get/set方法 SecurityContextHolder.class SecurityContext的持有器 // 全部委托给策略类public static void setContext(SecurityContext context) {strategy.setContext(context);}public …

算法课程笔记——蓝桥云课第二次直播

注意是‘’ 都正确 可以理解为a的首地址也是数字&#xff0c;向右1 %p逻辑地址 Cin cout字符串“”单个字符本身‘’&#xff0c;其他时候不用加 这样就可以 逆运算 bool比较真假<从小到大排 11/25 都输出最省事 变成长度为n1的数组 考虑到整个都可能为一个颜色&#xff0c;…

UML/SysML建模工具更新情况-截至2024年4月(1)5款-Trufun建模平台 v2024

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 工具最新版本&#xff1a;itemis CREATE 5.2.2 更新时间 2024年3月22日 工具简介 原名YAKINDU Statechart Tools。状态机建模工具&#xff0c;支持各种语言的代码生成&#xff0c;提…

Semaphore信号量源码解读与使用

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1. 前言 2. 什么是Semaphore&#xff1f; 3. Semaphore源码解读 3.1 acquire…

yml文件解析

.yml 后缀的文件可以有多个application.yml # 项目相关配置 用于 RuoYiConfig.java ruoyi:# 名称name: RuoYi# 版本version: 3.8.5# 版权年份copyrightYear: 2023# 实例演示开关demoEnabled: true# 文件路径 示例&#xff08; Windows配置D:/ruoyi/uploadPath&#xff0c;Lin…

SQLite的知名用户(二十九)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite作为应用程序文件格式&#xff08;二十八&#xff09; 下一篇:SQLite FTS5 扩展&#xff08;三十&#xff09; SQLite被数以百万计的应用程序使用 从字面上看&#xff0c;有数十亿次部署。 SQLite 是 当今世界。 下面…

C语言指针加法/减法

减法运算 指针的减法运算公式&#xff1a;就是两个指针的内存差值 / 指向的数据类型的内存空间大小 如果改变了指针类型指向的数据类型&#xff0c;对指针进行 - 运算&#xff0c;其新指向的位置只和转换后的数据类型有关 如果是char &#xff0c; 则指针指向变化1byte 如果…

【微服务】spring读取配置文件多种方式深入详解

目录 一、前言 二、java配置文件介绍 2.1 java配置文件产生原因 2.2 项目使用配置文件好处 2.3 springboot项目配置文件的必要性 2.4 微服务架构下配置文件使用场景 三、java读取配置文件常用方法 3.1 使用Properties类读取配置文件 3.1.1 使用getResourceAsStream读取…

【人工智能基础】知识表示和专家系统

目录 一、知识 知识 产生式表示法 产生式表示形式 确定的事实性知识的产生式表示 不确定的事实性知识的产生式表示 确定的规则知识的产生式表示 不确定的规则知识的产生式表示 产生式系统构成 优点 缺点 语义网络 优点 缺点 框架 框架的一般结构 框架的继承 优…

如何30天快速掌握键盘盲打

失业后在家备考公务员&#xff0c;发现了自己不正确的打字方式&#xff0c;决定每天抽出一点时间练习打字。在抖音上看到一些高手的飞速盲打键盘后&#xff0c;觉得使用正确的指法打字是很必要的。 练习打字&#xff0c;掌握正确的键盘指法十分关键。 练习打字的第一步是找到…

AJAX——ajax原理

1.XMLHttpRequest 定义&#xff1a;XMLHttpRequest&#xff08;XHR&#xff09;对象用于与服务器交互。通过XMLHttpRequest可以在不刷新页面的情况下请求特定URL&#xff0c;获取数据。这允许网页在不影响用户操作的情况下&#xff0c;更新页面的局部内容。XMLHttpRequest在AJA…

大话设计模式-里氏代换原则

里氏代换原则&#xff08;Liskov Substitution Principle&#xff0c;LSP&#xff09; 概念 里氏代换原则是面向对象设计的基本原则之一&#xff0c;由美国计算机科学家芭芭拉利斯科夫&#xff08;Barbara Liskov&#xff09;提出。这个原则定义了子类型之间的关系&#xff0…

MySQL之binlog归档日志

binlog&#xff08;二进制归档日志&#xff09; binlog 二进制日志记录保存所有执行过的修改操作语句&#xff0c;不保存查询操作。如果 MySQL 服务意外停止&#xff0c;可通过二进制日志文件排查&#xff0c;用户操作或表结构操作&#xff0c;从而来恢复数据库数据。启动 bin…

[BJDCTF 2020]encode

脱壳 rc4 自定义base64 异或

Make/Makefile详解

文章目录 make/MakefilemakeMakefile时间 make/Makefile Linux项目自动化构建工具。makefile定义了一系列的规则来指定&#xff0c;哪些文件需要先编译&#xff0c;哪些文件需要后编译&#xff0c;哪些文件需要重新编译&#xff0c;甚至进行更复杂的功能。makefile带来的好处就…