我对Jetpack Compose和Kotlin完全陌生,但对Java中的Android开发并不熟悉。想要第一次接触这两种技术,我想做一个非常简单的应用程序,用API中的文本填充LazyColumn。
如果我使用自定义日历来选择一周中的某一天,我希望与服务器通信,并从存储在一周中该天的数据接收响应,以将其与LazyColumn Composables关联。
我已经创建了TodoItem和TodoItemList函数,但是我问这个问题是因为我不知道如何通过与服务器通信和接收数据响应来连接这些值。
读取待办事项请求.kt
package com.example.todo_android.Request.TodoRequest
import com.example.todo_android.Response.TodoResponse.ReadTodoResponse
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Query
interface ReadTodoRequest {
@GET("/todo/todo/")
fun requestReadTodo(
@Header("Authorization") token: String,
@Query("year") year: Int,
@Query("month") month: Int,
@Query("day") day: Int
): Call<ReadTodoResponse>
}
读取到响应.kt
package com.example.todo_android.Response.TodoResponse
import com.google.gson.annotations.SerializedName
data class ReadTodoResponse(
@SerializedName("resultCode")
val resultCode: Int,
@SerializedName("data")
val data: ArrayList<RToDoResponse>
)
// 응답값으로 data의 디테일한 값들
data class RToDoResponse(
val id: Int,
val title: String,
val year: Int,
val month: Int,
val day: Int,
val done: Boolean,
val writer: String
)
待办事项.kt
package com.example.todo_android.Component
import android.provider.Settings.Global.getString
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.core.content.res.TypedArrayUtils.getString
import com.example.todo_android.Response.TodoResponse.ReadTodoResponse
import com.google.gson.JsonArray
import java.time.MonthDay
import java.time.Year
@Composable
fun TodoItem(Todo: ReadTodoResponse) {
Card(
modifier = Modifier
.padding(12.dp)
.fillMaxWidth()
.height(80.dp)
.background(color = Color.White)
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Text(
text = Todo.data.toString(),
)
}
}
}
@Composable
fun TodoItemList(Todo: List<ReadTodoResponse>) {
LazyColumn {
itemsIndexed(items = Todo) { index, item ->
TodoItem(Todo = item)
}
}
}
日历屏幕.kt
package com.example.todo_android.Screen
import android.util.Log
import androidx.compose.animation.*
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.example.todo_android.Component.TodoItemList
import com.example.todo_android.Data.Todo.CreateTodo
import com.example.todo_android.Data.Todo.ReadTodo
import com.example.todo_android.Data.Todo.UpdateTodo
import com.example.todo_android.Navigation.Action.RouteAction
import com.example.todo_android.Request.TodoRequest.CreateTodoRequest
import com.example.todo_android.Request.TodoRequest.DeleteTodoRequest
import com.example.todo_android.Request.TodoRequest.ReadTodoRequest
import com.example.todo_android.Request.TodoRequest.UpdateTodoRequest
import com.example.todo_android.Response.TodoResponse.CreateTodoResponse
import com.example.todo_android.Response.TodoResponse.DeleteTodoResponse
import com.example.todo_android.Response.TodoResponse.ReadTodoResponse
import com.example.todo_android.Response.TodoResponse.UpdateTodoResponse
import com.example.todo_android.Util.MyApplication
import com.himanshoe.kalendar.Kalendar
import com.himanshoe.kalendar.color.KalendarThemeColor
import com.himanshoe.kalendar.component.day.config.KalendarDayColors
import com.himanshoe.kalendar.model.KalendarDay
import com.himanshoe.kalendar.model.KalendarEvent
import com.himanshoe.kalendar.model.KalendarType
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
fun createTodo(token: String, year: String, month: String, day: String, title: String) {
var createTodoResponse: CreateTodoResponse? = null
var retrofit = Retrofit.Builder()
.baseUrl("https://plotustodo-ctzhc.run.goorm.io/")
.addConverterFactory(GsonConverterFactory.create())
.build()
var createTodoRequest: CreateTodoRequest = retrofit.create(CreateTodoRequest::class.java)
createTodoRequest.requestCreateTodo(token, CreateTodo(year, month, day, title))
.enqueue(object : Callback<CreateTodoResponse> {
// 실패 했을때
override fun onFailure(call: Call<CreateTodoResponse>, t: Throwable) {
Log.e("error", t.message.toString())
}
// 성공 했을때
override fun onResponse(
call: Call<CreateTodoResponse>,
response: Response<CreateTodoResponse>,
) {
createTodoResponse = response.body()
Log.d("createTodo", "token : " + MyApplication.prefs.getData("token", ""))
Log.d("createTodo", "resultCode : " + createTodoResponse?.resultCode)
Log.d("createTodo", "data : " + createTodoResponse?.data)
}
})
}
fun readTodo(token: String, year: Int, month: Int, day: Int) {
var readTodoResponse: ReadTodoResponse? = null
var retrofit = Retrofit.Builder()
.baseUrl("https://plotustodo-ctzhc.run.goorm.io/")
.addConverterFactory(GsonConverterFactory.create())
.build()
var readTodoRequest: ReadTodoRequest = retrofit.create(ReadTodoRequest::class.java)
readTodoRequest.requestReadTodo(token, year, month, day)
.enqueue(object : Callback<ReadTodoResponse> {
//실패할 경우
override fun onFailure(call: Call<ReadTodoResponse>, t: Throwable) {
Log.e("readTodo", t.message.toString())
}
//성공할 경우
override fun onResponse(
call: Call<ReadTodoResponse>,
response: Response<ReadTodoResponse>,
) {
readTodoResponse = response.body()
Log.d("readTodo", "token : " + MyApplication.prefs.getData("token", ""))
Log.d("readTodo", "resultCode : " + readTodoResponse?.resultCode)
Log.d("readTodo", "data : " + readTodoResponse?.data)
}
})
}
fun updateTodo(
token: String,
year: String,
month: String,
day: String,
title: String,
done: String,
) {
var updateTodoResponse: UpdateTodoResponse? = null
var retrofit = Retrofit.Builder()
.baseUrl("https://plotustodo-ctzhc.run.goorm.io/")
.addConverterFactory(GsonConverterFactory.create())
.build()
var updateTodoRequest: UpdateTodoRequest = retrofit.create(UpdateTodoRequest::class.java)
updateTodoRequest.requestUpdateTodo(token, UpdateTodo(year, month, day, title, done))
.enqueue(object : Callback<UpdateTodoResponse> {
// 실패 했을때
override fun onFailure(call: Call<UpdateTodoResponse>, t: Throwable) {
Log.e("updateTodo", t.message.toString())
}
// 성공 했을때
override fun onResponse(
call: Call<UpdateTodoResponse>,
response: Response<UpdateTodoResponse>,
) {
if (response.isSuccessful) {
updateTodoResponse = response.body()
Log.d("updateTodo", "token : " + MyApplication.prefs.getData("token", ""))
Log.d("updateTodo", "resultCode : " + updateTodoResponse?.resultCode)
Log.d("updateTodo", "data : " + updateTodoResponse?.data)
} else {
Log.e("updateTodo", "resultCode : " + response.body())
Log.e("updateTodo", "code : " + response.code())
}
}
})
}
fun deleteTodo(
token: String,
) {
var deleteTodoResponse: DeleteTodoResponse? = null
var retrofit = Retrofit.Builder()
.baseUrl("https://plotustodo-ctzhc.run.goorm.io/")
.addConverterFactory(GsonConverterFactory.create())
.build()
var deleteTodoRequest: DeleteTodoRequest = retrofit.create(DeleteTodoRequest::class.java)
deleteTodoRequest.requestDeleteTodo(token)
.enqueue(object : Callback<DeleteTodoResponse> {
// 실패 했을때
override fun onFailure(call: Call<DeleteTodoResponse>, t: Throwable) {
Log.e("updateTodo", t.message.toString())
}
// 성공 했을때
override fun onResponse(
call: Call<DeleteTodoResponse>,
response: Response<DeleteTodoResponse>,
) {
deleteTodoResponse = response.body()
Log.d("deleteTodo", "token : " + MyApplication.prefs.getData("token", ""))
Log.d("deleteTodo", "resultCode : " + deleteTodoResponse?.resultCode)
Log.d("deleteTodo", "data : " + deleteTodoResponse?.data)
}
})
}
@ExperimentalMaterial3Api
@Composable
fun CalendarScreen(routeAction: RouteAction) {
val states = listOf(
"월간",
"주간"
)
var selectedOption by remember { mutableStateOf(states[1]) }
val onSelectionChange = { text: String -> selectedOption = text }
var isVisible by remember { mutableStateOf(true) }
val token = "Token ${MyApplication.prefs.getData("token", "")}"
// val year = "2023"
// val month = "2"
// val day = "6"
// val token = "Token ${MyApplication.prefs.getData("token", "")}"
// val title = "qkrwhdwns"
// val done = "true"
var year by remember { mutableStateOf(0) }
var month by remember { mutableStateOf(0) }
var day by remember { mutableStateOf(0) }
val todoList = remember {
mutableStateListOf<ReadTodoResponse>()
}
val title = remember { mutableStateOf("") }
val done = remember { mutableStateOf("") }
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top
) {
Spacer(modifier = Modifier.height(15.dp))
Row(
modifier = Modifier
.clip(shape = RoundedCornerShape(24.dp))
.background(Color(0xffe9e9ed))
.padding(4.dp)
)
{
states.forEach { text ->
Text(
text = text,
color =
if (text == selectedOption) {
Color.Black
} else {
Color.Gray
},
fontWeight = FontWeight.Medium,
modifier = Modifier
.clip(shape = RoundedCornerShape(24.dp))
.clickable {
onSelectionChange(text)
isVisible = !isVisible
}
.background(
if (text == selectedOption) {
Color.White
} else {
Color(0xffe9e9ed)
}
)
.padding(
vertical = 5.dp,
horizontal = 16.dp,
)
)
}
}
Spacer(modifier = Modifier.height(29.dp))
AnimatedVisibility(isVisible)
{
Kalendar(
kalendarType = KalendarType.Oceanic(),
kalendarDayColors = KalendarDayColors(Color.Black, Color.Black),
kalendarThemeColor = KalendarThemeColor(
backgroundColor = Color.White,
dayBackgroundColor = Color(0xffFBE3C7),
headerTextColor = Color.Black),
onCurrentDayClick = { kalendarDay: KalendarDay, kalendarEvents: List<KalendarEvent> ->
year = kalendarDay.localDate.year
month = kalendarDay.localDate.monthNumber
day = kalendarDay.localDate.dayOfMonth
todoList.clear()
readTodo(token, year, month, day)
})
}
AnimatedVisibility(!isVisible) {
Kalendar(
kalendarType = KalendarType.Firey,
kalendarDayColors = KalendarDayColors(Color.Black, Color.Black),
kalendarThemeColor = KalendarThemeColor(
backgroundColor = Color.White,
dayBackgroundColor = Color(0xffFBE3C7),
headerTextColor = Color.Black),
onCurrentDayClick = { kalendarDay: KalendarDay, kalendarEvents: List<KalendarEvent> ->
year = kalendarDay.localDate.year
month = kalendarDay.localDate.monthNumber
day = kalendarDay.localDate.dayOfMonth
todoList.clear()
readTodo(token, year, month, day)
})
}
Spacer(modifier = Modifier.height(29.dp))
Text(text = day.toString())
TodoItemList(Todo = todoList)
// Scaffold(floatingActionButton = {
// FloatingActionButton(onClick = { /*TODO*/ }) {
// Icon(imageVector = Icons.Default.Add, contentDescription = "todolist 추가")
// }
// }) {
// LazyColumn {
// TodoItem()
// }
// }
// Surface(
// shape = RoundedCornerShape(24.dp),
// modifier = Modifier
// .wrapContentSize()
// ) {}
// Button(
// modifier = Modifier
// .width(300.dp)
// .height(50.dp),
// colors = ButtonDefaults.buttonColors(Color(0xffFFBE3C7)),
// onClick = { readTodo(token, year, month, day) }
// ) {
// Text(text = "TODO 조회", color = Color.Black)
// }
//
// Spacer(modifier = Modifier.height(30.dp))
//
// Button(
// modifier = Modifier
// .width(300.dp)
// .height(50.dp),
// colors = ButtonDefaults.buttonColors(Color(0xffFFBE3C7)),
// onClick = { createTodo(token, year, month, day, title) }
// ) {
// Text(text = "TODO 작성", color = Color.Black)
// }
//
// Spacer(modifier = Modifier.height(30.dp))
//
// Button(
// modifier = Modifier
// .width(300.dp)
// .height(50.dp),
// colors = ButtonDefaults.buttonColors(Color(0xffFFBE3C7)),
// onClick = { updateTodo(token, year, month, day, title, done) }
// ) {
// Text(text = "TODO 수정", color = Color.Black)
// }
//
// Spacer(modifier = Modifier.height(30.dp))
//
// Button(
// modifier = Modifier
// .width(300.dp)
// .height(50.dp),
// colors = ButtonDefaults.buttonColors(Color(0xffFFBE3C7)),
// onClick = { deleteTodo(token) }
// ) {
// Text(text = "TODO 삭제", color = Color.Black)
// }
}
}
1条答案
按热度按时间brvekthn1#
有几件事可能会有帮助。
1.您可以在
@Composable
中使用val scope = rememberCoroutineScope()
来创建一个协程作用域,在@Composable dispose时将自动取消作业。1.对于列表,如果希望在列表大小变化时刷新界面,可以选择
val todos = remember { mutableStateListOf<String>() }
,这样调用todos.add
就可以成功更新界面。1.如果你想在你的
TodoItem
中修改todos
,你可以这样写:希望这能帮到你!