002 Jetpack Compose基础组件学习

目录

1.Text组件

2.Button组件

3.TextField组件

4.Image组件


1.Text组件

Text组件就是原先的TextView组件,用法还是挺简单的,如下就是简单的Text用法:

package com.test.compose

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.test.compose.ui.theme.ComposeTestTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTestTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting("Compose")
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(
        text = "Hello $name!"
    )
}

上述的代码在真机显示效果就是Hello Compose!,如下:

 上述就是一个文字简单的使用,如果需要则是将Text中传参:

fun Text(
    text: String,                                        //文本内容
    modifier: Modifier = Modifier,                       //很复杂,参考:https://developer.android.google.cn/jetpack/compose/modifiers-list?hl=zh-cn 
    color: Color = Color.Unspecified,                    //文本颜色
    fontSize: TextUnit = TextUnit.Unspecified,           //文本大小 
    fontStyle: FontStyle? = null,                        //文本样式
    fontWeight: FontWeight? = null,                      //绘制文本时使用的字体粗细(例如 FontWeight.Bold)  
    fontFamily: FontFamily? = null,                      //渲染文本时使用的字体系列。请参阅 TextStyle.fontFamily。
    letterSpacing: TextUnit = TextUnit.Unspecified,      //每个字母之间添加的空格量。请参阅 TextStyle.letterSpacing。
    textDecoration: TextDecoration? = null,              //在文本上绘制的装饰(例如下划线)。请参阅 TextStyle.textDecoration。
    textAlign: TextAlign? = null,                        //段落行内文本的对齐方式。参见文本样式
    lineHeight: TextUnit = TextUnit.Unspecified,         //TextUnit 单位中段落的行高,例如SP 或 EM。请参阅 TextStyle.lineHeight。
    overflow: TextOverflow = TextOverflow.Clip,          //应如何处理视觉溢出。如果多余文字怎么处理,例如多余文字不显示
    softWrap: Boolean = true,                            //softWrap为false只能单行显示
    maxLines: Int = Int.MAX_VALUE,                       //最大行数,如果上面softWrap为false最大行数设置是无作用的
    onTextLayout: (TextLayoutResult) -> Unit = {},       //计算新文本布局时执行的回调。
    style: TextStyle = LocalTextStyle.current            //文本的样式配置,例如颜色、字体、行高等。
)

如上的字段设置后的显示效果:

2.Button组件

Button是非常常见的组件,使用也非常简单,就是将Button加进去即可,如下:

    Column() {
        Text(
            text = "Hello11111111111222222222111111111111111111111111111111111111111111111111111111111111 $name!",
            color = Color.Blue,     //字体颜色蓝色
            fontSize = 30.sp,       //字体大小30sp
            fontStyle = FontStyle.Italic,   //字体风格斜体
            fontWeight = FontWeight.Bold,   //字体加粗
            fontFamily = FontFamily.Cursive,//字体系列
            letterSpacing = 10.sp,          //文字间隔10sp
            textDecoration = TextDecoration.Underline,     //文字加下划线
            textAlign = TextAlign.End,       //段落右对齐
            lineHeight = 50.sp,              //每行高度,注意不是文字高度,是文字所在行高度
            overflow = TextOverflow.Ellipsis,    //超过行数多余部分文字截取并用...表示
            softWrap = true,                 //是否单行显示,true不是单行显示
            maxLines = 2                     //显示两行
        )
        Button(onClick = { /*TODO*/ }) {

        }
    }

如上代码显示效果:

 显示效果可以看出来是只有一个按钮没有文字的,如下是Button的详细传参:

fun Button(
    onClick: () -> Unit,                //点击事件
    modifier: Modifier = Modifier,      //同上,很复杂  
    enabled: Boolean = true,            //控制该按钮的启用状态。当为 false 时,该组件将不会响应用户输入,并且它将显示为视觉上禁用并且对辅助服务禁用。
    shape: Shape = ButtonDefaults.shape,//定义此按钮的容器、边框(当边框不为空时)和阴影(当使用高度时)的形状
    colors: ButtonColors = ButtonDefaults.buttonColors(),//ButtonColors 将用于解析此按钮在不同状态下的颜色。请参阅 ButtonDefaults.buttonColors。
    elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),//控制按钮下方阴影的大小
    border: BorderStroke? = null,        //围绕该按钮的容器绘制的边框
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,    //在容器和内容之间内部应用的间距值
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },//MutableInteractionSource 表示此按钮的交互流。您可以创建并传入您自己记住的实例来观察交互并自定义该按钮在不同状态下的外观行为。
    content: @Composable RowScope.() -> Unit
) {
//此处可以包装不同的组件,例如:Text
}
        Button(
            onClick = {
                Toast.makeText(context, "我被点击了!", Toast.LENGTH_SHORT).show()
            },
        ) {
            Text(text = "我是按钮")
        }

如上代码然后在手机上面显示交互过程如下:

3.TextField组件

TextField组件就是类似于原先的EditText组件,只不过使用上有所区别,如下是TextField的简单实现:
Column {
        ...
        TextField(value = "", onValueChange = {})
    }

如上的实现效果如下:

 然后从输入框输入文字发现没有任何反应,这就是和EditText最大的区别,由于Compose是状态驱动数据的模式,所以这里需要定义一个状态,然后赋值给TextField,具体这里就不详细说了,后面会继续详细说明这个状态的,然后我们将代码修改成下面这样:

    //用于记录文本输入框的输入的数据
    var inputText by remember {
        mutableStateOf("")
    }

    val context = LocalContext.current
    Column {
        ...
        TextField(value = inputText, onValueChange = {inputText = it})
    }

然后运行上面的代码,你可以发现此时可以输入内容了

然后我们详细说一下TextField的相关属性

fun TextField(
    value: String,                            //要在文本字段中显示的输入文本
    onValueChange: (String) -> Unit,          //输入服务(软键盘)更新文本时触发的回调。更新的文本作为回调的参数
    modifier: Modifier = Modifier,            //复杂,同上
    enabled: Boolean = true,                  //控制此文本字段的启用状态。当为 false 时,该组件将不会响应用户输入,并且它将显示为视觉上禁用并且对辅助服务禁用。
    readOnly: Boolean = false,                //控制文本字段的可编辑状态。如果为 true,则无法修改文本字段。但是,用户可以聚焦它并从中复制文本。只读文本字段通常用于显示用户无法编辑的预填写表单。
    textStyle: TextStyle = LocalTextStyle.current,    //要应用于输入文本的样式。默认为 LocalTextStyle。
    label: @Composable (() -> Unit)? = null,          //输入框文字提示(也不一定非要是文字),一直都在
    placeholder: @Composable (() -> Unit)? = null,    //输入框文字提示(也不一定非要是文字),输入文字后会消失
    leadingIcon: @Composable (() -> Unit)? = null,    //输入框左侧图标(也不一定非要是图标)
    trailingIcon: @Composable (() -> Unit)? = null,   //输入框右侧图标(也不一定非要是图标)
    supportingText: @Composable (() -> Unit)? = null, //下方的提示,可以是文字图标,isError为true可以变色提示
    isError: Boolean = false,        //是否输入有误
    visualTransformation: VisualTransformation = VisualTransformation.None,    //转换输入值的视觉表示形式 例如,您可以使用PasswordVisualTransformation 创建密码文本字段。默认情况下,不应用任何视觉变换。
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,    //软件键盘选项,包含 KeyboardType 和 ImeAction 等配置。
    keyboardActions: KeyboardActions = KeyboardActions.Default,    //当输入服务发出 IME 操作时,将调用相应的回调。请注意,此 IME 操作可能与您在 KeyboardOptions.imeAction 中指定的不同。
    singleLine: Boolean = false,    //当为 true 时,此文本字段将成为单个水平滚动文本字段,而不是换行到多行
    maxLines: Int = Int.MAX_VALUE,    //以最大可见行数表示的最大高度。应等于或大于 1。请注意,如果 singleLine 设置为 true,则该参数将被忽略,相反 maxLines 将设置为 1。
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },    //交互源 - MutableInteractionSource 表示此文本字段的交互流。您可以创建并传入您自己记住的实例来观察交互并自定义此文本字段在不同状态下的外观行为。
    shape: Shape = TextFieldDefaults.filledShape,        //定义此文本字段容器的形状
    colors: TextFieldColors = TextFieldDefaults.textFieldColors()    //TextFieldColors 将用于解析不同状态下此文本字段使用的颜色。
)

然后我们将绝大部分属性进行设置后的代码如下:

Column {
        TextField(
            value = inputText,
            onValueChange = { inputText = it },
            enabled = true,
            readOnly = false,
            label = {
                Text(
                    text = "账号"
                )
            },
            placeholder = {
                Text(text = "Type something here")
            },
            leadingIcon = {
                Icon(imageVector = Icons.Default.AccountBox, contentDescription = "左边的图标")
            },
            trailingIcon = {
                Icon(imageVector = Icons.Default.Edit, contentDescription = "左边的图标")
            },
            supportingText = {
                Text(
                    text = if (inputText == "error") {
                        "error"
                    } else {
                        ""
                    }
                )
            },
            isError = inputText == "error",
//            visualTransformation = PasswordVisualTransformation(),
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Ascii,
                imeAction = ImeAction.Done
            ),//输入英文字符,右下角是下一步操作
            keyboardActions = KeyboardActions(
                onDone = {
                    Toast.makeText(
                        context,
                        "onDone",
                        Toast.LENGTH_SHORT
                    ).show()
                },
                onGo = { Toast.makeText(context, "onGo", Toast.LENGTH_SHORT).show() },
                onNext = { Toast.makeText(context, "onNext", Toast.LENGTH_SHORT).show() },
                onPrevious = { Toast.makeText(context, "onPrevious", Toast.LENGTH_SHORT).show() },
                onSearch = { Toast.makeText(context, "onSearch", Toast.LENGTH_SHORT).show() },
                onSend = { Toast.makeText(context, "onSend", Toast.LENGTH_SHORT).show() }
            ),//imeAction点击的回调,不过要注意在其他厂商定制系统可能没有作用,比如我的小米手机就没有作用
            singleLine = false,
            maxLines = 3,//最多三行,多余的向下滚动
            shape = RoundedCornerShape(16.dp),//此处不生效
            colors = TextFieldDefaults.outlinedTextFieldColors(textColor = Color.Blue)
        )
        TextField(
            value = inputNumber,
            onValueChange = { inputNumber = it },
            shape = RoundedCornerShape(16.dp)//此处生效
        )
    }

尽量将所有属性都进行演示,上面的代码演示效果在最上面TextField演示效果,csdn真的挫,视频演示还不能在指定的位置。

4.Image组件

Image对应的是View当中的ImageView,也就是用于展示图片的,那么毫无疑问,这绝对又是一个必须掌握的常用控件。

好消息是,Image的用法还挺简单的,所以我们应该很快就可以上手了。

大家都知道,Android中的图片通常有两种比较常见的形式,一种是drawable资源,另一种是bitmap对象。Image对这两种形式的图片都提供了支持。

首先来看一下drawable资源形式的图片要如何加载,代码如下所示:

Column {
        ...
        Image(
            painter = painterResource(id = R.drawable.ic_launcher_foreground),
            contentDescription = "A launcher image"
        )
    }

上面的代码就可以显示出图片了,如下所示:

 Image参数列表上有两个必填参数,其中painter参数用于指定要展示的drawable资源,contentDescription参数用于指定对于这个资源的文字描述,然后来看下Image的参数列表:

Image(
    painter: Painter,        //显示的图片,必选项
    contentDescription: String?,    //图片的描述
    modifier: Modifier = Modifier,    
    alignment: Alignment = Alignment.Center,    //可选的对齐参数,用于将 Painter 放置在由宽度和高度定义的给定边界内。
    contentScale: ContentScale = ContentScale.Fit,    //可选缩放参数,用于确定在边界大小与 Painter 的固有大小不同时要使用的纵横比缩放
    alpha: Float = DefaultAlpha,        //当 Painter 在屏幕上渲染时,应用到 Painter 的可选不透明度默认使 Painter 完全不透明
    colorFilter: ColorFilter? = null,    //当 Painter 在屏幕上渲染时应用可选的 colorFilter
    filterQuality: FilterQuality = DefaultFilterQuality    //当位图缩放并绘制到目标时,采样算法应用于位图。默认值为 FilterQuality.Low,使用双线性采样算法进行缩放
)

尽量将上面的参数进行演示,但是有些参数还是看不出效果的,代码如下:

    Column {
        ...
        Image(
            painter = painterResource(id = R.drawable.ic_launcher_foreground),
            contentDescription = "A launcher image"
        )
        val bitmap: ImageBitmap =
            ImageBitmap.imageResource(id = android.R.drawable.ic_dialog_dialer)
        Image(
            modifier = Modifier
                .size(100.dp, 50.dp)//控件宽度100 高度50
                .background(Color.Green),//增加绿色背景
            bitmap = bitmap,//显示的图片,注意此处图片是ImageBitmap参数,如果是Bitmap需要进行转换
            contentDescription = "A dialer image",
            alignment = Alignment.BottomEnd,//右下角对齐
            contentScale = ContentScale.Inside,//显示在内部,图片不进行缩放
            alpha = 0.8.toFloat(),//图片透明度
            colorFilter = ColorFilter.lighting(Color.Black, Color.Cyan),//改变图片颜色
            filterQuality = FilterQuality.High//图片质量高
        )
    }

上面的参数演示效果如下:

到目前为止,我们展示的都是本地的图片资源。那么如果想要展示一张网络图片资源要怎么办呢?

很遗憾,Compose提供的Image是没有这个能力的,我们需要借助第三方依赖库才行。当然,ImageView也是没有这个能力的,所以我们以前也会使用Glide这样的第三方库。

目前Google比较推荐的第三方Compose图片加载库是Coil和Glide这两个。我知道大家看到Glide一定会感到非常亲切,可能更倾向于使用这个。但实际上Coil是一个基于协程开发的新兴图片加载库,用法更加贴合Kotlin也更加简单,因此我更推荐使用这个新库。

要使用Coil,首先需要将它引入到我们的项目当中:

dependencies {
    implementation "io.coil-kt:coil-compose:2.4.0"
}

然后在AndroidManifest中开启网络权限

<uses-permission android:name="android.permission.INTERNET" />

然后在代码中进行实现

Column {
        ...
        AsyncImage(
            model = "https://img-blog.csdnimg.cn/20200401094829557.jpg",
            contentDescription = "First line of code"
        )
    }

上面的代码演示效果如下:

 可以看出已经显示出网络加载的图片了

猜你喜欢

转载自blog.csdn.net/gongjdde/article/details/131709715