原文地址: Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝

本篇分别对常用的组件:图标(Icon) 按钮(Button) 输入框(TextField)的使用方法及各参数使用进行讲解,参考了不少文章,且费了不少时间去时间去一一实践,希望对各位带来些帮助

本系列以往文章请查看此分类链接jetpackcompose学习

图标Icon使用

Icon接收三种参数,如下图

//第一种就不多说,就是一个drawble对象

//获取图片资源,R.drawble.xx或R.mipmap.xx
Icon(painter = painterResource(id = R.drawable.head1_1024), null) //自带的图标
Icon(Icons.Filled.Search, null)

Compose内置了几十个常用的图标,我们使用枚举类型即可使用

Icons里面定了5种类型Outlined Filled Sharp TwoTone Rounded,可以根据自己的需要选择不同的类型,如填充型(Filled)或者是轮廓型(Outlined)

Icon的构造方法参数简单说明下

contentDescription是给无障碍人使用的文本描述,考虑到一些视觉障碍的人使用,所以有个这个属性,会使用TTS语音播放将contentDescription属性读出来,告知用户此按钮的作用

tint则是图标颜色的设置

Row() {
Icon(Icons.Outlined.Settings, contentDescription = null, tint = Color.Red)
Icon(Icons.Filled.Settings, contentDescription = null, tint = Color.Blue)
Icon(Icons.Sharp.Settings, contentDescription = null, tint = Color.Green)
Icon(Icons.TwoTone.Settings, contentDescription = null, tint = Color.Red)
Icon(Icons.Rounded.Settings, contentDescription = null, tint = Color.Black)
}

效果如下图所示

PS:具体的图标名称写的时候会有代码提示

不过默认常用的就那40几个,其他的图标就没有包含在内,当然,如果你想用的话,也有方法实现,需要导入material-icons-extended依赖即可

dependencies {
...
implementation "androidx.compose.material:material-icons-extended:$compose_version"
}

但是全套图标会导致打包后的apk文件过大,所以官方推荐使用导入图标文件的方法,详情可参考官方文档

按钮 Button

Button这个组件,官方已经实现了Material Design的效果,一般来说我们直接使用这个即可

除此之外,官方也是给我们封装了不同类型的Button,分别为IconButton TextButton OutlinedButton IconToggleButton

上面我们刚讲了图标,下面就先讲些图标按钮IconButton的使用方式吧

基本使用

和以往我们使用的按钮不一样,这里的按钮可以看做是一个布局控件,我们需要设置文字也就是往里面添加一个Text组件,这就是compose和传统Android的xml的不同之处

由上面这点,所以我们在代码层面就十分灵活,可以实现各种效果(如带有图标的按钮),下面来个例子

Button(onClick = { println("点击了按钮")}){
Icon(Icons.Default.Search,contentDescription = null)
Text(text = "测试")
}

上面的代码实现的效果就是有个图标在左侧

参数讲解

我们先看下Button的定义,其实封装好的方法,代码如下所示

fun Button(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
elevation: ButtonElevation? = ButtonDefaults.elevation(),
shape: Shape = MaterialTheme.shapes.small,
border: BorderStroke? = null,
colors: ButtonColors = ButtonDefaults.buttonColors(),
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
content: @Composable RowScope.() -> Unit
)

Buttoncontent参数(也就是上面lambda),传入多个组件,Button会将其按照水平方式排列(即Button可视为Row布局)

由于kotlin的语法特性,所以我们可以在后面以花括号写个lambda函数

这里先讲下比较简单的参数:

  • onClick是点击事件.也是接收一个函数
  • modifier是修饰符,本章先不使用,之后出个篇文章,专门讲解下这个的用法
  • enabled按钮是否可用(不可用默认是灰色,可用默认是蓝色),当然这里的默认的禁用和可用的颜色可可以调整,详情请见下面的colors参数

接下来就是稍微有点复杂的参数说明了,因为用法与之前原生Button有所区别,这里特别分成一小节讲解,方便目录查阅

1.elevation 阴影

Button的阴影参数是有有默认值的,我们也可以使用下面的方法进行数值的修改

ButtonDefaults.elevation(defaultElevation,pressedElevation,disabledElevation)
  • defaultElevation表示默认的阴影
  • pressedElevation表示按下时的阴影
  • disabledElevation表示未启用时候的阴影
Button(
enabled = true,
onClick = { /*TODO*/ },
elevation = ButtonDefaults.elevation(4.dp, 10.dp, 0.dp)
) {
Text(text = "阴影按钮")
} Button(
enabled = false,
onClick = { /*TODO*/ },
elevation = ButtonDefaults.elevation(4.dp, 10.dp, 0.dp)
) {
Text(text = "禁用状态的阴影按钮")
}

PS:使用的时候,发现导包会失败,给了些奇怪的东西...建议复制下ButtonDefaults.elevation(),再输入参数

2.shape 形状

Android官方给我们提供了以下四种形状,我从代码提示里只看到有这四种

  • RoundedCornerShape 圆角形状
  • CutCornerShape 切角形状
  • AbsoluteRoundedCornerShape 绝对圆角形状
  • AbsoluteCutCornerShape 绝对切角形状

这里从字面翻译知道其的意思,但是具体圆角形状和绝对圆角形状有什么区别,实际测试也有,但是没法看出来有什么区别,官方的文档也是解释的有点模糊

后来者如果知道,可以在评论区回复下,感谢~

上面四种类的接收参数其实是一样的,这里就截个图给大家看看

我们常用就是使用dp定位进行设置,如

RoundedCornerShape(10.dp) //设置10dp的圆角
RoundedCornerShape(topStart = 5.dp,topEnd = 6.dp,bottomEnd = 10.dp,bottomStart = 10.dp)
  • topStart 左上角
  • topEnd 右上角
  • bottomStart 左下角
  • bottomEnd 右下角

PS: 记住start是左,end是右,上面就比较好记了

Button(
onClick = { /*TODO*/ },
elevation = ButtonDefaults.elevation(4.dp, 10.dp, 0.dp),
shape = RoundedCornerShape(topStart = 5.dp,topEnd = 6.dp,bottomEnd = 10.dp,bottomStart = 10.dp) ) {
Text(text = "按钮")
}

我们可以实现如下图的效果

代码如下:

Modifier.size(50.dp,50.dp)是用来设置宽高的

Row() {
//固定长宽一样,圆角设置为50%即为圆形
Button(
modifier = Modifier.size(50.dp,50.dp),
onClick = { /*TODO*/ },
shape = RoundedCornerShape(50),
) {
Text(text = "")
} //固定长宽一样,切角设置为50%即为菱形
Button(
modifier = Modifier.size(50.dp,50.dp),
onClick = { /*TODO*/ },
shape = CutCornerShape(50.dp),
) {
Text(text = "")
} //左上角设置圆角
Button(
onClick = { /*TODO*/ },
shape = RoundedCornerShape(topStart = 20.dp),
) {
Text(text = "按钮")
} //圆角设置为50%
Button(
onClick = { /*TODO*/ },
shape = RoundedCornerShape(50),
border = BorderStroke(1.dp, Color.Green),
colors = ButtonDefaults.buttonColors(),
) {
Text(text = "按钮111")
} Button(
modifier = Modifier.size(50.dp,50.dp),
onClick = { /*TODO*/ },
shape = CutCornerShape(25),
border = BorderStroke(1.dp, Color.Green),
colors = ButtonDefaults.buttonColors(),
) {
Text(text = "按钮111")
} }

3.border 边框

边框就简单了,使用BorderStroke,接收两个参数,一个是边框的宽度,另外一个则是边框的颜色

BorderStroke(1.dp,color = Color.Black)
Button(
onClick = { /*TODO*/ },
elevation = ButtonDefaults.elevation(4.dp, 10.dp, 0.dp),
shape = RoundedCornerShape(topStart = 5.dp,topEnd = 6.dp,bottomEnd = 10.dp,bottomStart = 10.dp),
border = BorderStroke(1.dp, Color.Green)
) {
Text(text = "边框按钮")
}

4.colors 颜色

可以通过下面的方法进行颜色的参数的设置

ButtonDefaults.buttonColors(backgroundColor,contentColor,disabledBackgroundColor,disabledContentColor)
  • backgroundColor表示设置背景颜色
  • contentColor表示设置内容颜色这里比如说是登录文本的颜色
  • disabledBackgroundColor表示enable等于false的时候的背景颜色
  • disabledContentColor表示enable等于false时候的内容的颜色

PS:这个和之前的一样,直接导包会报错,使用复制大法ButtonDefaults.buttonColors()解决

5.contentPadding 内容内边距

contentPadding参数接收一个PaddingValues对象,这个对象的构造方法如下:

  • PaddingValues(all)
  • PaddingValues(horizontal: Dp, vertical: Dp)
  • PaddingValues(start: Dp = 0.dp,top: Dp = 0.dp,end: Dp = 0.dp,bottom: Dp = 0.dp)
PaddingValues(10.dp) //所有内边距为10dp

PaddingValues(10.dp,20.dp) //左右内边距ge10dp,上下内边距各20dp

PaddingValues(10.dp,15.dp,20.dp,25.dp) //左内边距10dp,上内边距15dp,右内边距20dp,下内边距25dp

6.interactionSource 状态变化

这个主要是用来按钮的状态说明,我们可以使用这个来达到动态切换按钮样式的效果(如按下按钮的样式效果,松开后按钮的样式),类似我们之前常用selector的xml文件给按钮设置样式

可以处理状态的,比如按下的时候什么效果,正常时候什么效果。类似之前再布局文件里写Selector

interactionSource是一个接口,我们需要使用其的实现类MutableInteractionSource

MutableInteractionSource中提供了三个属性用来获取状态

  • collectIsPressedAsState 按压状态
  • collectIsDraggedAsState 拖动状态
  • collectIsFocusedAsState 焦点状态

我们可以可以此状态来动态更改按钮的样式,如下面的代码

@Preview(showBackground = true)
@Composable
fun DefaultPreview2() { val myInteractionSource = remember {
MutableInteractionSource()
} val pressState = myInteractionSource.collectIsPressedAsState()
//如果是按压状态则是切角形状,否则则是圆角形状
val myShape = if(pressState.value) CutCornerShape(10.dp) else RoundedCornerShape(10.dp) Column(
Modifier.padding(20.dp)
) {
Button(
onClick = { /*TODO*/ },
//设置我们定义的shape
shape = myShape,
//设置创建的MutableInteractionSource对象
interactionSource = myInteractionSource
) {
Text("你好")
}
}
}

效果如下(要按住才会变化):

补充:

构造一个可观察的状态对象可以使用下面的三种方法,唯一有所区别的是,返回值不一样

val mutableState = remember { mutableStateOf(default) }
var value by remember { mutableStateOf(default) }
val (value, setValue) = remember { mutableStateOf(default) }

如下面有个例子:

val mutableState = remember { mutableStateOf("") } //mutableState是State<String>对象

var value by remember { mutableStateOf("") } //value是String对象
val (value, setValue) = remember { mutableStateOf("") }

一般选用by关键字的那种,代码就比较方便,如果是第一种的话,需要通过mutableState.value才能拿到其保存的数值

这里强烈建议看下官方的文档状态和Jetpack Compose

图标按钮IconButton

IconButton 可以帮助我们生成一个可点击的图标按钮,点击按钮默认会有水波涟漪的点击效果

IconButton(onClick = { /*TODO*/ }) {
Icon(Icons.Filled.Search, null)
}

其实这里里面也可以传多个组件,但是效果可能会变得怪怪的,所以我们就是按照规范来使用吧

TextButton

这个其实是扁平按钮,之前有个FlatButton,然后改名成这个了,用法和Button一样,就是样式有所调整

TextButton(onClick = { /*TODO*/ }) {
Icon(Icons.Default.Search,contentDescription = null)
Text(text = "测试")
}

OutlinedButton

这个的话,看效果觉得应该是带有边框的按钮,我们也可以根据实际需求改造

OutlinedButton(onClick = { /*TODO*/ }) {
Text(text = "测试")
}

TextField

TextField在第一篇登录页面也是有提及到,这里再深入了解下各个属性

TextField 实现分为两个级别:

1.TextField 是 Material Design 实现。我们建议您选择此实现,因为它遵循的是 Material Design 指南:

  • 默认样式为填充
  • OutlinedTextField 是轮廓样式版本

    2.BasicTextField 允许用户通过硬件或软件键盘编辑文字,但没有提供提示或占位符等装饰
TextField(value = "", onValueChange = {},label = {Text("用户名")})

OutlinedTextField(value = "", onValueChange = {},label = {Text("用户名")})

BasicTextField(value = "", onValueChange = {})

简单来说,就是BasicTextField是超级原生的输入框,其什么样式都没有,可以让我们进行高度的自定义,而TextFieldOutlinedTextField则是Android官方给我们封装好Material Design样式的控件

1.label

获得输入焦点,顶头的文字提示,接收一个组件的lambda表达式,一般传Text,示例代码如下

TextField(value = "", onValueChange = {},label = {Text("用户名")})

效果如下图所示

2.leadingIcon

输入框左边显示内容,leadingIcon接收来自一个组件的lambda表达式,可以是图标、文本或者其他组件

TextField(
value = text,
onValueChange = {
text = it
},
leadingIcon = {
Icon(Icons.Filled.Search, null)
},
)

3.trailingIcon

输入框右边的内容,和上面的leadingIcon一样的使用,这里不再赘述

PS:可以在右边放个x的图标,点击删除输入全部文本功能哦

4.singleLine

设置是否单行,接收一个boolean值

注: 此参数不能和maxLines参数联用

TextField(
value = text,
onValueChange = {
text = it
},
singleLine =true,
)

5.color

设置各种颜色,参数如下(参数真的多,应该够灵活了吧)

@Composable
fun textFieldColors(
// 输入的文字颜色
textColor: Color = LocalContentColor.current.copy(LocalContentAlpha.current), // 禁用 TextField 时,已有的文字颜色
disabledTextColor: Color = textColor.copy(ContentAlpha.disabled), // 输入框的背景颜色,当设置为 Color.Transparent 时,将透明
backgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = BackgroundOpacity), // 输入框的光标颜色
cursorColor: Color = MaterialTheme.colors.primary, // 当 TextField 的 isError 参数为 true 时,光标的颜色
errorCursorColor: Color = MaterialTheme.colors.error, // 当输入框处于焦点时,底部指示器的颜色
focusedIndicatorColor: Color = MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high), // 当输入框不处于焦点时,底部指示器的颜色
unfocusedIndicatorColor: Color = MaterialTheme.colors.onSurface.copy(alpha = UnfocusedIndicatorLineOpacity), // 禁用 TextField 时,底部指示器的颜色
disabledIndicatorColor: Color = unfocusedIndicatorColor.copy(alpha = ContentAlpha.disabled), // 当 TextField 的 isError 参数为 true 时,底部指示器的颜色
errorIndicatorColor: Color = MaterialTheme.colors.error, // TextField 输入框前头的颜色
leadingIconColor: Color = MaterialTheme.colors.onSurface.copy(alpha = IconOpacity), // 禁用 TextField 时 TextField 输入框前头的颜色
disabledLeadingIconColor: Color = leadingIconColor.copy(alpha = ContentAlpha.disabled), // 当 TextField 的 isError 参数为 true 时 TextField 输入框前头的颜色
errorLeadingIconColor: Color = leadingIconColor, // TextField 输入框尾部的颜色
trailingIconColor: Color = MaterialTheme.colors.onSurface.copy(alpha = IconOpacity), // 禁用 TextField 时 TextField 输入框尾部的颜色
disabledTrailingIconColor: Color = trailingIconColor.copy(alpha = ContentAlpha.disabled), // 当 TextField 的 isError 参数为 true 时 TextField 输入框尾部的颜色
errorTrailingIconColor: Color = MaterialTheme.colors.error, // 当输入框处于焦点时,Label 的颜色
focusedLabelColor: Color = MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high), // 当输入框不处于焦点时,Label 的颜色
unfocusedLabelColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium), // 禁用 TextField 时,Label 的颜色
disabledLabelColor: Color = unfocusedLabelColor.copy(ContentAlpha.disabled), // 当 TextField 的 isError 参数为 true 时,Label 的颜色
errorLabelColor: Color = MaterialTheme.colors.error, // Placeholder 的颜色
placeholderColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium), // 禁用 TextField 时,placeholder 的颜色
disabledPlaceholderColor: Color = placeholderColor.copy(ContentAlpha.disabled)
)

代码使用:

TextField(
value = text,
onValueChange = {
text = it
},
leadingIcon = {
Icon(Icons.Filled.Search, null)
},
colors = TextFieldDefaults.textFieldColors(
textColor = Color(0xFF0079D3),
backgroundColor = Color.Transparent
)
)

效果:

6.visualTransformation 视图变化

视图变化是我自己翻译出来的,也不知道准不准确,个人更倾向于理解成输入类型(inputType)

这个有点类似之前原生的inputType,可以改变输入的字符串(如密码或者是输入手机号时候多个-),不过官方目前只实现了PasswordVisualTransformation,其他的需要我们自定义

使用的话也很简单

var inputText by remember { mutableStateOf("") }

TextField(value = inputText, onValueChange = {value-> inputText= value},visualTransformation = PasswordVisualTransformation())

我们如果想实现Android那种带有个图标,点击可以显示密码的输入框,该怎么实现呢?

其实也很简单,设置个可观察的boolean值,点击图标改变数值即可,具体可参考下面代码


//密码内容
var inputText by remember { mutableStateOf("") }
//是否展示密码(默认是false)
var isShowPwd by remember { mutableStateOf(false) } //显示效果(true:显示内偶然你 false:显示密码的"*"好
val myVisualTransformation =
if (isShowPwd) VisualTransformation.None else PasswordVisualTransformation() TextField( value = inputText,
colors=TextFieldDefaults.textFieldColors(backgroundColor = Color.Transparent),
onValueChange = { value -> inputText = value },
visualTransformation = myVisualTransformation,
trailingIcon = {
//根据表示不同,显示不同的图标
if (isShowPwd) {
//当前是显示密码,则图标为眼睛
IconButton(onClick = {
//更改标志
isShowPwd = !isShowPwd
}) {
Icon(painter = painterResource(id = R.drawable.eye_show), null)
}
} else {
//当前是隐藏密码,则图标为眼睛禁止
IconButton(onClick = {
//更改标志
isShowPwd = !isShowPwd
}) {
Icon(painter = painterResource(id = R.drawable.eye_hide), null)
}
}
})

上面的两个图标是我自己去iconfont-阿里巴巴矢量图标库上找,效果如下:

补充(自定义VisualTransformation)

注意: 经过实践发现,这个只是改变了显示的数值而已,实际上你输入什么,保存的数值还是那个,单纯只是TextField没显示而已,不是很清楚这个操作,那这样是不能实现限制长度的功能,密码显示星号这种效果应该没啥问题

此功能有待讨论,或者是可能官方后面会更新长度限制等功能?

上面说到官方只实现了一个简单的密码输入类型,那如果我们想自定义该如何实现呢?

好在官方也是在API文档中给了个例子,可以实现输入信用卡号,以-隔开的效果

我们先看下官方的代码及效果(有点坑,官方只给出了一部分代码,稍微琢磨了一番才知道它是实现了VisualTransformation接口,并重写了filter()方法)

class CardVisualTransformation : VisualTransformation{
override fun filter(text: AnnotatedString): TransformedText {
// Making XXXX-XXXX-XXXX-XXXX string.
val trimmed = if (text.text.length >= 16) text.text.substring(0..15) else text.text
var out = ""
for (i in trimmed.indices) {
out += trimmed[i]
if (i % 4 == 3 && i != 15) out += "-"
} /**
* The offset translator should ignore the hyphen characters, so conversion from
* original offset to transformed text works like
* - The 4th char of the original text is 5th char in the transformed text.
* - The 13th char of the original text is 15th char in the transformed text.
* Similarly, the reverse conversion works like
* - The 5th char of the transformed text is 4th char in the original text.
* - The 12th char of the transformed text is 10th char in the original text.
*/
val creditCardOffsetTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (offset <= 3) return offset
if (offset <= 7) return offset + 1
if (offset <= 11) return offset + 2
if (offset <= 16) return offset + 3
return 19
} override fun transformedToOriginal(offset: Int): Int {
if (offset <= 4) return offset
if (offset <= 9) return offset - 1
if (offset <= 14) return offset - 2
if (offset <= 19) return offset - 3
return 16
}
} return TransformedText(AnnotatedString(out), creditCardOffsetTranslator)
}
}

之后我们将TextField设置为上面的对象,代码如下

//密码内容
var inputText by remember { mutableStateOf("") } //我们定义的卡号VisualTransformation
val myVisualTransformation = CardVisualTransformation() TextField(
value = inputText,
label={
Text(text = "卡号")
},
colors=TextFieldDefaults.textFieldColors(backgroundColor = Color.Transparent),
onValueChange = { value -> inputText = value },
visualTransformation = myVisualTransformation
)

效果如下:

可以看见,每输入4个字符,后面会自动加上-,且输入了16个字符后,就无法继续输入了,删除的时候,也会自动将-删除,我们分析下代码

//这里的text是之前提到的AnnotatedString类型
//最大程度过滤,只要16个字符,大于16个字符,后面的字符就忽略掉
val trimmed = if (text.text.length >= 16) text.text.substring(0..15) else text.text
//TextFiel显示的数据,满足条件即追加"-"
var out = ""
for (i in trimmed.indices) {
out += trimmed[i]
//最后个字符不需要加"-"(即中间每隔四个字符追加"-")
if (i % 4 == 3 && i != 15) out += "-"
}

接下来是实现了一个接口OffsetMapping

官方文档关于此类说明: 提供原始文本和转换文本(transformed text)之间的双向偏移映射

看到这里,相信各位对原理已经有了一定的了解,VisualTransformation这个类其实就是将原始文本转为转换文本,所以我们看到filter(text: AnnotatedString)最后是返回的一个TransformedText对象

val creditCardOffsetTranslator = object : OffsetMapping {
//原始文本对应的转换文本的下标映射
override fun originalToTransformed(offset: Int): Int {
if (offset <= 3) return offset
if (offset <= 7) return offset + 1
if (offset <= 11) return offset + 2
if (offset <= 16) return offset + 3
//转换文本最大长度为19
return 19
} //转换文本对应的原始文本下标映射
override fun transformedToOriginal(offset: Int): Int {
//4 9 14都是"-"的下标位置
if (offset <= 4) return offset
if (offset <= 9) return offset - 1
if (offset <= 14) return offset - 2
if (offset <= 19) return offset - 3
//原始文本的最大长度为16
return 16
}
}

映射这里稍微想下就明白了,如有个abcdefgh,其对应的转换文本就为abcd-efgh,其中,a-d是下标没变,都对应得上,但从e开始,由于多了个-,所以原始文本中e的下标为4,而在转换文本中,e的下标变为了5,后面的以此类推,反过来也是同理

我们根据官方的,改下手机号的,代码如下

class PhoneVisualTransformation : VisualTransformation{
override fun filter(text: AnnotatedString): TransformedText { val trimmed = if (text.text.length >= 11) text.text.substring(0,11) else text.text
var out = ""
for (i in trimmed.indices) {
out += trimmed[i]
if (i==2 || i==6 ) out += "-"
} // 147-9611-2406
// 14796112406
val creditCardOffsetTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (offset <= 2) return offset
if(offset<=6) return offset + 1
if (offset <= 11) return offset + 2
return 13
} override fun transformedToOriginal(offset: Int): Int {
if (offset <= 3) return offset
if (offset <= 8) return offset - 1
if (offset <= 14) return offset - 2
return 11
}
} return TransformedText(AnnotatedString(out), creditCardOffsetTranslator)
}
}

效果如下所示:

参考

Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用的更多相关文章

  1. Jetpack Compose学习(5)——从登录页美化开始学习布局组件使用

    原文:Jetpack Compose学习(5)--从登录页美化开始学习布局组件使用 | Stars-One的杂货小窝 本篇主要讲解常用的布局,会与原生Android的布局控件进行对比说明,请确保了解A ...

  2. Jetpack Compose学习(7)——MD样式架构组件Scaffold及导航底部菜单

    Jetpack Compose学习(7)--MD样式架构组件Scaffold及导航底部菜单 | Stars-One的杂货小窝 Compose给我们提供了一个Material Design样式的首页组件 ...

  3. Jetpack Compose学习(8)——State及remeber

    原文地址: Jetpack Compose学习(8)--State状态及remeber关键字 - Stars-One的杂货小窝 之前我们使用TextField,使用到了两个关键字remember和mu ...

  4. Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用

    原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ...

  5. Jetpack Compose学习(6)——关于Modifier的妙用

    原文: Jetpack Compose学习(6)--关于Modifier的妙用 | Stars-One的杂货小窝 之前学习记录中也是陆陆续续地将常用的Modifier的方法穿插进去了,本期就来详细的讲 ...

  6. Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)

    原文:Jetpack Compose学习(9)--Compose中的列表控件(LazyRow和LazyColumn) - Stars-One的杂货小窝 经过前面的学习,大致上已掌握了compose的基 ...

  7. Jetpack Compose学习(1)——从登录页开始入门

    原文地址:Jetpack Compose学习(1)--从登录页开始入门 | Stars-One的杂货小窝 Jetpack Compose UI在前几天出了1.0正式版,之前一直还在观望,终于是出了正式 ...

  8. Jetpack Compose学习(2)——文本(Text)的使用

    原文: Jetpack Compose学习(2)--文本(Text)的使用 | Stars-One的杂货小窝 对于开发来说,文字最为基础的组件,我们先从这两个使用开始吧 本篇涉及到Kotlin和DSL ...

  9. jquery ui 常用(一)(自动完成 | 标签页 | 折叠面板 | 带图标的按钮 | 日期选择器| )

    条件,引用3个文件 jquery-ui.min.css; jquery.min.js; jquery-ui.min.js. 一.自动完成 http://www.w3cschool.cc/jqueryu ...

随机推荐

  1. 【阅读笔记】Java核心技术卷一 #3.Chapter5

    5 继承 5.1 类.超类和子类 5.1.1 定义子类 超类(superclass)和子类(subclass), 基类(base class)和派生类(derived class), 父类(paren ...

  2. javascript获取焦点对象ID

    document.activeElement 方法:if(document.activeElement.id="textbox1") { }

  3. Hybrid接口

    目录 一.Hybrid接口 1.1 VLan的基本概念 1.2 Hybrid接口特点 1.3 Hybrid接口工作原理 1.4 Hybrid配置 一.Hybrid接口 1.1 VLan的基本概念 特点 ...

  4. JavaGUI画笔工具的使用

    JavaGUI画笔工具的使用 package GUI; import java.awt.*; public class TestPaint { public static void main(Stri ...

  5. Cookie和Session得使用理解

    Cookie 饼干 什么是Cokkie? 1.Cookie 翻译过来是饼干的意思. 2.Cookie 是服务器通知客户端保存键值对的一种技术. 3.客户端有了 Cookie 后,每次请求都发送给服务器 ...

  6. Spring学习03(Bean的自动装配)

    6.Bean的自动装配 6.1 自动装配说明 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean. Spring中bean的三种装配机 ...

  7. shell——sort、uniq、tr、cut和eval命令

    一.排序命令sort 以行位单位对文件内容进行排序,也可以根据不同的数据类型进行排序 格式:sort [选项] 参数 格式:cat file | sort 选项 1.2常用选项 选项说明 -f 忽略大 ...

  8. STP生成树的一些笔记

    一.STP概述 1.1.STP简介 交换网络环路主要由广播风暴.多帧复制和MAC地址表紊乱造成. 广播风暴:一个数据帧或包被传输到本地网段 (由广播域定义)上的每个节点就是广播:由于网络拓扑的设计和连 ...

  9. Linux 学习Shell一部分指令

    接下来就是shell命令的一些演示了 set (超级多的变量和系统默认值) echo $?查看上一条指令是否执行成功 返回0意味着成功,返回1意味着失败 echo 是个 env 设置变量 解释一下上面 ...

  10. PLSQL编程及存储过程的创建

    一.PLSQL的初步介绍 PLSQL是使sql具有处理过程的能力,可以分为三个部分:声明部分.可执行部分.异常处理部分 1.如何使用PLSQL打印Hello World! 在sqlplus里中打印   ...