Sobes.tech
Middle

Ako správne organizovať prácu s používateľským rozhraním na Android?

sobes.tech AI

Odpoveď od AI

Za organizáciu práce s používateľským rozhraním na Androidu by ste mali dodržiavať princípy architektúry a odporúčania Google.

Hlavné komponenty a prístupy:

  • Activity/Fragment: Sú to vstupné body pre používateľskú interakciu, obsahujú logiku zobrazenia (View).

  • View Binding/Data Binding: Mechanizmy pre bezpečnejší a pohodlnejší prístup k prvkom UI, znižujúce množstvo kódu a potenciálne chyby. View Binding sa odporúča pre jednoduché prípady, Data Binding pre zložitejšie scenáre s priameho viazaním dát v markup.

    <!-- res/layout/activity_main.xml (príklad s View Binding) -->
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/textViewHello"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, World!" />
    
        <Button
            android:id="@+id/buttonClick"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Click Me" />
    </LinearLayout>
    
    // MainActivity.kt (príklad s View Binding)
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import com.example.myapp.databinding.ActivityMainBinding
    
    class MainActivity : AppCompatActivity() {
    
        private lateinit var binding: ActivityMainBinding
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(binding.root)
    
            binding.buttonClick.setOnClickListener {
                binding.textViewHello.text = "Button Clicked!"
            }
        }
    }
    
  • ViewModel: Komponent z Android Architecture Components, zodpovedný za uchovávanie a správu dát UI špecifickým spôsobom s ohľadom na životný cyklus. Prežíva zmenu konfigurácie Activity, zabraňuje strate dát.

    // MyViewModel.kt
    import androidx.lifecycle.MutableLiveData
    import androidx.lifecycle.ViewModel
    
    class MyViewModel : ViewModel() {
        val counter = MutableLiveData<Int>().apply { value = 0 }
    
        fun incrementCounter() {
            counter.value = (counter.value ?: 0) + 1
        }
    }
    
  • LiveData/StateFlow/Flow: Obserovateľné držiteľské objekty dát, integrované s životným cyklom Androidu. Umožňujú, aby sa UI automaticky aktualizovalo pri zmene dát bez únikov pamäte. LiveData sa často používa s ViewModel. StateFlow a Flow (z Kotlin Coroutines) poskytujú mocnejšie funkcie pre reaktívne programovanie.

    Príklad použitia LiveData s ViewModel:

    // MainActivity.kt (pokračovanie, s ViewModel a LiveData)
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import androidx.activity.viewModels
    import androidx.lifecycle.Observer
    import com.example.myapp.databinding.ActivityMainBinding
    
    class MainActivity : AppCompatActivity() {
    
        private lateinit var binding: ActivityMainBinding
        private val viewModel: MyViewModel by viewModels()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(binding.root)
    
            viewModel.counter.observe(this, Observer { count ->
                binding.textViewHello.text = "Counter: $count"
            })
    
            binding.buttonClick.setOnClickListener {
                viewModel.incrementCounter()
            }
        }
    }
    
  • Architektonické vzory (MVVM, MVI): Rozdeľujú zodpovednosti medzi komponentami. MVVM (Model-View-ViewModel) je najviac odporúčaný Google, kde View sleduje zmeny v ViewModel a ViewModel komunikuje s Modelom (zdrojmi dát). MVI (Model-View-Intent) je alternatívny prístup založený na jednosmernom toku dát.

  • UI Toolkit (View System alebo Jetpack Compose): View System je tradičný imperatívny systém UI. Jetpack Compose je moderný deklaratívny UI nástroj, ktorý zjednodušuje tvorbu zložitých rozhraní.

    // Príklad s Jetpack Compose
    import android.os.Bundle
    import androidx.activity.ComponentActivity
    import androidx.activity.compose.setContent
    import androidx.compose.foundation.layout.Column
    import androidx.compose.material.Button
    import androidx.compose.material.Text
    import androidx.compose.runtime.*
    import androidx.compose.ui.graphics.Color
    import androidx.compose.ui.tooling.preview.Preview
    
    class ComposeActivity : ComponentActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContent {
                Greeting("Compose World")
            }
        }
    }
    
    @Composable
    fun Greeting(name: String) {
        var count by remember { mutableStateOf(0) }
    
        Column {
            Text(text = "Hello $name! Counter: $count")
            Button(onClick = { count++ }) {
                Text("Increment")
            }
        }
    }
    
    @Preview(showBackground = true)
    @Composable
    fun DefaultPreview() {
        Greeting("Compose Preview")
    }
    
  • Práca s tokmi: Všetky operácie s UI by mali byť vykonávané v hlavnom (UI) vlákne. Dlhé operácie (sieťové požiadavky, práca s databázou) by mali byť presunuté do pozadínových vlákien (napríklad pomocou Coroutines, RxJava alebo štandardného ExecutorService) a výsledky vrátené do hlavného vlákna na aktualizáciu UI.

    // Príklad s Coroutines
    import kotlinx.coroutines.*
    
    class MyRepository {
        suspend fun fetchData(): String = withContext(Dispatchers.IO) {
            // Simulácia dlhodobej operácie
            delay(1000)
            "Data from background"
        }
    }
    
    // V ViewModel alebo Activity/Fragment (ale je preferované vo ViewModel)
    fun loadData() {
        viewModelScope.launch { // Alebo lifecycleScope pre Activity/Fragment
            val data = MyRepository().fetchData()
            // Aktualizácia LiveData, ktorá je sledovaná UI
            _dataLiveData.value = data
        }
    }
    
  • Spracovanie udalostí: Implementácia poslucháčov udalostí (kliknutia na tlačidlá, zadanie textu) v Activity/Fragment alebo View, delegovanie biznis logiky do ViewModel.

  • Správa stavu: Použitie ViewModel, StateFlow alebo MutableState (v Compose) na bezpečné a predvídateľné riadenie stavu UI.

Dodržiavanie týchto princípov pomáha vytvárať škálovateľné, udržiavateľné a odolné aplikácie. Výber konkrétnych nástrojov (View System vs Compose, LiveData vs StateFlow) závisí od projektu a preferencií tímu. Google aktívne propaguje Jetpack Compose a Kotlin Coroutines. Použitie Android Architecture Components (ViewModel, LiveData, Room) je štandard.