能否在Xamarin Shared Project中嵌入多分辨率图片作为资源文件?
解决方案
原生平台的多分辨率适配逻辑不会自动作用于共享项目的嵌入式资源,你可以通过自定义XAML标记扩展实现相同的自动匹配效果,所有图片仍然存放在共享项目中无需拆分到各平台项目。
操作步骤
- 首先统一图片命名规范,将你提到的
addnew.scale.400.png修正为addnew.scale-400.png,保持所有后缀格式为scale-[百分比].png,所有图片放入共享项目的Images文件夹,生成操作统一设置为EmbeddedResource。 - 确保项目已引入Xamarin.Essentials库并完成初始化配置,用于获取设备当前的屏幕缩放比例。
- 实现自定义分辨率感知的XAML标记扩展,代码示例如下:
using Xamarin.Essentials; using Xamarin.Forms; using Xamarin.Forms.Xaml; using System.Reflection; [ContentProperty(nameof(Source))] public class ScaledImageResourceExtension : IMarkupExtension<ImageSource> { public string Source { get; set; } public ImageSource ProvideValue(IServiceProvider serviceProvider) { if (string.IsNullOrEmpty(Source)) return null; // 获取当前设备缩放比例 var density = DeviceDisplay.MainDisplayInfo.Density; var scalePercent = (int)Math.Round(density * 100); // 拆解原始资源路径,比如FoodApp.Images.addnew.png 拆成前缀和后缀 var lastDotIndex = Source.LastIndexOf('.'); var pathWithoutExt = Source.Substring(0, lastDotIndex); var ext = Source.Substring(lastDotIndex); // 按从高到低优先级匹配对应scale的资源,可自行调整优先级顺序 var priorityScales = new[] { scalePercent, 400, 200, 150, 125, 100 }; var assembly = typeof(ScaledImageResourceExtension).GetTypeInfo().Assembly; foreach (var scale in priorityScales) { var scaledPath = $"{pathWithoutExt}.scale-{scale}{ext}"; if (assembly.GetManifestResourceInfo(scaledPath) != null) { return ImageSource.FromResource(scaledPath, assembly); } } // 兜底返回原始无scale后缀的资源 return ImageSource.FromResource(Source, assembly); } object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) { return ProvideValue(serviceProvider); } }
- 替换原有XAML中的图片引用方式,首先在页面头部引入自定义扩展的命名空间,比如
xmlns:local="clr-namespace:FoodApp",之后图片引用修改为:
<Image x:Name="imgAddNewProject" HeightRequest="30" WidthRequest="30" Source="{local:ScaledImageResource FoodApp.Images.addnew.png}"/>
补充说明
如果需要兼容iOS原生的@2x/@3x命名规则,可在标记扩展的匹配逻辑中增加对应映射关系即可,无需调整资源存放位置。
内容的提问来源于stack exchange,提问作者sidsud
相关产品推荐
相关产品推荐

