UI

https://developer.android.com/design/ui
https://developer.android.com/design/ui/mobile
https://developer.android.com/design/ui/large-screens
https://developer.android.com/design/ui/widget
https://developer.android.com/design/ui/wear
https://developer.android.com/design/ui/tv
https://developer.android.com/studio/write/draw9patch
https://developer.android.com/topic/performance/vitals/render
https://m3.material.io/Material3
https://m2.material.io/design/color/the-color-system.htmlMaterial2 Color system
https://fonts.google.com/Google Fonts
https://fonts.google.com/iconsGoogle Icons
https://pictogrammers.com/library/mdi/Material Design Icons
https://www.color-name.com/hexName a Color
https://icon.kitchen/App Icon Generator
https://romannurik.github.io/AndroidAssetStudio/icons-app-shortcut.htmlApp Shortcut Icon Generator
https://mockuphone.com/Screenshots Device Mockups Generator
XML
https://developer.android.com/develop/ui/views/layout/declaring-layout
https://developer.android.com/reference/android/util/Xml

Extensible Markup Language. Язык разметки, используемый для описания данных. В Android в основном используется для описания данных, связанных с UI.

<merge>

Упрощает макет, убирая лишний уровень вложенности. Дочерние элементы <merge> добавляются напрямую в родительский макет, без создания дополнительного контейнера. Это улучшает производительность и упрощает структуру.

<!-- layout/fragment_example.xml -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView
        android:id="@+id/example_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World" />

    <Button
        android:id="@+id/example_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me" />
</merge>
<include>

Используется для повторного использования макетов и упрощения их структуры. Он позволяет включать один макет в другой, что помогает избежать дублирования кода и улучшает читаемость и поддерживаемость вашего проекта.

<!-- layout/activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        layout="@layout/fragment_example" />

</LinearLayout>
Layers
Layer List

Позволяет накладывать несколько изображений друг на друга в виде слоев. Каждый слой можно настроить по размеру, положению и порядку наложения.

• Слои отображаются в порядке их перечисления: первым идет самый нижний слой, последним — самый верхний.

• Если у слоя не указаны размеры, он займет весь доступный контейнер.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/background"
        android:drawable="@color/background_color"
        android:padding="8dp" />

    <item
        android:drawable="@drawable/icon_shadow"
        android:left="5dp"
        android:top="5dp"
        android:right="5dp"
        android:bottom="5dp"
        android:opacity="opaque" />

    <item
        android:drawable="@drawable/icon_main"
        android:width="48dp"
        android:height="48dp"
        android:gravity="center"
        android:visible="true" />

    <item
        android:drawable="@drawable/icon_overlay"
        android:paddingLeft="4dp"
        android:paddingTop="4dp"
        android:paddingRight="4dp"
        android:paddingBottom="4dp"
        android:blendMode="src_over" />
</layer-list>
imageView.setImageResource(R.drawable.layered_icon)

drawable указывает изображение или цвет для слоя.

id задает уникальный идентификатор слоя.

left отступ от левой стороны контейнера.

top отступ от верхней стороны контейнера.

right отступ от правой стороны контейнера.

bottom отступ от нижней стороны контейнера.

width задает ширину слоя (в dp).

height задает высоту слоя (в dp).

gravity указывает позиционирование слоя (например, center, left, right).

padding задает общий отступ внутри слоя.

paddingLeft отступ внутри слоя от левой стороны.

paddingTop отступ внутри слоя от верхней стороны.

paddingRight отступ внутри слоя от правой стороны.

paddingBottom отступ внутри слоя от нижней стороны.

opacity задает прозрачность слоя (opaque, translucent, transparent).

visible определяет, отображается ли слой (true или false).

blendMode указывает режим смешивания слоя (src_over, multiply, screen и другие).

State List

Позволяет отображать разные изображения в зависимости от состояния View. Порядок элементов важен: первым должен быть <item> с более специфичным состоянием.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/item_pressed" android:state_pressed="true" />
    <item android:drawable="@drawable/item_enabled" android:state_enabled="true" />
    <item android:drawable="@drawable/item_disabled" android:state_enabled="false" />
    <item android:drawable="@drawable/item_checked" android:state_checked="true" />
    <item android:drawable="@drawable/item_selected" android:state_selected="true" />
    <item android:drawable="@drawable/item_focused" android:state_focused="true" />
    <item android:drawable="@drawable/item_activated" android:state_activated="true" />
    <item android:drawable="@drawable/item_drag_can_accept" android:state_drag_can_accept="true" />
    <item android:drawable="@drawable/item_drag_hovered" android:state_drag_hovered="true" />
    <item android:drawable="@drawable/item_hovered" android:state_hovered="true" />
    <item android:drawable="@drawable/item_window_focused" android:state_window_focused="true" />
    <item android:drawable="@drawable/item_checkable" android:state_checkable="true" />
    <item android:drawable="@drawable/item_multiline" android:state_multiline="true" />
    <item android:drawable="@drawable/item_first" android:state_first="true" />
    <item android:drawable="@drawable/item_last" android:state_last="true" />
    <item android:drawable="@drawable/item_middle" android:state_middle="true" />
</selector>
imageView.setImageResource(R.drawable.button_state_list)

state_pressed состояние нажатия.

state_enabled элемент включен или отключен.

state_checked находится в состоянии выбора (например, для CheckBox).

state_selected выделена пользователем.

state_focused находится в фокусе.

state_activated активирована (например, для ListView).

state_active обозначение активного элемента.

state_drag_can_accept может принять перетаскиваемый объект.

state_drag_hovered находится под перетаскиваемым объектом.

state_hovered указатель (например, мышь) находится над элементом.

state_window_focused окно, в котором находится элемент, в фокусе.

state_checked_highlighted выбор элемента с дополнительной визуальной подсветкой.

state_checkable поддерживает состояние выбора.

state_multiline поддерживает многострочный текст.

state_first первый элемент в группе.

state_last последний элемент в группе.

state_middle находится между первым и последним в группе.

Level List

Отображает разные изображения в зависимости от текущего уровня.

<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/battery_empty" android:minLevel="0" android:maxLevel="20" />
    <item android:drawable="@drawable/battery_low" android:minLevel="21" android:maxLevel="50" />
    <item android:drawable="@drawable/battery_half" android:minLevel="51" android:maxLevel="80" />
    <item android:drawable="@drawable/battery_full" android:minLevel="81" android:maxLevel="100" />
</level-list>
imageView.setImageResource(R.drawable.battery_level_list)
imageView.drawable.level = 45

minLevel минимальный уровень, при котором изображение отображается.

maxLevel максимальный уровень, при котором изображение отображается.

Bitmap

Изображение, представленное в виде пиксельных данных. В Android Bitmap используется для работы с изображениями (фото, иконки) и позволяет загружать, создавать и изменять растровые изображения.

val bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
Bitmap.Config

Определяет формат и качество хранения пиксельных данных в Bitmap. Выбор конфигурации влияет на количество памяти, занимаемой изображением, а также на поддерживаемые цветовые каналы и прозрачность.

ALPHA_8 изображение с 8-битным альфа-каналом (прозрачность).

RGB_565 изображение с 16-битными пикселями (5 бит красный, 6 бит зеленый, 5 бит синий). Меньше памяти, но без альфа-канала.

ARGB_8888 изображение с 32-битными пикселями (по 8 бит на каждый канал: альфа, красный, зеленый, синий). Высокое качество, но больше занимает памяти.

RGBA_F16 изображение с 16-битными значениями для каждого канала. Используется для изображений высокого качества.

HARDWARE используется аппаратное ускорение для обработки изображения. Значительно повышает производительность, но не поддерживает прямое изменение пикселей через методы getPixel() и setPixel().

RGBA_1010102 изображение с 10-битными значениями для каналов красного, зеленого и синего и 2-битным альфа-каналом. Используется для изображений высокого качества на устройствах с HDR-экраном.

createBitmap

Создает новый пустой Bitmap с заданной шириной, высотой и конфигурацией.

val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
copy

Создает копию текущего Bitmap с новой конфигурацией. Если isMutable = true, то копия будет изменяемой.

val bitmapCopy = bitmap.copy(Bitmap.Config.RGB_565, true)
getWidth

Возвращают ширину Bitmap в пикселях.

val width = bitmap.width
getHeight

Возвращают высоту Bitmap в пикселях.

val height = bitmap.height
getPixel

Возвращает цвет пикселя по указанным координатам в виде значения Int.

val color = bitmap.getPixel(50, 50)
setPixel

Устанавливает цвет пикселя по указанным координатам. Работает только для изменяемых Bitmap.

bitmap.setPixel(50, 50, Color.RED)
compress

Сохраняет Bitmap в указанный поток в сжатом виде. Параметр quality определяет степень сжатия (0–100).

bitmap.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream("output.png"))
recycle

Освобождает память, занятую Bitmap. Используется, когда изображение больше не нужно, чтобы избежать утечек памяти.

bitmap.recycle()
isMutable

Возвращает true, если Bitmap можно изменять, и false, если изображение неизменяемое.

val isMutable = bitmap.isMutable
eraseColor

Заполняет все пиксели Bitmap указанным цветом. Работает только для изменяемых изображений.

bitmap.eraseColor(Color.WHITE)
hasAlpha

Возвращает true, если изображение поддерживает альфа-канал (прозрачность).

val supportsAlpha = bitmap.hasAlpha()
extractAlpha

Создает новый Bitmap, содержащий только альфа-канал (прозрачность) исходного изображения.

val alphaBitmap = bitmap.extractAlpha()
BitmapFactory

Используется для декодирования изображений из различных источников, таких как файлы, ресурсы, потоки или байтовые массивы, в объекты Bitmap.

decodeResource

Декодирует изображение из ресурсов по его идентификатору. Удобен для загрузки изображений, находящихся в папке res/drawable.

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.sample_image)
decodeFile

Загружает изображение из файла по указанному пути.

val bitmap = BitmapFactory.decodeFile("/storage/emulated/0/Download/image.jpg")
decodeStream

Декодирует изображение из потока данных. Полезен для загрузки изображений из сети или при чтении из файлового потока.

val inputStream = URL("https://example.com/image.png").openStream()
val bitmap = BitmapFactory.decodeStream(inputStream)
inputStream.close()
decodeByteArray

Декодирует изображение из массива байтов. Используется, если изображение загружено в виде байтового массива, например, из базы данных.

val bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
Drawable
https://developer.android.com/guide/topics/resources/drawable-resource

Базовый класс для представления графических объектов, которые можно отображать на экране. Он используется для работы с изображениями, цветами и фигурами в интерфейсе.

BitmapDrawable

Используется для отображения растровых изображений (Bitmap) в Android. Он позволяет загружать, отображать и настраивать растровые изображения, например, управлять их масштабом или положением.

ShapeDrawable

Позволяет рисовать простые фигуры (прямоугольники, овалы, линии и т. д.).

LayerDrawable

Позволяет объединить несколько Drawable в один слой. Каждый слой может быть отрисован отдельно, с возможностью управления их положением и прозрачностью.

StateListDrawable

Позволяет отображать разные изображения (Drawable) в зависимости от состояния элемента интерфейса, например, нажатия, выделения или отключения.

NinePatchDrawable

Позволяет создавать растягиваемые изображения для фоновых элементов, кнопок или других UI-компонентов. Использует .9.png файлы, которые имеют встроенные данные для растяжения и заполнения.

VectorDrawable

Класс в Android для работы с векторными изображениями. Он позволяет описывать графику в виде XML-файлов с использованием форм, линий и цветов.

AnimationDrawable

Позволяет создавать анимации из последовательности изображений (кадров). Он используется для покадровой анимации, где каждое изображение отображается в течение заданного времени.

9-Patch

Растровые изображения, размер которых автоматически изменяется в соответствии с содержимым представления и размером экрана. Выбранные части изображения масштабируются по горизонтали или вертикали на основе индикаторов, нарисованных внутри изображения.

Density

Количество пикселей на единицу площади экрана устройства, обычно измеряется в dpi (dots per inch). В Android экраны делятся на несколько категорий плотности.

• ldpi (low) — 120 dpi

• mdpi (medium) — 160 dpi

• hdpi (high) — 240 dpi

• xhdpi (extra high) — 320 dpi

• xxhdpi (extra extra high) — 480 dpi

• xxxhdpi (extra extra extra high) — 640 dpi

dp

Density-independent pixels — единица измерения, которая используется для создания интерфейсов, независимых от плотности пикселей экрана. 1 dp эквивалентен 1 пикселю на экране с плотностью 160 dpi. Это помогает поддерживать стабильные размеры элементов интерфейса на устройствах с разной плотностью пикселей.

sp

Scale-independent pixels — единица измерения для текста в Android, которая учитывает настройки размера шрифта пользователя (например, для доступности). Используется для определения размеров текста, чтобы он корректно отображался на разных устройствах и при разных настройках экрана.

nodpi

Квалификатор, который используется для ресурсов, не зависящих от плотности пикселей экрана. Такие ресурсы будут одинаково отображаться на всех устройствах.

anydpi

Квалификатор для ресурсов, который используется на устройствах с любым разрешением экрана.

Strings

• Строки хранятся в ресурсах (файл strings.xml), что позволяет поддерживать интернационализацию.

<string name="app_name">My Application</string>
Plurals

Ресурс, предназначенный для отображения текста с учётом числового значения, чтобы правильно склонять слова.

• Для ru-строк корректно будет работать только если в системе установлен русский язык.

<plurals name="item_count">
    <item quantity="zero">Нет предметов</item>
    <item quantity="one">%d предмет</item>
    <item quantity="two">%d предмета</item>
    <item quantity="few">%d предмета</item>
    <item quantity="many">%d предметов</item>
    <item quantity="other">%d предметов</item>
</plurals>
val count = 3
val text = resources.getQuantityString(R.plurals.item_count, count, count)
textView.text = text

zero используется для значения 0.

one используется для чисел 1, 21, 31 и т.д.

two используется в некоторых языках (например, на арабском) для значения 2.

few используется для чисел от 2 до 4 в русском языке.

many используется для чисел от 5 до 20, а также для всех значений, кратных 10.

other используется по умолчанию, если никакое другое правило не подходит.

LayoutInflater

Используется для преобразования XML-файлов разметки в соответствующие объекты View.

// Получаем LayoutInflater из контекста
val inflater = LayoutInflater.from(context)

// Используем inflater для создания View из XML
val view = inflater.inflate(R.layout.custom_view_layout, null)
attachToRoot

Если вы используете LayoutInflater в производительном коде, например, в адаптерах RecyclerView, рекомендуется использовать метод inflate с параметром attachToRoot = false, чтобы избежать лишних операций и улучшить производительность.

val view = LayoutInflater.from(context).inflate(R.layout.my_layout, rootView, attachToRoot = true)
AsyncLayoutInflater

Позволяет асинхронно инфлейтить XML-разметку. Это полезно для улучшения производительности и избегания блокировки основного потока приложения при создании сложных или ресурсозатратных пользовательских интерфейсов. Выполняется в фоновом потоке.

AsyncLayoutInflater(context).inflate(R.layout.my_layout, null) { inflatedView, _, _ ->
    // Этот блок кода выполняется после завершения инфлейтации
    // Вы можете использовать inflatedView для дальнейших операций
}
Choreographer

Класс, который помогает синхронизировать обновления экрана и анимации с частотой обновления экрана (refresh rate). Он играет ключевую роль в обеспечении плавности анимаций и поддержке высокой производительности пользовательского интерфейса.

• Синхронизация с частотой обновления экрана. Choreographer обеспечивает, чтобы обновления и отрисовка экрана происходили синхронно с частотой обновления экрана, что помогает избегать мерцания и улучшает плавность анимаций.

• Планирование и обработка кадров. Класс управляет планированием и обработкой кадров в цикле отображения. Он гарантирует, что обновления пользовательского интерфейса и отрисовка происходят в нужное время.

• Методы для добавления задач. Choreographer предоставляет методы для добавления задач, которые будут выполняться до или после обновления экрана.

postFrameCallback

Позволяет добавить FrameCallback, который будет вызван перед следующим обновлением экрана. Это полезно для выполнения задач, которые должны быть синхронизированы с кадровой частотой, например, обновление анимаций.

Choreographer.getInstance().postFrameCallback(object: Choreographer.FrameCallback {
    override fun doFrame(frameTimeNanos: Long) {
        // Ваш код для обновления UI
        Choreographer.getInstance().postFrameCallback(this) // Повторное добавление
    }
})
postCallback

Позволяет добавить Runnable (или Callback) для выполнения задачи в заданный момент времени, например, после обновления экрана.

Choreographer.getInstance().postCallback(
    Choreographer.CALLBACK_ANIMATION,
    Runnable {
        // Ваш код для выполнения после обновления экрана
    },
    null
)
SplashScreen

Предоставляет поддержку для создания экранов загрузки (splash screens) на устройствах, работающих на Android до версии 12 (API 31), а также упрощает реализацию сплэш-экранов на более поздних версиях. Она позволяет разработчикам легко и быстро настраивать сплэш-экраны с минимальными усилиями.

https://developer.android.com/develop/ui/views/launch/splash-screen/migrate
Theme.SplashScreen

Специальная тема, предоставляемая библиотекой SplashScreen Compat в Android, предназначенная для настройки внешнего вида сплэш-экрана вашего приложения. Она позволяет определять, как будет выглядеть сплэш-экран при запуске приложения.

<style name="Theme.App.Starting" parent="Theme.SplashScreen">
    <item name="windowSplashScreenBackground">@color/splash_background</item>
    <item name="windowSplashScreenAnimatedIcon">@drawable/ic_animated_icon</item>
    <item name="windowSplashScreenIconBackgroundColor">@color/icon_background</item>
    <item name="windowSplashScreenAnimationDuration">500</item>
    <item name="android:windowSplashScreenBrandingImage">@drawable/ic_branding_image</item>
    <item name="postSplashScreenTheme">@style/Theme.App</item>
</style>
windowSplashScreenBackground

Задает цвет фона сплэш-экрана.

<item name="windowSplashScreenBackground">@color/splash_background</item>
windowSplashScreenAnimatedIcon

Определяет иконку, отображаемую на сплэш-экране.

<item name="windowSplashScreenAnimatedIcon">@drawable/ic_animated_icon</item>
windowSplashScreenIconBackgroundColor

Устанавливает цвет фона для иконки.

<item name="windowSplashScreenIconBackgroundColor">@color/icon_background</item>
windowSplashScreenAnimationDuration

Задает продолжительность анимации сплэш-экрана в миллисекундах.

<item name="windowSplashScreenAnimationDuration">500</item>
windowSplashScreenBrandingImage

Добавляет брендированное изображение.

<item name="android:windowSplashScreenBrandingImage">@drawable/ic_branding_image</item>
postSplashScreenTheme

Определяет тему, которая будет применяться после показа сплэш-экрана.

<item name="postSplashScreenTheme">@style/Theme.App</item>
installSplashScreen

Используется для установки и настройки SplashScreen в Activity, обеспечивая возможность кастомизации его поведения и внешнего вида.

class MainActivity: ComponentActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        // Устанавливаем экран загрузки
        val splashScreen = installSplashScreen()
        super.onCreate(savedInstanceState)
    }
}
setKeepOnScreenCondition

Позволяет управлять тем, как долго экран загрузки будет оставаться видимым, в зависимости от определенного условия.

class MainActivity: ComponentActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        val splashScreen = installSplashScreen()
        splashScreen.setKeepOnScreenCondition { viewModel.splashLoading.value }
        super.onCreate(savedInstanceState)
    }
}

class MainViewModel: ViewModel() {
	  private val _splashLoading = MutableStateFlow(true)
    val splashLoading: StateFlow<Boolean> get() = _splashLoading.asStateFlow()
}
RenderThread

Отдельный поток для повышения производительности и плавности интерфейса. RenderThread отвечает за отрисовку UI, разгружая основной поток (UI Thread) и минимизируя задержки и лаги в отображении интерфейса.

• Появился в Android 5.0 (API 21).

Gestures
GestureDetector

Класс, который используется для распознавания простых жестов пользователя, таких как нажатие, двойное нажатие, смахивание и прокрутка. Этот класс помогает обработать сложные взаимодействия с пользователем на основе последовательности событий касания.

val gestureDetector = GestureDetector(context, object: GestureDetector.SimpleOnGestureListener() {
    override fun onSingleTapUp(e: MotionEvent): Boolean {
        // обработка одиночного нажатия
        return true
    }

    override fun onLongPress(e: MotionEvent) {
        // обработка долгого нажатия
    }

    override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
        // обработка смахивания
        return true
    }
})

override fun onTouchEvent(event: MotionEvent): Boolean {
    return gestureDetector.onTouchEvent(event)
}
GestureListener

Интерфейс, который используется для обработки жестов пользователя.

onDown

Вызывается при первом касании экрана.

onShowPress

Вызывается, когда палец касается экрана, но еще не отпущен.

onSingleTapUp

Вызывается при быстром одиночном нажатии.

onScroll

Вызывается при движении пальца по экрану.

onLongPress

Вызывается при долгом нажатии.

onFling

Вызывается при быстром движении пальца по экрану (смахивании).

Animations
ValueAnimator

Представляет механизм для запуска анимаций вычисления анимированных значений и установки их для целевых объектов.

ObjectAnimator

Наследуется от ValueAnimator. Обеспечивает поддержку анимации свойств целевых объектов. Анимации можно создавать из кода и XML.

ViewPropertyAnimator

Вызывается через View.animate. Подходит для выполнения нескольких анимаций одновременно.

HEX-Colors Opacity
HEXOpacity
100%FF
99%FC
98%FA
97%F7
96%F5
95%F2
94%F0
93%ED
92%EB
91%E8
90%E6
89%E3
88%E0
87%DE
86%DB
85%D9
84%D6
83%D4
82%D1
81%CF
80%CC
79%C9
78%C7
77%C4
76%C2
75%BF
74%BD
73%BA
72%B8
71%B5
70%B3
69%B0
68%AD
67%AB
66%A8
65%A6
64%A3
63%A1
62%9E
61%9C
60%99
59%96
58%94
57%91
56%8F
55%8C
54%8A
53%87
52%85
51%82
50%80
49%7D
48%7A
47%78
46%75
45%73
44%70
43%6E
42%6B
41%69
40%66
39%63
38%61
37%5E
36%5C
35%59
34%57
33%54
32%52
31%4F
30%4D
29%4A
28%47
27%45
26%42
25%40
24%3D
23%3B
22%38
21%36
20%33
19%30
18%2E
17%2B
16%29
15%26
14%24
13%21
12%1F
11%1C
10%1A
9%17
8%14
7%12
6%0F
5%0D
4%0A
3%08
2%05
1%03
0%00
Server-Driven UI (SDUI)

Подход к разработке, в котором сервер управляет отображением пользовательского интерфейса (UI) на клиенте. Вместо жестко закодированного UI на стороне клиента, сервер отправляет инструкции или JSON-описание, и клиентский код строит интерфейс на их основе.

{
    "type": "VerticalLayout",
    "children": [
        {
            "type": "Text",
            "text": "Добро пожаловать!"
        },
        {
            "type": "Button",
            "text": "Начать",
            "action": "navigate_to_start"
        }
    ]
}
fun renderUI(json: String) {
    val uiData = parseJson(json)
    when (uiData.type) {
        "Text" -> Text(text = uiData.text)
        "Button" -> Button(onClick = { handleAction(uiData.action) }) {
            Text(text = uiData.text)
        }
        "VerticalLayout" -> Column {
            uiData.children.forEach { renderUI(it) }
        }
    }
}
Вопросы на собесе (10)
  • XML (2)
    1. Для чего используется тег merge в XML?

      Для повторного использования иерархий представлений, позволяя вставлять содержимое одного XML-файла в другой. Это упрощает управление разметкой и уменьшает дублирование кода.

    1. Для чего используется тег include в XML?

      Для повторного использования разметки, позволяя вставлять содержимое одного XML-файла в другой. Это упрощает управление представлениями и уменьшает дублирование кода.

  • Другие (8)
    1. C какой частотой должен отрисовываться UI?

      UI должен отрисовываться с частотой не менее 60 кадров в секунду (FPS) для обеспечения плавного и отзывчивого пользовательского интерфейса. Это соответствует обновлению экрана каждые 16,67 миллисекунд. Если частота падает ниже 30 FPS, пользователь может заметить задержки и подтормаживания, что ухудшает опыт использования приложения.

    1. Что такое RenderThread?

      Это отдельный поток в Android, используемый для операций отрисовки пользовательского интерфейса, таких как анимации и графика. Он разгружает основной поток приложения, улучшая отзывчивость интерфейса и снижая задержки при отрисовке, что особенно важно в графически насыщенных приложениях.

    1. Какие есть инструменты для создания анимаций?

      ValueAnimator PropertyAnimator ObjectAnimator MotionLayout

    1. Как в Android обрабатывать жесты?

      GestureDetector для распознавания стандартных жестов, таких как одиночное нажатие, двойное нажатие, пролистывание и т.д. Можно переопределить методы onSingleTapConfirmed() и onFling() для обработки конкретных жестов.

      ScaleGestureDetector для обработки жестов масштабирования, позволяя обрабатывать увеличение и уменьшение масштаба.

      TouchListener реализуйте интерфейс OnTouchListener на View для получения детальных данных о прикосновениях и отслеживания движений пальцев.

    1. Что нельзя делать с MotionEvent?

      Сохранять ссылки на него. Поскольку события генерируются в большом количестве, а система использует ограниченный пул объектов, сохранять ссылки на MotionEvent неправильно. Лучше обрабатывать события сразу, чтобы избежать проблем с производительностью и утечками памяти.

    1. Как оптимизировать UI?

      Не рисовать фон в XML. устанавливать его в windowBackground.

      Задавать размеры View если они известны чтобы не тратить ресурсы на измерение.

    1. Какой метод используется для получения ссылки на компонент из макета?

      getViewByld()

      findViewByld()

      findComponentByld()

      getComponentByld()

    1. Какой из следующих классов используется для создания анимаций в Android?

      AnimationManager

      AnimationController

      AnimationUtils

      AnimationHandler