【问题标题】:Xamarin.Forms: Can't access images in folderXamarin.Forms:无法访问文件夹中的图像
【发布时间】:2018-12-30 18:31:10
【问题描述】:

我有一个非常基本的 Xamarin.Forms 应用程序,我尝试在其中访问图像。当图像位于必要的文件夹中时,这可以正常工作,例如

  • \Resources\btc.png 对于 iOS
  • \Resouces\Drawable\btc.png Android 版
  • 根文件夹\btc.png 用于 UWP

但是,当我将文件夹添加到组合中时,它不会显示任何内容:

  • \Resources\Logos\btc.png 对于 iOS
  • \Resouces\Drawable\Logos\btc.png Android
  • 根文件夹\Logos\btc.png 用于 UWP

这是我正在使用的线路: <Image Source="btc.png" HeightRequest="20" WidthRequest="20" />

这是行不通的行: <Image Source="Logos\btc.png" HeightRequest="20" WidthRequest="20" />

我对所有反斜杠和拼写/大写字母进行了三次检查。

【问题讨论】:

  • 我还要补充一点:我正在以同样的方式将图像拖到解决方案中,并且已经尝试了多次。
  • 这个实现可能就是你要找的那个。 Add image in another folder.(Android).
  • @Wildchild 我绝对不会使用将图像(在这种情况下为 1500 个)嵌入到最终组件中的方法(强制内存膨胀和性能问题会比比皆是)。

标签: xaml xamarin xamarin.forms


【解决方案1】:

TL;DR:不要使用子文件夹。 ;-)

在 Android 上,当使用 Drawable 文件夹(以及像素密度文件夹,即:drawable-xxhpdi)中的子文件夹时,子文件夹名称将被忽略,但 drawable 的 ID 会在 Java R. 文件中生成(C# Resources. in Xamarin.Android),假设没有无效名称或冲突。因此,在原生 Android 和 Xamarin.Android 中,这些可绘制对象将分配一个资源 ID(基于整数)并且可以使用。

但是,Xamarin.Forms 将无法找到这些图像,因为使用了从名称到 Android 资源 ID 的反向查找,因此将不匹配。

同样在 iOS 上,通过BundleResource 使用Resource 文件夹来存储图像已被弃用,您应该改用“资产目录图像集”。

欲了解更多信息:Images in Xamarin.Forms

【讨论】:

  • 感谢您的描述性回答。我将遇到的问题是,当应用程序最终完成时,我将拥有超过 1500 张图像。图片不是很大,每张大约 1KB,这只是它填满了我的解决方案的问题。
  • @MattWard 除了没有在解决方案资源管理器中展开“Drawable”文件夹外,您实际上并没有做太多;-/ ... Xamarin 只是没有一个像样的解决方案来处理大型媒体在 Visual Studio 中设置类似的设置。 Android Studio(和 Xcode)允许您创建模块并将媒体移出核心项目,但在编译时,这些媒体模块被视为实际位于核心项目中,因此资源标识等被正确生成。跨度>
【解决方案2】:

是的,很遗憾,您不能将子文件夹用于 android 图像,但您可以将其用于其他 2 个平台,并考虑到这里的差异,这就是我通常所做的。

使用以下 AssetPathHelper(根据您的需要进行修改,在下面我只对 UWP 图像使用子文件夹,而对于乐天动画我在 UWP 和 iOS 中都使用子文件夹)。我还假设.png,如果您使用其他图像类型,则需要处理它。

public static class AssetPathHelper
{
    public static readonly string UWPimgRoot = @"Assets\Images\";
    public static readonly string UWPanimRoot = @"Assets\Animations\";
    public static readonly string iOSanimRoot = @"Animations/"; //note the different slash here, not sure if it's required but that is what works

    public static string GetImageSource(string resourceName)
    {
        var imgFileName = resourceName + ".png"; //! obviously this requires all images used to be pngs

        if (Device.RuntimePlatform != Device.UWP)
            return imgFileName;

        return UWPimgRoot + imgFileName;
    }
    public static string GetLottieAnimSource(string resourceName)
    {
        var animFileName = resourceName + ".json";

        switch (Device.RuntimePlatform)
        {
            case Device.iOS:
                return iOSanimRoot + animFileName;
            case Device.UWP:
                return UWPanimRoot + animFileName;
        }
        return animFileName;
    }
}

在以下转换器中使用:

/// <summary>
/// Provides the path to the image taking into account the platform specific location.
/// Can be used without a real binding (i.e. when only a parameter is provided)
/// </summary>
public class ImagePathConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (parameter != null)
            return AssetPathHelper.GetImageSource(parameter.ToString());
        return AssetPathHelper.GetImageSource(value.ToString());
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

所以现在我可以在我的 XAML 中执行此操作,如果图像会发生变化,则作为真正的绑定,否则,只需将图像名称作为转换器参数传递:

        <Image
            Source="{Binding ConverterParameter=logo_splash, Converter={StaticResource ImagePathConverter}}"/>

【讨论】:

    猜你喜欢
    • 2013-11-04
    • 2016-10-03
    • 2017-06-18
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 2013-11-24
    • 2012-03-28
    相关资源
    最近更新 更多