前言:我认为kotlin语言和前端三剑客本质上并无多大区别,都是写页面的语言。kotlin语言中使用了大量的语法糖来加速页面开发,这门语言的功能性较强
(一)
kotlin
data class ZhipuRequest(
val model: String = "glm-4v", // 使用具备视觉能力的模型
val messages: List<ZhipuMessage>
)
- 在class前定义data,那么这个类就会自动生成hashCode(),toString()等方法
- val在kotlin中是常量的意思,类比java中的final
- kotin的变量命名方式是"变量名:数据类型"
(二)
kotlin
val text: String? = null
- 定义text变量,数据类型是String
- String? 的意思是这个变量本身可能为空,= null是把text变量初始值设为null
(三)
kotlin
interface AiApiService {
@POST("chat/completions")
suspend fun analyzeResume(
@Header("Authorization") token: String, // 放入你的 API Key
@Body request: ZhipuRequest
): Response<ResponseBody> // 先用 ResponseBody 接收原始字符串,方便调试
}
- interface 接口名。定义一个接口
- @POST("chat/completions"),定义一个访问路径
- suspend表示异步
- fun表示定义一个函数,函数内是两个注解参数,第一个是在HTTP请求的请求头中添加一个Authorization字段,将String类型的token变量与这个键绑定,第二个是将ZhipuRequest类型的request对象转换成json数据,放入请求体中
- :Response< ResponseBody >,代表这个analyzeResume函数的返回值是一个Response< ReponseBody>类型的数据
(四)
kotlin
object RetrofitClient {
private const val BASE_URL = "https://open.bigmodel.cn/api/paas/v4/"
val instance: AiApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(AiApiService::class.java)
}
}
- Object{}:是一个匿名对象,当你需要这个对象,却又懒的写类名,并且复用的少的时候可以使用它
- by lazy{}:懒加载,软件初始化的时候先不创建它,等到需要用它的时候再创建它,这是为了降低页面初始化时间
- Retrofit:是一个处理网络请求的库,作为客户端访问AI的网络请求的请求中转站
- .Builder():构造器模式,优雅的创建对象
(五)
kotlin
(1..150).map {Question(id = it, title = "[$category] 第 $it 题", answer = "", category = category, passRate = "${(60..95).random()}%")
- (1...150):是一个语法唐,直观表示从1到150的区间
- map:不是一种数据结构,而是一个函数映射工具,负责将前面的数据(1...150)循环映射进后面的数据(Question类数据)
- it:是对(1...150)的每一个元素的别名,类似于Java中的
java
for (String s : Str){
s = "牛逼666"
}
的s变量
(六)
kotlin
@Composable
fun ProfileSectionCard(title: String, content: @Composable ColumnScope.() -> Unit) {
Card(modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors(containerColor = Color.White), shape = RoundedCornerShape(12.dp)) {
Column(modifier = Modifier.padding(16.dp)) {
Text(text = title, fontWeight = FontWeight.Bold, fontSize = 15.sp)
Spacer(modifier = Modifier.height(12.dp))
content()
}
}
}
- @Composable:组件注解,声明下方的方法会直接渲染组件在页面上
- content: @Composable ColumnScope.() -> Unit :接收一个content参数,也就是这个卡片的主体内容。.() 代表不接受任何参数,->Unit 代表没有任何返回值,只执行UI渲染操作 ColumnScope代表卡片的主体内容必须要按照竖直方向排列
- Card():代表接下来要创建一个卡片容器
- modifier :控制容器的长相,比如这里的
modifier = Modifier.fillMaxWidth()就是让Card这个卡片容器填满宽度
(七)
kotlin
Column(
modifier = Modifier.padding(16.dp)
) {
Text(text = title, fontWeight = FontWeight.Bold, fontSize = 15.sp)
Spacer(modifier = Modifier.height(12.dp))
content()
}
- Column:创建一个列容器
- Modifier.padding(16.dp):将这个容器的上下左右都与边界隔开16像素
- Column()后面的大括号:大括号里面的内容,就是在这个容器里面的东西,有Text文本,也有content()
- Spacer:创造一个间隔容器,将Text与content()内容空隔开12像素
(八)
kotlin
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
imageVector = icon,
contentDescription = null,
tint = color,
modifier = Modifier.size(40.dp)
)
Spacer(modifier = Modifier.height(12.dp))
Text(
text = title,
// 这里是关键:确保 fontWeight 与意向页保持一致
// 如果觉得太粗,就把 FontWeight.Bold 改为 FontWeight.SemiBold
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
fontSize = 16.sp
)
}
- Icon:创建一个标签
- verticalArrangemnet:表示该容器放置的位置是垂直居中
- horizontalAlignment :表示该容器放置的位置是水平居中
- tint:该标签的颜色
- style = MaterialTheme.typography.titleMedium:在全局的"样式"容器中获取所有"字体",titleMedium就是具体的名字
(九)
kotlin
@OptIn(ExperimentalMaterial3Api::class)
- @Optln :一种声明,是告诉编译器我现在要用一些正处在实验阶段的功能代码
- ExperimentalMaterial3Api:正处在实验性阶段的Material3库的API
- ::class:kotlin的类引用方式
(十)
kotlin
val backgroundPath = remember { Path() }
remember:捕捉Path()对象的变化,使得在页面刷新时能够一直保存Path的地址,不至于每次刷新都新创建一个Path对象
(十一)
kotlin
for (level in 1..3)
level就类似于Java中的
java
for(int i = 0; i < 5; i++){
}
的i
(十二)
java
backgroundPath.reset()
backgroundPath.close()
- .reset() :一键清空绘图板
- .close():关闭绘图板
(十三)
java
if (data.any { it > 0f })
.any: 自动遍历data列表,只要有一个元素满足括号里面的条件,就返回true,如果没有元素符合,那么就返回false
(十四)
kotlin
FileOutputStream(file).use { output -> input.copyTo(output) }
.use:就是让前面的对象执行后面大括号里的逻辑
Canvas:是供绘画的画布
Box:盒子容器
Button:按钮容器
Dialog:对话框
Colunm:内部进行列排放的容器
Row:内部进行横向排放的容器
scaffold:脚手架,也就是说这个容器内部预留了几个位置,例如bottomBar,
?.:如果前面的值不为空则执行后面的逻辑,例如:
kotlin
data?.split(",") -如果data不为空,则将data以","分割
?:: 如果前面的值为空,则赋入后面的值(或执行后面的逻辑),例如:
kotlin
ImageUtils.uriToBase64(context, resumeUri!!)?: return@launch 如果为空,则执行return@launch逻辑
return@launch:launch是一段协程,return@launch就是退出这个协程