0Pricing
Kotlin Academy · บทเรียน

จำลองสถานะ UI ด้วย Sealed Class

ใช้ sealed class แทนสถานะ UI ได้แก่ Loading, Success และ Error

จำลองสถานะ UI ด้วย Sealed Class เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

ปัญหาสถานะส่วนติดต่อผู้ใช้

หน้าจอส่วนติดต่อผู้ใช้มีหลายสถานะ ได้แก่ กำลังโหลด กำลังแสดงข้อมูล กำลังแสดงข้อผิดพลาด หรือว่างเปล่า การจัดการสถานะเหล่านี้ด้วยค่าบูลีน (isLoading, hasError) เปราะบาง คลาสแบบปิดผนึกช่วยแก้ปัญหานี้

นรกของค่าบูลีนแบบดั้งเดิม

การใช้ค่าบูลีนแยกกันหลายค่าทำให้เกิดสถานะที่เป็นไปไม่ได้
// Fragile: isLoading=true AND hasError=true is invalid
var isLoading = false
var hasError = false
var data: List<Item>? = null
// 8 combinations, most of which are invalid!

สถานะแบบปิดผนึก: มีเฉพาะสถานะที่ถูกต้อง

คลาสแบบปิดผนึกทำให้ไม่สามารถแทนสถานะที่ไม่ถูกต้องได้
sealed class UiState<out T>
object Loading : UiState<Nothing>()
data class Success<T>(val data: T) : UiState<T>()
data class Error(val message: String, val retryable: Boolean = true) : UiState<Nothing>()
object Empty : UiState<Nothing>()

การแสดงผลตามสถานะ

ใช้ when เพื่อแสดงส่วนติดต่อผู้ใช้ที่ถูกต้องสำหรับแต่ละสถานะ
fun render(state: UiState<List<Item>>) = when (state) {
    Loading -> showProgressBar()
    is Success -> showItems(state.data)
    is Error -> showError(state.message, state.retryable)
    Empty -> showEmptyView()
}

ViewModel ปล่อยสถานะ

ViewModel ปล่อยสถานะแบบปิดผนึกผ่าน StateFlow
class ItemViewModel : ViewModel() {
    private val _state = MutableStateFlow<UiState<List<Item>>>(Loading)
    val state: StateFlow<UiState<List<Item>>> = _state

    fun loadItems() = viewModelScope.launch {
        _state.value = Loading
        _state.value = try {
            Success(repository.getItems())
        } catch (e: Exception) {
            Error(e.message ?: "Unknown error")
        }
    }
}

การประกอบสถานะโดยมีเนื้อหาภายใน

ใช้สถานะแบบปิดผนึกทั่วไปเพื่อจัดการข้อมูลทุกชนิด
fun <T> loading(): UiState<T> = Loading
fun <T> success(data: T): UiState<T> = Success(data)
fun <T> error(msg: String): UiState<T> = Error(msg)

ตัวอย่างสถานะการแบ่งหน้า

คลาสแบบปิดผนึกเหมาะสำหรับจำลองสถานะของรายการที่แบ่งหน้าโดยธรรมชาติ
sealed class PageState
object Idle : PageState()
object FirstLoad : PageState()
data class Content(val items: List<Item>, val hasMore: Boolean) : PageState()
data class LoadingMore(val items: List<Item>) : PageState()
data class Error(val items: List<Item>?, val msg: String) : PageState()

การแปลงสถานะ

แปลงสถานะที่สำเร็จได้โดยไม่ต้องแตะต้องกรณีอื่น
fun <T, R> UiState<T>.mapData(transform: (T) -> R): UiState<R> = when (this) {
    is Success -> Success(transform(data))
    is Error -> this
    Loading -> Loading
    Empty -> Empty
}

การทดสอบด้วยสถานะแบบปิดผนึก

สถานะทดสอบได้ง่าย เพียงตรวจสอบว่ามีรูปแบบใดถูกปล่อยออกมา
@Test
fun testLoadingState() {
    viewModel.loadItems()
    assertEquals(Loading, viewModel.state.value)
}
@Test
fun testSuccessState() {
    viewModel.setData(listOf(item))
    assert(viewModel.state.value is Success)
}

สถานะรวมเทียบกับโฟลว์หลายรายการ

โฟลว์สถานะแบบปิดผนึกเพียงรายการเดียวสะอาดกว่าโฟลว์หลายรายการที่แยกกันและต้องรักษาให้สอดคล้องกัน
// Fragile: two flows must stay in sync
val loading = MutableStateFlow(false)
val error = MutableStateFlow<String?>(null)

// Clean: one sealed state
val state = MutableStateFlow<UiState<List<Item>>>(Loading)

การเพิ่มข้อมูลกำกับให้สถานะ

ชนิดย่อยแบบปิดผนึกสามารถเก็บข้อมูลกำกับที่เกี่ยวข้องได้
data class Error(
    val message: String,
    val code: Int = 0,
    val retryable: Boolean = true,
    val timestamp: Long = System.currentTimeMillis()
) : UiState<Nothing>()

ตรวจสอบอย่างรวดเร็ว

ปัญหาสำคัญใดที่แก้ได้ด้วยการจำลองสถานะส่วนติดต่อผู้ใช้ด้วยคลาสแบบปิดผนึก

ทบทวน

จำลองสถานะส่วนติดต่อผู้ใช้ด้วยคลาสแบบปิดผนึก ได้แก่ Loading, Success(ข้อมูล), Error(ข้อความ), Empty ใช้ when เพื่อแสดงผลแต่ละกรณี StateFlow เดียวที่มีชนิดแบบปิดผนึกดีกว่าค่าบูลีนหลายตัว บทถัดไป: การซ้อนลำดับชั้นแบบปิดผนึก

คำถามที่พบบ่อย

บทเรียน “จำลองสถานะ UI ด้วย Sealed Class” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “จำลองสถานะ UI ด้วย Sealed Class” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “จำลองสถานะ UI ด้วย Sealed Class”

ใช้ sealed class แทนสถานะ UI ได้แก่ Loading, Success และ Error คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “จำลองสถานะ UI ด้วย Sealed Class” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. sealed class กับ sealed interface: ควรใช้แบบใด
  2. when แบบครอบคลุมทุกกรณีกับลำดับชั้น Sealed
  3. จำลองสถานะ UI ด้วย Sealed Class
  4. การซ้อนและรวมลำดับชั้น Sealed
← กลับไปที่ Kotlin Academy