Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 582новые вакансии за сутки·92 562вакансии открыты сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании7 220
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 402 кандидата открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python17 105
  • Облачные технологии14 068
  • QA вакансии3 460
  • Backend вакансии2 098
  • Инженер данных1 796
  • Продакт-менеджер1 248

Разработка

  • Android1 866
  • iOS1 699
  • Fullstack вакансии979
  • AI вакансии951
  • Frontend вакансии742
  • Mobile вакансии44

По стеку

  • Go8 651
  • Java6 544
  • Node.js2 018
  • .NET1 719
  • Kotlin1 623
  • Rust1 453
  • C#709
  • PHP683
  • C++571

DevOps и инфраструктура

  • Kubernetes7 761
  • DevOps вакансии6 057
  • Linux-инфраструктура5 492
  • Terraform / IaC4 259
  • CI/CD3 240
  • Мониторинг и Observability1 782
  • SRE565
  • Кибербезопасность450

Аналитика и данные

  • Data Scientist1 127
  • Бизнес-аналитик925
  • Аналитик данных845
  • Системный аналитик154

Другие направления

  • Проджект-менеджер611
  • UI/UX дизайн145
  • Ручное тестирование14

По регионам

  • Вакансии в США43 686
  • Вакансии в Европе23 668
  • Вакансии в Канаде4 413
  • Работа в России3 909

По формату

  • Удалённые вакансии73 889
  • Релокация в США43 686
  • Гибридная работа12 392
  • Офисная работа7 088

По уровню

  • Senior вакансии42 236
  • Middle вакансии20 545
  • Junior вакансии6 653

Сейчас нанимают

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML166 вакансий
  • Grab138 вакансий
  • Celonis39 вакансий
  • Spotify36 вакансий
  • Adyen29 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace16 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме FlutterВсе вопросы
FlutterMiddleПроектирование систем

Как Flutter реализует функции доступности (accessibility)?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

Flutter строит параллельное дерево SemanticsNode поверх widget-дерева и транслирует его в нативный API доступности платформы (UIAccessibility/AccessibilityNodeInfo); кастомные виджеты требуют явного обёртывания в Semantics с label, hint и действиями.

SemanticsNode и Semantics-виджет

Каждый виджет, который хочет быть виден скринридеру, создаёт SemanticsNode. Низкоуровневые виджеты Flutter (Text, ElevatedButton, Checkbox и другие) уже содержат встроенные аннотации. Для кастомных виджетов используется обёртка Semantics:

Semantics(
  label: 'Удалить задачу',
  hint: 'Двойное нажатие удаляет задачу из списка',
  button: true,
  enabled: !isLoading,
  child: GestureDetector(
    onTap: onDelete,
    child: Icon(Icons.delete, color: Colors.red),
  ),
)

Параметры label, hint, value, button, checked, enabled, onTap, onLongPress транслируются во флаги и строки, понятные платформенному API доступности.

Как Flutter реализует доступность

Flutter рисует весь UI через собственный движок (Skia/Impeller) и не использует нативные виджеты платформы. Это означает, что операционная система не знает ничего о кнопках, текстовых полях и изображениях внутри Flutter-приложения. Чтобы TalkBack (Android) и VoiceOver (iOS) могли читать экран, Flutter строит отдельное дерево семантики — SemanticsTree — параллельно дереву виджетов.

Слияние семантики: MergeSemantics и ExcludeSemantics

Составные виджеты часто содержат несколько дочерних узлов, каждый из которых генерирует свой SemanticsNode. Скринридер тогда будет останавливаться на каждом элементе по отдельности. Чтобы сгруппировать их в один фокус доступности, используется MergeSemantics:

MergeSemantics(
  child: Row(
    children: [
      Icon(Icons.star, color: Colors.amber),
      SizedBox(width: 4),
      Text('4.8'),
      Text(' (120 отзывов)'),
    ],
  ),
)

TalkBack объявит это как единый элемент: «4.8 (120 отзывов)». Чтобы скрыть декоративный элемент от скринридера, используется ExcludeSemantics:

ExcludeSemantics(
  child: Icon(Icons.decorative_divider),
)

Мост к платформе: SemanticsBinding и AccessibilityBridge

Flutter Engine содержит AccessibilityBridge (реализован отдельно для Android и iOS). Когда TalkBack или VoiceOver активируется, Engine получает системное событие через SemanticsBinding.ensureSemantics(), после чего начинает синхронизировать SemanticsTree с нативным деревом доступности (UIAccessibility на iOS, AccessibilityNodeInfo на Android). Обновление дерева происходит каждый кадр при наличии изменений.

Практический пример: кастомный SliderWidget

class AccessibleSlider extends StatelessWidget {
  final double value;
  final double min;
  final double max;
  final ValueChanged<double> onChanged;

  const AccessibleSlider({
    super.key,
    required this.value,
    required this.min,
    required this.max,
    required this.onChanged,
  });

  @override
  Widget build(BuildContext context) {
    return Semantics(
      slider: true,
      value: '${value.toStringAsFixed(0)}',
      increasedValue: '${(value + 1).clamp(min, max).toStringAsFixed(0)}',
      decreasedValue: '${(value - 1).clamp(min, max).toStringAsFixed(0)}',
      onIncrease: () => onChanged((value + 1).clamp(min, max)),
      onDecrease: () => onChanged((value - 1).clamp(min, max)),
      child: CustomPaint(
        painter: SliderPainter(value: value, min: min, max: max),
        size: const Size(double.infinity, 40),
      ),
    );
  }
}

Параметры increasedValue и decreasedValue позволяют TalkBack заранее объявить значение до того, как пользователь сделает свайп.

Тестирование доступности

Flutter предоставляет SemanticsController в widget-тестах:

testWidgets('delete button has correct semantics', (tester) async {
  final SemanticsHandle handle = tester.ensureSemantics();
  await tester.pumpWidget(MaterialApp(home: TaskItem(onDelete: () {})));

  expect(
    tester.getSemantics(find.byIcon(Icons.delete)),
    matchesSemantics(
      label: 'Удалить задачу',
      isButton: true,
      hasEnabledState: true,
      isEnabled: true,
    ),
  );

  handle.dispose();
});

Команда командной строки для быстрой проверки на устройстве:

# Включить TalkBack через adb
adb shell settings put secure enabled_accessibility_services com.google.android.marvin.talkback/com.google.android.marvin.talkback.TalkBackService

# Проверить дерево семантики в отладчике Flutter
flutter inspect --tree semantics

Размер шрифта и dynamic type

Flutter уважает системный масштаб текста через MediaQuery.textScalerOf(context). По умолчанию Text-виджеты масштабируются автоматически. Если нужно ограничить масштаб (например, в иконках с текстом), используется textScaler: TextScaler.linear(1.0) — но делать это следует осознанно, так как это ухудшает доступность для слабовидящих.

Подводные камни

  • Кастомные виджеты, нарисованные через CustomPainter, невидимы для скринридера без явного Semantics-обёртки — Engine не может интерпретировать произвольные пиксели.
  • MergeSemantics не работает поверх виджетов, которые уже имеют действия (onTap и т. п.) — дочерние действия теряются при слиянии, если не указать их явно в родительском Semantics.
  • Отключение семантики через ExcludeSemantics на контейнере с кнопками внутри лишает пользователей скринридера доступа ко всем дочерним интерактивным элементам, а не только декоративным.
  • Порядок фокуса TalkBack/VoiceOver следует порядку SemanticsNode в дереве, а не визуальному порядку — при наложениях через Stack фокус может переходить в неожиданном порядке.
  • Использование Semantics(label: ...) без excludeSemantics: true на Image приводит к дублированию: объявляется и label, и alt-текст из атрибута semanticLabel самого Image.
  • Анимированные виджеты с постоянными перестройками (например, shimmer-эффект) непрерывно обновляют SemanticsTree, что перегружает TalkBack и делает его неотзывчивым — нужен ExcludeSemantics на время анимации.
  • На iOS SemanticsAction.customAction не транслируется напрямую в UIAccessibility custom actions без дополнительного кода на уровне FlutterViewController — стандартные жесты VoiceOver могут не срабатывать.
  • Минимальный рекомендуемый размер touch-цели — 48×48 dp (Material) и 44×44 pt (iOS HIG). Flutter не применяет это ограничение автоматически; маленькие иконки без явного SizedBox или Padding нарушают рекомендации WCAG 2.5.5.

Частые вопросы на собеседовании

  • Как работает управление состоянием (state management) во Flutter? Назовите распространённые решения.
  • Как работает дерево виджетов (widget tree) во Flutter (widget tree, element tree, render tree)?
  • Каковы лучшие практики оптимизации производительности Flutter?
  • В чём разница между StatelessWidget и StatefulWidget?

Типичные ошибки

  • Сводить «Flutter реализует функции доступности (accessibility)» к синтаксису и не объяснять platform channel.
  • Игнорировать жизненный цикл, основной поток или момент освобождения ресурсов в сценарии flutter-24.
  • Выбирать API по привычке, не проверяя состояние, ошибки, доступность и платформенные ограничения.

Что проверяет интервьюер

  • Формулирует точную модель для «Flutter реализует функции доступности (accessibility)» и подтверждает ее корректным примером.
  • Умеет связать ответ с widget tree, тестированием и отладкой на устройстве.
  • Называет ограничения подхода flutter-24, включая производительность, память и сопровождение.

Как вы знаете этот вопрос?

Проверить себя по теме Flutter →

Источники

  • https://docs.flutter.dev/ui/accessibility

Связанные темы

Flutterframework-api-designMobile-Engineering