Xamarin 在 Android 中在框架上形成阴影
Xamarin forms Shadow on Frame in Android
Xamarin Forms 中的 Frame class 非常有限,不能让我在 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 原生的了解有点有限。谁能告诉我要看什么,也许是一些好的代码示例?我还没有找到与此类似的内容。
在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.
我能够在 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
}
}
}
我知道这个问题很老了,但是有一种更新的方法可以获得比接受的答案更好的阴影效果。从 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());
}
}
}
}
希望这对像我一样偶然发现这里的人有所帮助。
Xamarin Forms 中的 Frame class 非常有限,不能让我在 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 原生的了解有点有限。谁能告诉我要看什么,也许是一些好的代码示例?我还没有找到与此类似的内容。
在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.
我能够在 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
}
}
}
我知道这个问题很老了,但是有一种更新的方法可以获得比接受的答案更好的阴影效果。从 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());
}
}
}
}
希望这对像我一样偶然发现这里的人有所帮助。