《Jetpack Compose从入门到实战》第三章 定制 UI 视图

news2024/11/28 1:21:42

在这里插入图片描述

目录

  • 配置颜色、字体与形状
    • Welcome Page
    • Login Page
    • Home Page
  • 主题
    • CompositionLocal

配置颜色、字体与形状

-ui.theme.Color.kt

val pink100 = Color(0xFFFFF1F1)
val pink900 = Color(0xFF3F2C2C)
val white = Color(0xFFFFFFFF)
val white850 = Color(0xD9FFFFFF)
val gray = Color(0xFF232323)
  • ui.theme.Type.kt
    先将Nunito Sans字体家族放入 res/font,再根据设计稿写代码
val nunitoSansFamily = FontFamily(
    Font(R.font.nunitosans_light, FontWeight.Light),
    Font(R.font.nunitosans_semibold, FontWeight.SemiBold),
    Font(R.font.nunitosans_bold, FontWeight.Bold)
)

val h1 = TextStyle(
    fontSize = 18.sp,
    fontFamily = nunitoSansFamily,
    fontWeight = FontWeight.Bold
)
val h2 = TextStyle(
    fontSize = 14.sp,
    letterSpacing = 0.15.sp,
    fontFamily = nunitoSansFamily,
    fontWeight = FontWeight.Bold
)
val subtitle1 = TextStyle(
    fontSize = 16.sp,
    fontFamily = nunitoSansFamily,
    fontWeight = FontWeight.Light
)
val body1 = TextStyle(
    fontSize = 14.sp,
    fontFamily = nunitoSansFamily,
    fontWeight = FontWeight.Light
)
val body2 = TextStyle(
    fontSize = 12.sp,
    fontFamily = nunitoSansFamily,
    fontWeight = FontWeight.Light
)
val button = TextStyle(
    fontSize = 14.sp,
    letterSpacing = 1.sp,
    fontFamily = nunitoSansFamily,
    fontWeight = FontWeight.SemiBold,
    color = white
)
val caption = TextStyle(
    fontSize = 12.sp,
    fontFamily = nunitoSansFamily,
    fontWeight = FontWeight.SemiBold
)
  • ui.theme/Shape.kt

Welcome Page

@Preview(showBackground = true)
@Composable
fun WelcomeTitle() {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxWidth()
    ) {
        Image(
            painter = rememberVectorPainter(image = ImageVector.vectorResource(id = R.drawable.ic_light_logo)),
            contentDescription = "weclome_logo",
            modifier = Modifier
                .wrapContentWidth()
                .height(32.dp)
        )
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(32.dp),
            contentAlignment = Alignment.BottomCenter
        ) {
            Text(
                text = "Beautiful home garden solutions",
                textAlign = TextAlign.Center,
                style = subtitle1,
                color = gray
            )
        }
    }
}

@Preview(showBackground = true)
@Composable
fun WelcomeButtons() {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxWidth()
    ){
        Button(
            onClick = { },
            modifier = Modifier
                .height(48.dp)
                .padding(horizontal = 16.dp)
                .fillMaxWidth()
                .clip(medium),
            colors = ButtonDefaults.buttonColors(backgroundColor = pink900)
        ) {
            Text(
                text = "Create account",
                style = button,
                color = white
            )
        }
        Spacer(modifier = Modifier.height(24.dp))
        TextButton(
            onClick = { },
        ) {
            Text(
                text = "Log in",
                style = button,
                color = pink900,
            )
        }
    }
}

@Preview(showBackground = true)
@Composable
fun LeafImage() {
    Image(
        painter = rememberVectorPainter(image = ImageVector.vectorResource(id = R.drawable.ic_light_welcome_illos)),
        contentDescription = "weclome_illos",
        modifier = Modifier
            .wrapContentSize()
            .padding(start = 88.dp)
    )
}

@Preview(showBackground = true)
@Composable
fun WelcomeContent() {
    Column(modifier = Modifier
        .fillMaxSize()
    ) {
        Spacer(Modifier.height(72.dp))
        LeafImage()
        Spacer(modifier = Modifier.height(48.dp))
        WelcomeTitle()
        Spacer(modifier = Modifier.height(40.dp))
        WelcomeButtons()
    }
}

@Composable
fun WelcomePage() {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(pink100)
    ) {
        Image(
            painter = rememberVectorPainter(image = ImageVector.vectorResource(id = R.drawable.ic_light_welcome_bg)),
            contentDescription = "weclome_bg",
            modifier = Modifier.fillMaxSize()
        )
        WelcomeContent()
    }
}

Login Page

@Preview(showBackground = true)
@Composable
fun TopText() {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        var keywordPre = "By Clicking below you agree to our".split(" ")
        var keywordPost = "and consent".split(" ")
        for (word in keywordPre) {
            Text(
                text = word,
                style = body2,
                color = gray,
            )
        }
        Text(
            text = "Terms of Use",
            style = body2,
            color = gray,
            textDecoration = TextDecoration.Underline
        )
        for (word in keywordPost) {
            Text(
                text = word,
                style = body2,
                color = gray,
            )
        }
    }
}

@Preview(showBackground = true)
@Composable
fun BottomText() {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.Center
    ) {
        Text(text = " to Our ",
            style = body2,
            color = gray
        )
        Text(text = "Privacy Policy.",
            style = body2,
            color = gray,
            textDecoration = TextDecoration.Underline
        )
    }
}

@Preview(showBackground = true)
@Composable
fun HintWithUnderline() {
    Column(
        modifier = Modifier.paddingFromBaseline(top = 24.dp, bottom = 16.dp)
    ){
        TopText()
        BottomText()
    }
}

@Preview(showBackground = true)
@Composable
fun LoginInputBox() {
    Column {
        OutlinedTextField(
            value = "",
            onValueChange = {},
            modifier = Modifier
                .fillMaxWidth()
                .height(56.dp)
                .clip(small),
            placeholder = {
                Text(
                    text = "Email address",
                    style = body1,
                    color = gray
                )
            }
        )
        Spacer(modifier = Modifier.height(8.dp))
        OutlinedTextField(
            value = "",
            onValueChange = {},
            modifier = Modifier
                .fillMaxWidth()
                .height(56.dp)
                .clip(small),
            placeholder = {
                Text(
                    text = "Password(8+ Characters)",
                    style = body1,
                    color = gray
                )
            }
        )
    }
}

@Preview(showBackground = true, showSystemUi = false)
@Composable
fun LoginTitle() {
    Text(
        text = "Log in with email",
        modifier = Modifier
            .fillMaxWidth()
            .paddingFromBaseline(top = 184.dp, bottom = 16.dp),
        style = h1,
        color = gray,
        textAlign = TextAlign.Center
    )
}

@Preview(showBackground = true)
@Composable
fun LoginButton() {
    Button(
        onClick = { },
        modifier = Modifier
            .height(48.dp)
            .fillMaxWidth()
            .clip(medium),
        colors = ButtonDefaults.buttonColors(backgroundColor = pink900)
    ) {
        Text(
            text = "Log in",
            style = button,
            color = white
        )
    }
}

@Composable
fun LoginPage() {
    Column(
        Modifier
            .fillMaxSize()
            .background(white)
            .padding(horizontal = 16.dp)
    ) {
        LoginTitle()
        LoginInputBox()
        HintWithUnderline()
        LoginButton()
    }
}

@Composable
@Preview
fun LoginPageLightPreview() {
    BloomTheme() {
        LoginPage()
    }
}

Home Page

val small = RoundedCornerShape(4.dp)
val medium = RoundedCornerShape(24.dp)

val shapes = Shapes(
    small = RoundedCornerShape(4.dp),
    medium = RoundedCornerShape(4.dp),
    large = RoundedCornerShape(0.dp)
)
data class ImageItem(val name: String, val resId: Int)

val bloomBannerList = listOf(
    ImageItem("Desert chic", R.drawable.desert_chic),
    ImageItem("Tiny terrariums", R.drawable.tiny_terrariums),
    ImageItem("Jungle Vibes", R.drawable.jungle_vibes)
)

val bloomInfoList = listOf(
    ImageItem("Monstera", R.drawable.monstera),
    ImageItem("Aglaonema", R.drawable.aglaonema),
    ImageItem("Peace lily", R.drawable.peace_lily),
    ImageItem("Fiddle leaf tree", R.drawable.fiddle_leaf),
    ImageItem("Desert chic", R.drawable.desert_chic),
    ImageItem("Tiny terrariums", R.drawable.tiny_terrariums),
    ImageItem("Jungle Vibes", R.drawable.jungle_vibes)
)

val navList = listOf(
    ImageItem("Home", R.drawable.ic_home),
    ImageItem("Favorites", R.drawable.ic_favorite_border),
    ImageItem("Profile", R.drawable.ic_account_circle),
    ImageItem("Cart", R.drawable.ic_shopping_cart)
)

@Preview(showBackground = true)
@Composable
fun BloomRowBanner() {
    Column {
        Box(
            Modifier.fillMaxWidth()
        ) {
            Text(
                text = "Browse themes",
                style = h1,
                color = gray,
                modifier = Modifier
                    .fillMaxWidth()
                    .paddingFromBaseline(top = 32.dp)
            )
        }
        Spacer(modifier = Modifier.height(16.dp))
        LazyRow(
            modifier = Modifier.height(136.dp)
        ) {
            items(bloomBannerList.size) {
                if (it != 0) {
                    Spacer(modifier = Modifier.width(8.dp))
                }
                PlantCard(bloomBannerList[it])
            }
        }
    }
}


@Preview(showBackground = true)
@Composable
fun BloomInfoList() {
    Column {
        Row(
            Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Text(
                text = "Design your home garden",
                style = h1,
                color = gray,
                modifier = Modifier.paddingFromBaseline(top = 40.dp)
            )
            Icon(
                painterResource(id = R.drawable.ic_filter_list),
                "filter",
                modifier = Modifier
                    .padding(top = 24.dp)
                    .size(24.dp)
            )
        }
        Spacer(modifier = Modifier.height(16.dp))
        LazyColumn(
            modifier = Modifier
                .fillMaxWidth(),
            contentPadding = PaddingValues(bottom = 56.dp)
        ) {
            items(bloomInfoList.size) {
                if (it != 0) {
                    Spacer(modifier = Modifier.height(8.dp))
                }
                DesignCard(bloomInfoList[it])
            }
        }
    }
}

@Preview(showBackground = true)
@Composable
fun SearchBar() {
    Box {
        TextField(
            value = "",
            onValueChange = {},
            modifier = Modifier
                .fillMaxWidth()
                .height(56.dp)
                .clip(RoundedCornerShape(4.dp))
                .border(BorderStroke(1.dp, Color.Black)),
            leadingIcon = {
                Icon(
                    painter = rememberVectorPainter(image = ImageVector.vectorResource(id = R.drawable.ic_search)),
                    contentDescription = "search",
                    modifier = Modifier.size(18.dp)
                )
            },
            placeholder = {
                Text(
                    text = "Search",
                    style = body1,
                    color = gray
                )
            },
            colors = TextFieldDefaults.outlinedTextFieldColors(
                backgroundColor = white,
                unfocusedBorderColor = white,
                focusedBorderColor = white,
            ),
        )
    }
}

@Composable
fun HomePage() {
    Scaffold(
        bottomBar = {
            BottomBar()
        }
    ) {
        Column(
            Modifier
                .fillMaxSize()
                .background(white)
                .padding(horizontal = 16.dp)
        ) {
            Spacer(modifier = Modifier.height(40.dp))
            SearchBar()
            BloomRowBanner()
            BloomInfoList()
        }
    }
}

@Composable
fun DesignCard(plant: ImageItem) {
    Row(
        modifier = Modifier.fillMaxWidth()
    ) {
        Image(
            painterResource(id = plant.resId),
            contentScale = ContentScale.Crop,
            contentDescription = "image",
            modifier = Modifier
                .size(64.dp)
                .clip(RoundedCornerShape(4.dp))
        )
        Spacer(modifier = Modifier.width(16.dp))
        Column {
            Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                Column {
                    Text(
                        text = plant.name,
                        style = h2,
                        color = gray,
                        modifier = Modifier.paddingFromBaseline(top = 24.dp)
                    )
                    Text(
                        text = "This is a description",
                        style = body1,
                        color = gray,
                        modifier = Modifier
                    )
                }
                Checkbox(
                    modifier = Modifier
                        .padding(top = 24.dp)
                        .size(24.dp),
                    checked = false,
                    onCheckedChange = {
                        // plant.enable = it
                    },
                    colors = CheckboxDefaults.colors(
                        checkmarkColor = white
                    )
                )
            }
            Divider(color = gray, modifier = Modifier.padding(top = 16.dp), thickness = 0.5.dp)
        }
    }
}


@Composable
fun PlantCard(plant: ImageItem) {
    Card(
        modifier = Modifier
            .size(136.dp)
            .clip(RoundedCornerShape(4.dp))
    ) {
        Column {
            Image(
                painterResource(id = plant.resId),
                contentScale = ContentScale.Crop,
                contentDescription = "image",
                modifier = Modifier
                    .fillMaxWidth()
                    .height(96.dp)
            )
            Box(
                Modifier
                    .fillMaxWidth()
                    .padding(start = 16.dp)
            ) {
                Text(
                    text = plant.name,
                    style = h2,
                    color = gray,
                    modifier = Modifier
                        .fillMaxWidth()
                        .paddingFromBaseline(top = 24.dp, bottom = 16.dp)
                )
            }
        }
    }
}

@Composable
fun BottomBar() {
    BottomNavigation(
        elevation = 16.dp,
        modifier = Modifier
            .fillMaxWidth()
            .height(56.dp)
            .background(pink100)
    ) {
        navList.forEach {
            BottomNavigationItem(
                onClick = {},
                icon = {
                    Icon(
                        painterResource(id = it.resId),
                        contentDescription = null,
                        modifier = Modifier.size(24.dp),
                    )
                },
                label = {
                    Text(
                        it.name,
                        style = caption,
                        color = gray,
                    )
                },
                selected = ("Home" == it.name)
            )
        }
    }
}

@Preview(showBackground = true)
@Composable
fun BottomBarPreview() {
    BloomTheme() {
        BottomBar()
    }
}

@Preview(showBackground = true)
@Composable
fun DesignCardPreview() {
    BloomTheme() {
        DesignCard(bloomInfoList[0])
    }
}

@Preview(showBackground = true)
@Composable
fun PlantCardPreview() {
    BloomTheme() {
        PlantCard(bloomBannerList[0])
    }
}

@Preview(showBackground = true)
@Composable
fun HomePageLightPreview() {
    BloomTheme() {
        HomePage()
    }
}

主题

private val BloomLightColorPaltte = lightColors(
    primary = pink100,
    secondary = pink900,
    background = white,
    surface = white850,
    onPrimary = gray,
    onSecondary = white,
    onBackground = gray,
    onSurface = gray,
)

private val BloomDarkColorPaltte = darkColors(
    primary = green900,
    secondary = green300,
    background = gray,
    surface = white150,
    onPrimary = white,
    onSecondary = gray,
    onBackground = white,
    onSurface = white850
)

open class WelcomeAssets private constructor(
    var background: Int,
    var illos: Int,
    var logo: Int
) {
    object LightWelcomeAssets : WelcomeAssets(
        background = R.drawable.ic_light_welcome_bg,
        illos = R.drawable.ic_light_welcome_illos,
        logo = R.drawable.ic_light_logo
    )

    object DarkWelcomeAssets : WelcomeAssets(
        background = R.drawable.ic_dark_welcome_bg,
        illos = R.drawable.ic_dark_welcome_illos,
        logo = R.drawable.ic_dark_logo
    )
}

internal var LocalWelcomeAssets = staticCompositionLocalOf { WelcomeAssets.LightWelcomeAssets as WelcomeAssets }

val MaterialTheme.welcomeAssets
    @Composable
    @ReadOnlyComposable
    get() = LocalWelcomeAssets.current

enum class BloomTheme {
    LIGHT, DARK
}


@Composable
fun BloomTheme(theme: BloomTheme = BloomTheme.LIGHT, content: @Composable() () -> Unit) {
    CompositionLocalProvider(
        LocalWelcomeAssets provides if (theme == BloomTheme.DARK) WelcomeAssets.DarkWelcomeAssets else WelcomeAssets.LightWelcomeAssets,
    ) {
        MaterialTheme(
            colors = if (theme == BloomTheme.DARK) BloomDarkColorPaltte else BloomLightColorPaltte,
            typography = bloomTypoGraphy,
            shapes = shapes,
            content = content
        )
    }
}

CompositionLocal

CompositionLocal 是 Jetpack Compose 中的一种数据传递方式。它可以在组合组件之间传递可变数据,而无需通过 props 或 state 管理器来传递数据。这个特性比传统的数据传递方式更为高效和方便。
例如,我们可以通过 CompositionLocal 在应用程序的不同部分中传递数据,如主题、语言环境、字体等。这个特性可以让我们在组合应用程序中更轻松地使用全局状态,而不必每次都传递数据。
此外,CompositionLocal 还可以用于实现本地化和自定义主题等功能的高效性。因此,它是 Jetpack Compose 中非常重要的一个组成部分。

  • 如果CompositonLocal提供得知发生更改的可能性很小或永远无法改变,利用staticCompositionLocal能显著提升性能

总结

  • 所有视图组件建议用顶级函数声明

随笔:

  • 简历 遇到什么问题,用了什么方法,如何进行优化

《Jetpack Compose从入门到实战》第一章 全新的 Android UI 框架

《Jetpack Compose从入门到实战》 第二章 了解常用UI组件

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

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

相关文章

朝着“强国建设民族复兴”之路奋勇前行

今(2023年10月1日)天,本“人民体验官”隆重推广人民日报官方微博文化产品《人民日报国庆社论#:坚定不移朝着强国建设、民族复兴的宏伟目标奋勇前进》。 图:来源“人民体验官”推广平台 以下推广今天的《人民日报》社论…

深度学习与python theano

文章目录 前言1.安装2.基本用法3.function用法4.shared 变量5.activation function6.Layer层7.regression 回归例子8.classification分类学习9.过拟合10.正则化11.save model12 总结 前言 本章主要介绍深度学习与python theano。 1.安装 2.基本用法 3.function用法 4.sha…

Linux系统编程系列之进程间通信-信号量组

一、什么是信号量组 信号量组是信号量的一种, 是system-V三种IPC对象之一,是进程间通信的一种方式。 二、信号量组的特性 信号量组不是用来传输数据的,而是作为“旗语”,用来协调各进程或者线程工作的。信号量组可以一次性在其内…

【Linux】 OpenSSH_9.3p1 升级到 OpenSSH_9.3p2(亲测无问题,建议收藏)

👨‍🎓博主简介 🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 🐋 希望大家多多支…

基于Python3搭建qt开发环境

Python可视化编程相信大部分刚接触都是tkinter,tkinter是Python自带的库,不需要安装第三方库即可使用,在我的Python专栏中也有很多基于tkinter来设计的可视化界面。本篇文章将尝试另外一个Python的可视化编程库(pyqt),与tkinter编…

深度剖析Linux磁盘分区 | LVM逻辑卷 | VDO卷 | AutoFS存储自动挂载

深度剖析Linux磁盘分区 | LVM逻辑卷 | VDO卷 | AutoFS存储自动挂载 前言说明1. 安装操作系统分区配置2. 大磁盘分区管理3. LVM逻辑卷管理3.1. 创建LVM逻辑卷3.1.1. 创建物理卷PV3.1.2. 创建卷组VG3.1.3. 创建逻辑卷LV3.1.4. 创建并挂载文件系统3.1.5. 配置开机自动挂载 3.2. 逻…

bypass disable_function 学习

LD_PRELOAD 我是在做了 buu的 REC ME 来做这个系列 所以 LD_PRELOAD 已经有了解了 我们来做这个题目 CTFHub Bypass disable_function —— LD_PRELOAD本环境来源于AntSword-Labs <!DOCTYPE html> <html> <head><title>CTFHub Bypass disable_func…

零基础Linux_9(进程)环境变量+进程地址空间+进程创建fork

目录 1. 环境变量 1.1 环境变量基本概念 1.2 环境变量PATH 1.3 环境变量HOME和SHELL 1.4 获取环境变量&#xff08;main函数参数&#xff09; 1.4.1 main函数第三个参数 1.4.2 设置普通变量和环境变量 1.4.3 main函数前两个参数 2. 进程地址空间 2.1 验证进程地址空…

技术Leader对下管理的法宝-SMART

SMART方法论 源于国外管理大师的《管理的实践》是管理者能够更加明确员工高效工作的利器&#xff0c;科学、规范的对员工绩效制定考核目标和考核标准5个单词缩写 Specific:目标要具体Measurable:目标成果要可衡量(量化) Attainable:目标要可实现&#xff0c;避免过高/过低Rel…

为什么字节大量用GO而不是Java?

见字如面&#xff0c;我是军哥。 我看很多程序员对字节编程语言选型很好奇&#xff0c;为此我还特地问了在字节的两位4-1的技术大佬朋友&#xff0c;然后加上自己的思考&#xff0c;总结了一下就以下 2 个原因&#xff1a; 1、 选型上没有历史包袱 字节的早期的程序员大多来自于…

OpenHarmony Trace的使用

背景&#xff1a; 近期很多开发者反馈OpenHarmony三方库Imageknife有性能问题&#xff1a;连续拖动很多张图片时&#xff0c;界面有明显的卡顿现象。 因为对这个三方库的源码并不了解&#xff0c;因此需要了解目前Imageknife渲染花费了多少时间&#xff0c;最初想的是只有通过…

不愧是疑问解决神器!你强任你强

不愧是疑问解决神器&#xff01;你强任你强&#x1f44d;&#x1f44d;&#x1f44d; 在过去&#xff0c;我习惯用这种方式来阅读书籍或文章&#xff1a;先快速浏览一遍&#xff0c;然后再进行复读&#xff0c;并最终总结所学的知识点。然而&#xff0c;长期以来&#xff0c;我…

VMware中虚拟机没网

VMware中虚拟机没网 1 打开服务2 还原虚拟机网络设置 1 打开服务 2 还原虚拟机网络设置 ————————————————————— 以上就是今日博客的全部内容了 创作不易,若对您有帮助,可否点赞、关注一二呢,感谢支持.

scrapy爬取图片

文章目录 ImagesPipeline使用步骤&#xff1a;1. 数据解析&#xff1a; 获取图片的地址 & 2. 将存储图片地址的item提交到指定的管道类&#xff08;hotgirls.py&#xff09;3. 在管道文件中自制一个基于ImagesPipeLine的一个管道类&#xff01;&#xff01;天大的坑 &#…

Linux常见操作命令(1)

​ 前言&#xff1a;作者也是初学Linux&#xff0c;可能总结的还不是很到位 ♈️今日夜电波&#xff1a;达尔文—林俊杰 0:30━━━━━━️&#x1f49f;──────── 4:06 &#x1f504; ◀️ …

容易理解的归并排序(C语言)

以二路归并为例&#xff0c;可简单理解为&#xff1a; 把一个大的数组拆分成两个数组&#xff0c;拆出来的两个数组再分别拆出两个数组&#xff0c;以此类推&#xff0c;直到每个数组只有一个元素。然后将这些只有一个元素的数组两两合并到一个临时数组&#xff0c;即可完成排序…

ffmpeg、ffplay在线安装,离线导出整个程序,移植到其他服务器使用(linux系统)

环境说明 以ubuntu系统作为说明 在线安装 下面命令会同时安装ffplay和ffmpeg sudo apt-get install ffmpeg怎么验证安装成功&#xff1f; 输入ffmpeg命令 ffmpeg&#xff0c;如图则说明安装成功 转储可执行程序和依赖的文件 找到安装路径&#xff0c;一般在/usr/bin目录…

Redis与分布式-哨兵模式

接上文 Redis与分布式-主从复制 1.哨兵模式 启动一个哨兵&#xff0c;只需要修改配置文件即可&#xff0c; sentinel monitor lbwnb 1247.0.0.1 6001 1先将所有服务关闭&#xff0c;然后修改配置文件&#xff0c;redis Master&#xff0c;redis Slave&#xff0c;redis Slave…

buuctf-[Zer0pts2020]Can you guess it?

点击source&#xff0c;进入源代码 <?php include config.php; // FLAG is defined in config.phpif (preg_match(/config\.php\/*$/i, $_SERVER[PHP_SELF])) {exit("I dont know what you are thinking, but I wont let you read it :)"); }if (isset($_GET[so…

nodejs缓存策略

nodejs缓存策略 缓存是一种强大的技术&#xff0c;可以显著提高nodejs应用程序的性能。 在现代Web应用程序中&#xff0c;性能和效率是直接影响用户体验和应用程序成功的关键因素。 通过将频繁访问的数据存储在缓存中&#xff0c;我们可以减少对昂贵的计算或外部API调用的需求…