Был ли опыт работы со сложными кастомными вью в Android
Что проверяют
Хотят понять, где проходит граница вашего опыта: собирали ли вы только составные вью из готовых виджетов или сами отвечали за измерение, отрисовку и касания. Следом обычно просят рассказать, как вы добивались плавности и что делали с wrap_content.
Как отвечать
Возьмите один реальный компонент: зачем понадобился, почему стандартные не подошли, что было сложным. Примеры и цифры нужны свои, а технический каркас такой:
- измерение:
onMeasure()с разборомMeasureSpec(режимыEXACTLY,AT_MOST,UNSPECIFIED) и обязательный вызовsetMeasuredDimension(). Для своегоViewGroupдобавляетсяonLayout()с раскладкой детей; - отрисовка:
onDraw()сCanvas,Paint,Path. Объекты создаются заранее, а не на каждый кадр, иначе сборщик мусора даёт рывки, а Lint выдаётDrawAllocation; - обновление:
invalidate()только перерисовывает,requestLayout()запускает новое измерение и раскладку. Путать их значит либо терять изменение размера, либо зря гонять measure на каждый кадр; - атрибуты:
declare-styleableв XML, чтение черезobtainStyledAttributes()иrecycle()илиwithStyledAttributesиз core-ktx; - касания и доступность:
onTouchEvent(),GestureDetector, порогViewConfiguration.get(context).scaledTouchSlop. Для виртуальных элементов внутри одной вью нуженExploreByTouchHelper, иначе TalkBack их не увидит.
Если новые экраны у вас на Jetpack Compose, упомяните аналоги: Canvas, Modifier.drawBehind, свой Layout и встраивание старой вью через AndroidView.
Если опыта нет, не выдумывайте. Скажите, что делали составные компоненты, и опишите, с чего начали бы свою вью: какие методы переопределить и как проверить производительность в Layout Inspector и Perfetto.
Где спотыкаются
Выдают за сложную вью LinearLayout с тремя вложенными виджетами. Первый вопрос про onMeasure закончит разговор.
Создают Paint и Path прямо в onDraw(). На анимации это даёт пропуски кадров, их потом списывают на слабое устройство.
Игнорируют MeasureSpec, из-за чего wrap_content ведёт себя как match_parent: базовая реализация View в режиме AT_MOST просто занимает всё доступное место.