Я хочу использовать основной логотип из ресурсов Flutter в своем родном коде Android — например, для отображения уведомления. Как вы знаете, в Android вы обычно получаете ресурсы из drawable
папки вот так R.drawable.icon
. Но тогда мне также нужно скопировать значок в папку Android. Может быть, есть способ получить доступ к ресурсам (читай — активам) Flutter из нативного кода?
Об этом есть хороший раздел в флаттер документация.
Учитывая актив "icons/heart.png", для Android (начиная с 1.22):
FlutterLoader loader = FlutterInjector.instance().flutterLoader();
String key = loader.getLookupKeyForAsset("icons/heart.png");
Для iOS (быстро):
let key = registrar.lookupKey(forAsset: "icons/heart.png");
let path = Bundle.main.path(forResource: key, ofType: nil)
Для iOS (obj-c):
NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];
Для Android до версии Flutter 1.22 (устарело):
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("icons/heart.png");
AssetFileDescriptor fd = assetManager.openFd(key);
Тем не менее, вы не сможете поделиться элементом рисования непосредственно с флаттером, а главная иконка — это особый случай, которым вы определенно не можете поделиться с флаттером. Flutter не знает, что такое «drawable», а работает с ресурсами по-своему, кросс-платформенно.
что, если я не в плагине, а в MainActivity? stackoverflow.com/questions/65374762/…
И как вы конвертируете свой AssetFileDescriptor в Drawable или ресурс?
PluginRegistry.Registrar устарел. Ответ от @SurajNair содержит обновленный код.
Вам нужно получить относительный путь к файлу актива.
Ниже приведен вспомогательный метод для доступа к пути к файлу/изображению из собственного кода Swift.
func flutterAssetLottieFilePath(imageName : String) -> String {
var flutterViewController = FlutterViewController()
flutterViewController = UIWindow.init(frame: UIScreen.main.bounds).rootViewController as! FlutterViewController
let key = flutterViewController.lookupKey(forAsset:"assets/images/\(imageName).png")
let path = Bundle.main.path(forResource: key, ofType: nil)
return path ?? ""
}
Когда я это писал, документация устарел. В моей версии флаттера 1.17.1 вот пример котлин андроид с необходимым импортом выше:
import android.content.Context
import io.flutter.embedding.engine.loader.FlutterLoader
import java.io.InputStream
val myAssetPath : Sting = "assets/my_asset"
val assetLookupKey = FlutterLoader.getInstance().getLookupKeyForAsset(myAssetPath)
val inputStream: InputStream = applicationContext.assets.open(assetLookupKey)
// Read in the file from the InputStream...
Следует отметить, что значение, возвращаемое этим методом getLookupKeyForAsset, обычно является путем к вашему ресурсу, поскольку он включен в ваш pubspec.yaml в разделе ресурсов, просто с префиксом «flutter_assets/». Таким образом, в случае приведенного выше примера он вернет flutter_assets/активы/мой_актив.
ОБНОВЛЕНИЕ ДЛЯ НОВОЙ ВЕРСИИ
Для флаттера версии 1.22 или выше Флаттерлоадер доступен только через Флаттеринжектор.
import io.flutter.FlutterInjector;
FlutterLoader loader = FlutterInjector.instance().flutterLoader();
String key = loader.getLookupKeyForAsset("assets_file_name");
а затем, как превратить ваш ключ в Drawable?
В проекте, над которым я работаю, используется устаревший пакет, который выдает ошибку в строке final FlutterLoader flutterLoader = FlutterLoader.getInstance()
, замена его вашим решением заставила его работать. Спасибо
пытались анализировать файл
.apk
, созданный инструментамиflutter run
/flutter build
? вы заметили, что он содержит папкуassets
в корне?