Compose的基本布局

Compose的基本布局

本篇博客参考博客

先看一下实现的效果

主要是由3个部分构成的,一个是上面那个搜索框(搜索框是死的,就是一个纯UI,只能看,文字都没办法输入);第二个是中间的,中间的又可以分为2部分,上面的那块是用LazyRow可以左右滑动,下面的是用LazyHorizontalGrid实现了两列的左右滑动(使用LazyHorizontalGrid的时候务必注意:你的kotlin版本必须特别高,否则用不了这个);最后是下面的底部导航栏(这个也是写死的东西,点击后不会有任何反应)。

顶部搜索框的实现

我们会用一个TextField,该组件的功能是

在Jetpack Compose中,TextField是用于输入和编辑文本的组件。可以将其理解为一个可编辑的文本框。当用户在TextField中输入时,输入的内容可以通过onValueChange回调函数捕获并进行处理。

最开始的时候只用TextField基本上什么也看不见,出现不了我最开始那张截图的效果,因为TextField的颜色和那个Search字没写并且没有那个搜索的Icon,我们只能自己加上去

value = "",
onValueChange = {},
leadingIcon = { Icon(imageVector = Icons.Default.Search, contentDescription = null) },
colors = TextFieldDefaults.textFieldColors(backgroundColor = MaterialTheme.colors.background),
placeholder = {
    Text("Search")
},
modifier = modifier
    .fillMaxWidth()
    .heightIn(min = 56.dp)

从这段代码中可以看出IconleadingIcon这里面控制的,搜索框的颜色是由colors控制的,

placeholder = {
    Text("Search")
},

是用来写那个Search

而那里面的

onValueChange = {},

是用来进行回调并处理的

具体什么意思呢?

最开始**value = “”**意思就是最开始那个搜索框的显示的就是空,如果你把它该值设置为

value ="nihao" ,

那么效果就是这样的

搜索框就会出现一个nihao

虽然搜索框上面写的是nihao但是因为前面

onValueChange = {},

所以我想读取搜索框输入了什么的时候,读取出来的一直都是"",然后会把onValueChange的值传回给value,然后value = “”,所以显示的就是空

搜索框的ui就基本结束了,但是我不想只要ui,我还想做到我输入什么东西,搜索框就能展示什么东西

搜索框显示text

TextField(
    var searchText by remember { mutableStateOf("") }
    value =searchText ,
    onValueChange = {searchText = it},
    leadingIcon = { Icon(imageVector = Icons.Default.Search, contentDescription = null) },
    colors = TextFieldDefaults.textFieldColors(backgroundColor = MaterialTheme.colors.background),
    placeholder = {
        Text("Search")
    },
    modifier = modifier
        .fillMaxWidth()
        .heightIn(min = 56.dp)
)

这段代码定义了一个可变状态变量searchText,它的初始值为空字符串""。这个可变状态变量是通过mutableStateOf函数来创建的。

mutableStateOf函数是Compose中的一个状态管理函数,用于创建可变的状态变量,并返回一个包含该变量的MutableState对象。在这个例子中,我们使用了remember修饰符,将这个可变状态变量保存在Composable函数的记忆中。这意味着,当Composable函数重新执行时,该变量的值会被保留下来,而不会被重置为初始值。

onValueChange = {searchText = it},

这段代码没太理解,但是chatgpt上说it表示当前文本字段中的新值

然后就没了

如果,我想让搜索框原先什么都没有,然后随便输入什么出来的结果都是12,怎么解决

 var searchText by remember { mutableStateOf("") }
    value =searchText ,
    onValueChange = {searchText = "12"},

和上面的代码差不多,但是我的onValueChange里面的代码改一下就行了

没办法放视频,到时候自己写一下就知道了

中间滑动的实现

上下两个其实差不多,甚至有一个函数我定义的都是一样的。就是下面比上面多了LazyHorizontalGrid,但当时弄这个把我弄的难受的呀。

LazyRow()

先说上面的:我主要用了

data class AlignYourBodyData(
    val drawable: Int,
    val text: String
)

这个是用来到时候保存图片和文字的

val alignYourBodyData = listOf(
    AlignYourBodyData(R.mipmap.saber, "Saber"),
    AlignYourBodyData(R.mipmap.archer, "Archer"),
    AlignYourBodyData(R.mipmap.lancer, "Lancer"),
    AlignYourBodyData(R.mipmap.caster, "Caster"),
    AlignYourBodyData(R.mipmap.rider, "Rider"),
    AlignYourBodyData(R.mipmap.assassin, "Assassin"),
    AlignYourBodyData(R.mipmap.berserker, "Berserker")
)

这就相当于一个数组或者一个集合保存了每张图片和文字

最后在LazyRow里面

items(alignYourBodyData) { item ->
    AlignYourBodyElement(item.drawable, item.text)
}

挨个在下面这个方法里面遍历

@Composable
fun AlignYourBodyElement(text: Int, s: String) {
    Column(
        modifier = Modifier,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            painter = painterResource(id = text), contentDescription = null,
            contentScale = ContentScale.Crop,//不加这句话,图片不是一个圆形
            //contentScale = ContentScale.Crop
            // 用于指定在将图像缩放到与卡片的宽度相同的同时,保留图像中心部分,以便显示一个“切片”效果的图像。
            modifier = Modifier
                .size(120.dp)
                .clip(CircleShape)
        )
        Text(
            text = s,
            fontStyle = Italic
        )

    }
}

这个方法就一个比较重要的

contentScale = ContentScale.Crop

如果没有这段代码的话,

 modifier = Modifier
                .size(120.dp)
                .clip(CircleShape)

这段代码是让图像变圆的,如果没有

contentScale = ContentScale.Crop

这段代码,图像就特别怪异

圆的两边像被砍了一刀

contentScale = ContentScale.Crop

chatgpt是这么解释的

contentScale 是一个用于指定如何缩放和裁剪显示内容的属性,它通常用于图片、视频等可缩放的内容。其中 ContentScale.Crop 是一个预定义的枚举值,表示将内容缩放并裁剪以填充目标框架,使其填满可用空间并完全填充。这通常意味着图片的宽高比可能会被裁剪,以便完全填充所用的空间。这与 ContentScale.FillBounds 相反,它会尽可能填充目标框架,但不会剪切内容。例如,如果目标框架的宽高比与内容的宽高比不同,那么内容可能会被留有空白区域。

我没怎么看懂,反正直接加上就对了

好,现在看下面的代码

LazyHorizontalGrid()

这个和LazyRow()很像,都是可以左右滑动。但是不一样,看我上面的上面的(n个上面的)截图可以看到,用LazyRow()的一列只有一个,但是LazyHorizontalGrid可以一列设置多个

LazyHorizontalGrid(
    rows = GridCells.Fixed(2),
    contentPadding = PaddingValues(horizontal = 16.dp),
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    verticalArrangement = Arrangement.spacedBy(15.dp),
    modifier = modifier.height(215.dp)
    //若不加最后这句最后界面有点点问题
) {
    items(favoriteCollectionsData) { item ->
        FavoriteCollectionCard(item.drawable, item.text)
    }
}

通过

rows = GridCells.Fixed(2),

可以设置一列有多少个,其他都没啥问题

但是但是,一般情况下最大的问题是你的**LazyHorizontalGrid()**显示不出来

当时候我只找到了LazyVerticalGrid(),找不到LazyHorizontalGrid(),原本以为是某个

implementation

没加上去,最后发现Android开发者文档说了,我的kotlin版本太低了,所以没有这个,得升级版本,然后我就把kotlin那个改成了

implementation 'androidx.compose.foundation:foundation:1.4.2'

然后又报错,这次好像还是直接红了,说的是compose_ui_versionorg.jetbrains.kotlin.android的版本号不统一还是啥的。

最后改成了compose_ui_version = '1.4.3’

id ‘org.jetbrains.kotlin.android’ version ‘1.8.10’ apply false

然后又说好像必须得Sdk 33才能用,然后又改,

然后将compileSdk 改成了33

,结果把minSdk也改成33了导致只能用安卓13及以上的用(后来改了)

终于终于,最后**LazyHorizontalGrid()**可以用了

底部导航栏

@Composable
fun SootheBottomNavigation() {
    BottomNavigation(
        modifier = Modifier,
        backgroundColor = MaterialTheme.colors.secondary
    ) {
        BottomNavigationItem(
            icon = {
                Icon(
                    imageVector = Icons.Default.Home,
                    contentDescription = null
                )
            },
            label = {
                Text("HOME")
            },
            selected = true, onClick = {})
        BottomNavigationItem(
            icon = {
                Icon(
                    imageVector = Icons.Default.AccountCircle,
                    contentDescription = null
                )
            },
            label = {
                Text("PROFILE")
            },
            selected = true, onClick = {})
    }
}

这个不太难,主要就是会用BottomNavigation设置底部导航栏的颜色BottomNavigationItem来设置对应的iconlabel

最重要也是最重要的,怎么让你的BottomNavigation位于界面的底部

Scaffold(bottomBar = { SootheBottomNavigation() }) { paddingValues ->
    HomeScreen(Modifier.padding(paddingValues))
}

SootheBottomNavigation()是刚才那个底部导航栏

亲测

HomeScreen(Modifier.padding(paddingValues))

中括号里面的东西可以不写

对了HomeScreen()就是除了底部导航栏以外的所有东西

这个讲完了compose的基本布局也就结束了

什么你问我[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-do529z1T-1683465549533)(../../assets/image-20230507211737273.png)]

还有下面[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cqcRFnUA-1683465549536)(../../assets/image-20230507211756887.png)]

为什么不讲一下,直接一个Text结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值