Ответ
Flutter обеспечивает глубокую, но гибкую интеграцию с Android, сохраняя при этом высокую производительность и единую кодовую базу.
Ключевые механизмы адаптации:
-
Нативный рендеринг через Skia: Flutter самостоятельно отрисовывает каждый пиксель на экране, используя графический движок Skia. Это даёт полный контроль над UI и гарантирует идентичный внешний вид и поведение на всех версиях Android, минуя фрагментацию нативных компонентов.
-
Material Design из коробки: Виджеты
MaterialApp,Scaffold,AppBar,FloatingActionButtonи сотни других реализуют актуальные гайдлайны Material Design, что сразу делает приложение привычным для пользователей Android. -
Доступ к платформенным API:
- Готовые плагины: Для типовых задач (камера, геолокация, сенсоры) используются плагины из
pub.dev(например,camera,geolocator). - Platform Channels: Для уникальной логики или доступа к специфичным API используется прямой двусторонний канал связи между Dart-кодом и нативным Kotlin/Java-кодом.
- Готовые плагины: Для типовых задач (камера, геолокация, сенсоры) используются плагины из
-
Адаптация к системе: Flutter автоматически обрабатывает системные темы (тёмная/светлая), жесты навигации (например, "свайп назад"), плотность пикселей (pixel ratio) и интенты (intents).
Пример использования MethodChannel для вызова нативного кода:
// Dart-сторона (Flutter)
import 'package:flutter/services.dart';
class BatteryService {
static const platform = MethodChannel('com.example.app/battery');
static Future<int> getBatteryLevel() async {
try {
final int result = await platform.invokeMethod('getBatteryLevel');
return result;
} on PlatformException catch (e) {
// Обработка ошибки канала
return -1;
}
}
}
// Android-сторона (Kotlin, в MainActivity.kt)
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.example.app/battery"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
if (call.method == "getBatteryLevel") {
val batteryLevel = getBatteryLevel()
if (batteryLevel != -1) {
result.success(batteryLevel)
} else {
result.error("UNAVAILABLE", "Battery level not available.", null)
}
} else {
result.notImplemented()
}
}
}
private fun getBatteryLevel(): Int {
val batteryLevel: Int
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
} else {
val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
batteryLevel = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
}
return batteryLevel
}
}
- Кастомизация нативного слоя: Папка
android/в проекте Flutter — это полноценный Android-проект (Gradle). Я могу редактироватьAndroidManifest.xml, настраиватьbuild.gradle, добавлять ресурсы или изменятьMainActivity.ktдля реализации специфичной для платформы логики.