【问题标题】:Xamarin forms Shadow on Frame in AndroidXamarin 在 Android 中在框架上形成阴影
【发布时间】:2017-07-19 05:50:57
【问题描述】:

Xamarin Forms 中的 Frame 类非常有限,不能让我在 Frame 后面看到阴影。我使用以下代码为 iOS 制作了一个自定义渲染器:

public class RatingInfoFrameRenderer : FrameRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
    {
        base.OnElementChanged(e);

        Layer.BorderColor = UIColor.White.CGColor;
        Layer.CornerRadius = 10;
        Layer.MasksToBounds = false;
        Layer.ShadowOffset = new CGSize(-2, 2);
        Layer.ShadowRadius = 5;
        Layer.ShadowOpacity = 0.4f;
    }
}

在 Android 上制作类似的东西给我带来了问题,因为我对 Android 原生的了解有限。谁能告诉我要看什么,也许是一些好的代码示例?我还没有找到类似的东西。

【问题讨论】:

    标签: xamarin xamarin.android xamarin.forms custom-renderer


    【解决方案1】:

    在Android平台上可以很简单,但首先你需要在Android资源的Drawable文件夹下创建你的影子。例如:

    <?xml version="1.0" encoding="utf-8" ?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
      <item>
        <shape android:shape="rectangle">
          <solid android:color="#CABBBBBB" />
          <corners android:radius="2dp" />
        </shape>
      </item>
    
      <item
          android:left="0dp"
          android:right="0dp"
          android:top="0dp"
          android:bottom="2dp">
        <shape android:shape="rectangle">
          <solid android:color="@android:color/white" />
          <corners android:radius="2dp" />
        </shape>
      </item>
    </layer-list>
    

    将此文件命名为“shadow.xml”并将其放在Android项目的Drawable文件夹下,然后在您的RatingInfoFrameRenderer中:

    public class RatingInfoFrameRenderer : FrameRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                ViewGroup.SetBackgroundResource(Resource.Drawable.shadow);
            }
        }
    }
    

    要改变阴影的样式,可以修改shadow.xml文件,更多信息可以参考google官方文档:LayerList

    【讨论】:

    • 谢谢,但需要注意一件事。必须添加填充,否则它不会呈现任何效果。
    【解决方案2】:

    我知道这个问题很老,但是有一种更新的方法可以获得比公认答案更好的阴影效果。从Xamarin.Forms.Platform.Android.FastRenderers.FrameRenderer继承,然后使用SetOutlineSpotShadowColor(Color color)设置阴影颜色。您也可以使用CardElevation 来确定阴影的强度和传播范围。

    [assembly: ExportRenderer(typeof(Myframe), typeof(MyFrameRenderer))]
    namespace MyApp.Droid.Renderers
    {
        public class MyFrameRenderer: Xamarin.Forms.Platform.Android.FastRenderers.FrameRenderer
        {
            public MyFrameRenderer(Context context) : base(context)
            {
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
            {
                base.OnElementChanged(e);
    
                CardElevation = 10;
    
                if(((App)Application.Current).Theme != Core.Enums.Theme.Dark)
                {
                    SetOutlineSpotShadowColor(Xamarin.Forms.Color.Gray.ToAndroid());
                }
                else
                {
                    SetOutlineSpotShadowColor(Xamarin.Forms.Color.HotPink.ToAndroid());
                }
            }
        }
    }
    

    希望这可以帮助像我一样在这里绊倒的人。

    【讨论】:

      【解决方案3】:

      我能够在 Xamarin Forms 中为框视图获得阴影效果,我很确定它可以类似地用于框架。我从Android Documentation得到了线索

      我添加了一个名为 HasShadow 的新属性

              public static readonly BindableProperty HasShadowProperty =
                  BindableProperty.Create("HasShadow", typeof(bool), typeof(ExtendedBoxView), false);
      
              public bool HasShadow
              {
                  get { return (bool)GetValue(HasShadowProperty); }
                  set { SetValue(HasShadowProperty, value); }
              }
      

      这是 Android 中渲染器的代码

             public class ExtendedBoxViewRenderer : BoxRenderer
      {
          protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
          {
              base.OnElementChanged(e);
              var element = e.NewElement as ExtendedBoxView;
      
      
              if (element == null) return;
      
              if (element.HasShadow)
              {
                  ViewGroup.Elevation = 8.0f;
                  ViewGroup.TranslationZ = 10.0f;
      
      
              }
      
          }
      
      }
      

      这就是它的外观

      更新

      我发现这种方法会导致旧版 Android 的应用崩溃。虽然我还没有找到在 Lollipop 之前的 Android 版本中显示阴影的方法。这将防止任何应用程序崩溃

          public class ExtendedBoxViewRenderer : BoxRenderer
          {
              protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
              {
                  base.OnElementChanged(e);
                  var element = e.NewElement as ExtendedBoxView;
      
      
                  if (element == null) return;
      
                  if (element.HasShadow)
                  {
      //For some reason ViewCompat has issues when running in debug hence the workaround.
      #if DEBUG
                      double dAndroidVersion;
                      if (double.TryParse(Build.VERSION.Release, out dAndroidVersion))
                      {
                          if (dAndroidVersion < 21)
                              return;
                      }
      #else
                      ViewCompat.SetElevation(ViewGroup, 8.0f);
                      ViewCompat.SetTranslationZ(ViewGroup, 10.0f);
      #endif
                  }
      
              }
      
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-13
        • 1970-01-01
        • 2019-03-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多