Xamarin.Forms:无法访问文件夹中的图像

时间:2018-07-23 10:21:58

标签: xaml xamarin xamarin.forms

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

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

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

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

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

这行不起作用: <Image Source="Logos\btc.png" HeightRequest="20" WidthRequest="20" />

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

2 个答案:

答案 0 :(得分:2)

TL; DR:请勿使用子文件夹。 ;-)

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

但是,Resources.在使用反向查找时(从名称到Android资源ID)将无法找到那些图像,因此将不匹配。

在iOS上,也已不建议使用Xamarin.Android文件夹通过Xamarin.Forms来存储图像,而应该使用“资产目录图像集”。

有关更多信息:Images in Xamarin.Forms

答案 1 :(得分:2)

是的,很遗憾,您不能为Android图像使用子文件夹,但可以为其他2个平台使用子文件夹,并且要考虑到差异,这是我通常所做的。

使用以下AssetPathHelper(根据您的需要进行修改,在下文中,我仅对UWP图像使用子文件夹,对于Lottie动画,在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}}"/>