Как делать UI в Android — практическое руководство

Короткий ответ: для новых проектов выбирайте Jetpack Compose, для поддержки legacy — XML, для встраивания веб‑контента — WebView; Android Studio дает Preview, Layout Inspector, Profiler и генераторы тем, которые ускорят работу и помогут отладить производительность.

XML — классика и совместимость

XML — декларативные макеты в res/layout подходят для поддерживаемых проектов и случаев, когда нужна тесная интеграция с существующей View-системой.

Пример простого layout (activity_main.xml):

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Привет, XML!"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Нажми"
        app:layout_constraintTop_toBottomOf="@id/textView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Плюсы: предсказуемость, простота тестов, совместимость с ViewBinding/DataBinding. Минусы: шаблонный код для динамики, вложенные layout'ы могут ухудшать производительность.

Используйте ConstraintLayout и Chain вместо вложенных LinearLayout — это уменьшит глубину иерархии и улучшит рендер.

Jetpack Compose — современный реактивный UI

Compose — UI как функции Kotlin, recomposition происходит только при изменениях state. Рекомендуется для greenfield и постепенной миграции.

Минимальный пример:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { MyApp() }
    }
}

@Composable
fun MyApp() {
    var text by remember { mutableStateOf("Привет, Compose!") }
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(text)
        Spacer(Modifier.height(16.dp))
        Button(onClick = { text = "Нажато!" }) { Text("Изменить") }
    }
}

Практические советы:

  • Держите composable маленькими и переиспользуемыми.
  • Для асинхронной логики используйте LaunchedEffect, side‑effect избегайте в теле composable.
  • Включите Preview для быстрого дизайна и тестов.

Не выполняйте долгие операции внутри composable — это приведёт к пропускам кадров. Переносите логику в ViewModel/корутины.

WebView и когда использовать HTML

WebView полезен для встраивания существующего веб‑контента, лендингов или PWA внутри приложения.

Пример загрузки локального файла:

val webView: WebView = findViewById(R.id.webview)
webView.settings.javaScriptEnabled = true
webView.webViewClient = WebViewClient()
webView.loadUrl("file:///android_asset/index.html")

Советы по безопасности и производительности:

  • Отключайте JS, если он не нужен.
  • Ограничивайте доступ к файловой системе.
  • Тестируйте на разных WebView‑движках (разные версии Android имеют разные реализации).

WebView быстро решает задачу показа HTML, но требует особого внимания к безопасности и тестированию на разных API.

Инструменты Android Studio для UI

  • Composable Preview — быстрый просмотр composable без запуска приложения.
  • Layout Inspector — отладка иерархии View/Compose во время выполнения.
  • Material Theme Builder — создание темы на основе палитры.
  • Profiler (CPU, GPU, Frames) — измеряйте FPS и overdraw.
  • Lint и Accessibility checks — автоматические рекомендации по оптимизации и удобству.

Быстрые шаги оптимизации:

  1. Включите Profiler → отслеживайте кадры и устраните длинные операции на главном потоке.
  2. Измеряйте overdraw и минимизируйте прозрачные слои.
  3. Профилируйте память при больших списках (RecyclerView/LazyColumn).

Частые ошибки

  • Запуск тяжёлой работы на UI‑потоке (ANR).
  • Излишняя вложенность layout'ов в XML.
  • Хранение состояния UI вне ViewModel при Compose.
  • Оставленный включённый JavaScript в WebView без фильтрации контента.
  • Игнорирование accessibility (TalkBack, contentDescription).

FAQ

  • Как мигрировать экран с XML на Compose?

    • Мигрируйте по частям: оберните отдельные View в AndroidView или создавайте новые экраны на Compose, оставляя навигацию прежней.
  • Можно ли смешивать XML и Compose?

    • Да: используйте ComposeView в XML или AndroidView в Compose для interoperability.
  • Что быстрее по разработке?

    • Compose обычно быстрее для прототипов и сложной UI‑логики; XML проще при маленьких статичных экранах в legacy-проектах.
  • Как тестировать WebView?

    • Проверяйте загрузку контента, навигацию, обработку ссылок и безопасность на реальных устройствах с разными версиями WebView.