【问题标题】:Xamarin - Does Android Drawable Exist?Xamarin - Android Drawable 存在吗?
【发布时间】:2019-01-04 19:55:04
【问题描述】:

在 Xamarin Forms (3.0) 应用程序中,我将使用什么方法从共享项目代码中判断我的 Android 项目中是否存在可绘制资源?

在 iOS 中,我可以使用 NSFileManager 查看文件是否存在于我的 iOS 项目的“资源”文件夹中:

#if __IOS__
private bool DoesImageExist(string image)
{
    //WORKS
    return Foundation.NSFileManager.DefaultManager.FileExists(image);
}
#endif

在 Android 中,我认为它应该是程序集资源的一部分,但这只是返回我的 App.xaml 文件。

#if __ANDROID__
private bool DoesImageExist(string image)
{
    //DOES NOT WORK
    if(MyApp.Current?.GetType() is Type type)
        foreach (var res in Assembly.GetAssembly(type).GetManifestResourceNames())
        {
            if (res.Equals(image, StringComparison.CurrentCultureIgnoreCase))
                return true;
        }
    return false;
}
#endif

【问题讨论】:

    标签: android xamarin.forms resources drawable


    【解决方案1】:

    如何在 android 中按名称专门检查是否存在可绘制对象将像这样工作:

    #if __ANDROID__
    public bool DoesImageExist(string image)
    {
        var context = Android.App.Application.Context;
        var resources = context.Resources;
        var name = Path.GetFileNameWithoutExtension(image);
        int resourceId = resources.GetIdentifier(name, "drawable", context.PackageName);
    
        return resourceId != 0;
    }
    #endif
    

    如果您的代码在 pcl 或 .net 标准程序集中,则必须创建一个抽象。某种 Ioc 库可以很好地解决这个问题。您还可以让 Android 或 iOS 实现抽象接口,并在某处将其作为单例提供。它没有那么优雅,但它会起作用。

    基本上你会实现这样的:

    public interface IDrawableManager
    {
        bool DoesImageExist(string path);
    }
    

    然后有两个实现:

    public class DroidDrawableManager : IDrawableManager
    {
            var context = Android.App.Application.Context;
            var resources = context.Resources;
            var name = Path.GetFileNameWithoutExtension(image);
            int resourceId = resources.GetIdentifier(name, "drawable", context.PackageName);
    
            return resourceId != 0;
    }
    
    public class IOSDrawableManager : IDrawableManager
    {
        public bool DoesImageExist(string image)
        {
            return Foundation.NSFileManager.DefaultManager.FileExists(image);
        }
    }
    

    我已将一个工作示例上传到 github:

    https://github.com/curtisshipley/ResourceExists

    【讨论】:

    • 看起来我们走在正确的道路上,但我收到了Error CS7036 There is no argument given that corresponds to the required formal parameter 'defPackage' of 'Resources.GetIdentifier(string, string, string)'
    • resources.GetIdentifier(image, "drawable", context.PackageName); 不返回任何内容
    • 您可能需要删除扩展。
    • 添加包名称并删除扩展对我有用。我已经将一个工作示例上传到 github。
    • 您的示例有效,它回答了核心问题“如何”,但我仍然无法使其在我的应用程序中工作,即使将您的示例重建为 DLL 并引用它也不起作用。我的 PackageName 与我的项目的 Android Manifest 匹配。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多