Jetpack Compose API 데이터를 목록 보기로

데이터를 가져오고 목록을 사용하여 해당 데이터를 표시하기 위해 API를 호출해야 하는 경우가 많습니다. 여기에서는 Compose로 이를 수행하는 방법을 보여줍니다. 응용 프로그램의 구조를 설명하기 위해 다음 다이어그램을 살펴보겠습니다.

먼저 AndroidManifest.xml에서 애플리케이션에 인터넷 권한을 추가합니다.

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


시작하기 전에 Retrofit HTTP 클라이언트 및 JSON과의 직렬화를 위해 Gson을 사용하는 aConverter로 build.gradle 파일을 업데이트하겠습니다.

dependencies{
...
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.0.0"
}


Todo API 서비스



네트워크 요청을 보내려면 Retrofit 인스턴스를 만들어야 합니다. Retrofit Builder 클래스를 사용하고 서비스의 기본 URL을 지정해야 합니다. 여기에 모든 Todo를 가져오고 목록으로 역직렬화하는 하나의 GET이 있습니다.

data class Todo(
    var userId: Int,
    var id: Int,
    var title: String,
    var completed: Boolean
)

const val BASE_URL = "https://jsonplaceholder.typicode.com/"

interface APIService {
    @GET("todos")
    suspend fun getTodos(): List<Todo>

    companion object {
        var apiService: APIService? = null
        fun getInstance(): APIService {
            if (apiService == null) {
                apiService = Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build().create(APIService::class.java)
            }
            return apiService!!
        }
    }
}


Todo 뷰모델



보기 모델은 todoList를 게시하고 모든 할일을 가져오는 데 사용할 보기에 대한 getTodoList 함수가 있습니다.

class TodoViewModel : ViewModel() {
    private val _todoList = mutableStateListOf<Todo>()
    var errorMessage: String by mutableStateOf("")
    val todoList: List<Todo>
        get() = _todoList

    fun getTodoList() {
        viewModelScope.launch {
            val apiService = APIService.getInstance()
            try {
                _todoList.clear()
                _todoList.addAll(apiService.getTodos())

            } catch (e: Exception) {
                errorMessage = e.message.toString()
            }
        }
    }
}


토도 뷰



마지막으로 할 일 목록 상태 변경에 대해 ViewModel을 감시하는 보기가 있습니다. 할 일 목록이 보기에 표시됩니다. 실행 시 보기에서 API를 호출합니다.

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        val vm = TodoViewModel()
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                TodoView(vm)
            }
        }
    }
}

@Composable
fun TodoView(vm: TodoViewModel) {

    LaunchedEffect(Unit, block = {
        vm.getTodoList()
    })

    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Row {
                        Text("Todos")
                    }
                })
        },
        content = {
            if (vm.errorMessage.isEmpty()) {
                Column(modifier = Modifier.padding(16.dp)) {
                    LazyColumn(modifier = Modifier.fillMaxHeight()) {
                        items(vm.todoList) { todo ->
                            Column {
                                Row(
                                    modifier = Modifier
                                        .fillMaxWidth()
                                        .padding(16.dp),
                                    horizontalArrangement = Arrangement.SpaceBetween
                                ) {
                                    Box(
                                        modifier = Modifier
                                            .fillMaxWidth()
                                            .padding(0.dp, 0.dp, 16.dp, 0.dp)
                                    ) {
                                        Text(
                                            todo.title,
                                            maxLines = 1,
                                            overflow = TextOverflow.Ellipsis
                                        )
                                    }
                                    Spacer(modifier = Modifier.width(16.dp))
                                    Checkbox(checked = todo.completed, onCheckedChange = null)
                                }
                                Divider()
                            }
                        }
                    }
                }
            } else {
                Text(vm.errorMessage)
            }
        }
    )
}


좋은 웹페이지 즐겨찾기