【问题标题】:Referring Android vector resource in Xamarin - PCL?在 Xamarin - PCL 中引用 Android 矢量资源?
【发布时间】:2016-12-02 11:56:49
【问题描述】:

我在每个平台上都有图标资源,并使用 OnPlatform 引用 png 图像。像下面的代码一样引用矢量 xml 会很好。

MapIconImage.Source = Device.OnPlatform(
            iOS: ImageSource.FromFile("Icons/location_pin.png"),
            Android: ImageSource.FromFile("location_pin.xml"),
            WinPhone: ImageSource.FromFile("Icons/location_pin.png"));

其中 location_pin.xml 是 android 向量 xml

我知道可以将 png 与相应的 dpi 文件夹一起使用。但这个是更好的 IMO。

有什么方法可以在 Xamarin - PCL 中引用 Android 矢量资源?

【问题讨论】:

  • 你认为不可能吗?您是在说一般意义上的地图还是图像?
  • 我最近回答了一个关于单选按钮矢量源的问题,因此可以在Android中为图像分配矢量xml。您可能需要自定义渲染器(或不需要:-))
  • @YuriS 它与地图无关。只是一个 imagebutton 的图标。

标签: android xamarin.forms


【解决方案1】:

您可以使用简单的按钮自定义渲染器来做到这一点。

页面:

public class VectorImageSourceAndroidPage : ContentPage
{
    public VectorImageSourceAndroidPage()
    {

        Content = new StackLayout
        {
            Children = {
                new VectorImageButton() {
                    HorizontalOptions=LayoutOptions.CenterAndExpand,
                    VerticalOptions=LayoutOptions.CenterAndExpand,
                    WidthRequest=70,
                    HeightRequest=70,
                    BackgroundColor=Color.Blue,

                     Source = Device.OnPlatform(
                        iOS: "",
                        Android: "woman",
                        WinPhone: "")
                }
            }
        };
    }
}

public class VectorImageButton : Button
{
    public string Source { get; set; }
}

渲染器:

[assembly: ExportRenderer(typeof(VectorImageButton), typeof(VectorImageRenderer))]
namespace ButtonRendererDemo.Droid
{
    public class VectorImageRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                var button = (VectorImageButton)e.NewElement;
                var resourceId = (int)typeof(Resource.Drawable).GetField(button.Source).GetValue(null);

                Control.Background = Context.GetDrawable(resourceId);
            }
        }
    }
}

可绘制文件夹中的资源:

女人.xml

<?xml version="1.0" encoding="UTF-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"
            android:id="@+id/shapeBg">
      <solid android:color="#ff69b4"/>
      <size android:width="70dp" android:height="70dp"/>
    </shape>
  </item>
  <item android:drawable="@drawable/woman_path"/>
</layer-list>

woman_path.xml

<?xml version="1.0" encoding="UTF-8" ?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="70dp"
    android:height="70dp"
    android:viewportWidth="70"
    android:viewportHeight="70">
  <path
      android:fillColor="#ffffff"
      android:pathData="M43 45l-6 0 0 -5c6,-1 11,-6 11,-13 0,-7 -6,-13 -13,-13 -7,0 -13,6 -13,13 0,7
5,12 11,13l0 5 -6 0c-2,0 -2,3 0,3l6 0 0 6c0,2 4,2 4,0l0 -6 6 0c2,0 2,-3
0,-3zm-18 -18c0,-5 5,-10 10,-10 5,0 10,5 10,10 0,5 -5,10 -10,10 -5,0 -10,-5
-10,-10z" />
</vector>

【讨论】:

    【解决方案2】:

    我正在寻找类似的东西,并使用特定于平台的 ImageRenderer 找到了解决方案。由于 ImageRenderer 可以特定于 Android,因此您可以使用它们的矢量可绘制对象。为此,您首先在共享表单项目中创建:

    namespace MyApp
    {
        public class VectorImage : Image
        {
            public string ImageSource { get; set; }
        }
    }
    

    用对应的xaml:

    <myApp:VectorImage ImageSource="location_pin" Aspect="AspectFill" WidthRequest="50" HeightRequest="50" />
    

    然后在你的android项目中添加特定的(矢量)ImageRenderer:

    [assembly: ExportRenderer(typeof(VectorImage), typeof(VectorImageRenderer))]
    namespace MyApp.Droid
    {
        public class VectorImageRenderer : ImageRenderer
        {
            protected override bool DrawChild(Canvas canvas, global::Android.Views.View child, long drawingTime)
            {
                var imageSource = ((VectorImage) Element).ImageSource;
                var vectorDrawable = Context.Resources.GetDrawable(imageSource);
                vectorDrawable.SetBounds(0, 0, Width, Height);
                vectorDrawable.Draw(canvas);
                return base.DrawChild(canvas, child, drawingTime);
            }
        }
    }
    

    应该不错了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      • 2017-11-05
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      相关资源
      最近更新 更多