如何在 Xamarin.Forms 页面中使用 Spotlight Xamarin.Android 库
How to use Spotlight Xamarin.Android Library in Xamarin.Forms Pages
我想安装一个库以在用户打开应用程序时首次聚焦 First Page
。为此,我找到了这个名为 AndroidSpotlight 的惊人库,但问题是我无法将其安装在 Xamarin.Forms
项目中,因为它仅适用于 Xamarin.Android
.
当我尝试为 Xamarin.Forms
项目安装它时,出现了这个错误。
Package Android.Spotlight 2019.11.14.1 is not compatible with netstandard2.1 (.NETStandard,Version=v2.1). Package Android.Spotlight 2019.11.14.1 supports: monoandroid10 (MonoAndroid,Version=v1.0)
但是第一页在 Xamarin.Forms
中,所以我如何使用他们的这个库?
Views/IntroPage.xml
(我要强调的是ImageButton
)
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Mobile.App.Views.IntroPage"
xmlns:local="clr-namespace:Mobile.App.Control"
NavigationPage.HasNavigationBar="False">
<ContentPage.Content>
<StackLayout>
<StackLayout VerticalOptions="Start">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<ImageButton x:Name="SettingsButton"
Source="drawable/icon.png"
WidthRequest="20"
HeightRequest="20"
HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand"
Command="{Binding SettingsButtonCommand}">
</ImageButton>
</Grid>
</Grid>
</StackLayout>
<StackLayout HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand">
// Code
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
更新
@Jason推荐使用DependencyService.
它工作正常,但现在 Spotlight Code 出现了问题。在 Control\SpotLightService.cs
中,Target()
需要一个名为 view
的参数。当我使用 Xamarin.Forms.View view
时,它显示 Cannot convert form 'Xamarin.Forms.ImageButton' to 'Android.Views.View'
。
但是当我使用 Android.View
时,在 Views/IntroPage.xml.cs
中我无法访问 SettingsButton
,我想要 Spotlight。
Views/IntroPage.xml.cs
public partial class IntroPage : ContentPage
{
public IntroPage()
{
DependencyService.Get<ISpotLight>().ShowIntro(SettingsButton, "settings");
InitializeComponent();
}
}
Services\ISpotLight.cs
using Xamarin.Forms;
namespace Mobile.App.Services
{
public interface ISpotLight
{
void ShowIntro(View view, string usageId);
}
}
Control\SpotLightService.cs
使用来自 AndroidSpotlight
的代码
[assembly: Xamarin.Forms.Dependency(typeof(SpotLightService))]
namespace Mobile.App.Droid.Control
{
public class SpotLightService : ISpotLight
{
private bool isRevealEnabled = true;
private SpotlightView spotLight;
public void ShowIntro(Xamarin.Forms.View view, string usageId)
{
spotLight = new SpotlightView.Builder((Activity)Application.Context)
.IntroAnimationDuration(400)
.EnableRevealAnimation(isRevealEnabled)
.PerformClick(true)
.FadeinTextDuration(400)
.HeadingTvColor(Color.ParseColor("#eb273f"))
.HeadingTvSize(32)
.HeadingTvText("Love")
.SubHeadingTvColor(Color.ParseColor("#ffffff"))
.SubHeadingTvSize(16)
.SubHeadingTvText("Like the picture?\nLet others know.")
.MaskColor(Color.ParseColor("#dc000000"))
.Target(view)
.LineAnimDuration(400)
.LineAndArcColor(Color.ParseColor("#eb273f"))
.DismissOnTouch(true)
.DismissOnBackPress(true)
.EnableDismissAfterShown(true)
.UsageId(usageId)
.ShowTargetArc(true)
.Show();
}
}
}
将Xamarin.Forms.View
转换为Android.Views.View
,可以试试下面的代码.
public View ConvertFormsToNative(Xamarin.Forms.View view)
{
var vRenderer = Platform.CreateRendererWithContext(view, MainActivity.Instance);
var Androidview = vRenderer.View;
vRenderer.Tracker.UpdateLayout();
var size = view.Bounds;
var layoutParams = new ViewGroup.LayoutParams((int)size.Width, (int)size.Height);
Androidview.LayoutParameters = layoutParams;
view.Layout(size);
Androidview.Layout(0, 0, (int)view.WidthRequest, (int)view.HeightRequest);
Androidview.SetBackgroundColor(Color.Red);
return Androidview;
}
并且 target
应该设置为 .Target(ConvertFormsToNative(view))
将new SpotlightView.Builder((Activity)Application.Context)
改为new SpotlightView.Builder(MainActivity.Instance)
.
Instance
是在 MainActivity
中定义的字段。
public static MainActivity Instance;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
Instance = this;
将 Dependency service
的调用从构造函数移动到 LayoutChanged
事件。
public Page1()
{
InitializeComponent();
this.LayoutChanged += Page1_LayoutChanged;
}
bool isShown = false;
private void Page1_LayoutChanged(object sender, EventArgs e)
{
if (!isShown)
{
DependencyService.Get<ISpotLight>().ShowIntro(SettingsButton, "settings");
isShown = true;
}
}
我想安装一个库以在用户打开应用程序时首次聚焦 First Page
。为此,我找到了这个名为 AndroidSpotlight 的惊人库,但问题是我无法将其安装在 Xamarin.Forms
项目中,因为它仅适用于 Xamarin.Android
.
当我尝试为 Xamarin.Forms
项目安装它时,出现了这个错误。
Package Android.Spotlight 2019.11.14.1 is not compatible with netstandard2.1 (.NETStandard,Version=v2.1). Package Android.Spotlight 2019.11.14.1 supports: monoandroid10 (MonoAndroid,Version=v1.0)
但是第一页在 Xamarin.Forms
中,所以我如何使用他们的这个库?
Views/IntroPage.xml
(我要强调的是ImageButton
)
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Mobile.App.Views.IntroPage"
xmlns:local="clr-namespace:Mobile.App.Control"
NavigationPage.HasNavigationBar="False">
<ContentPage.Content>
<StackLayout>
<StackLayout VerticalOptions="Start">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<ImageButton x:Name="SettingsButton"
Source="drawable/icon.png"
WidthRequest="20"
HeightRequest="20"
HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand"
Command="{Binding SettingsButtonCommand}">
</ImageButton>
</Grid>
</Grid>
</StackLayout>
<StackLayout HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand">
// Code
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
更新
@Jason推荐使用DependencyService.
它工作正常,但现在 Spotlight Code 出现了问题。在 Control\SpotLightService.cs
中,Target()
需要一个名为 view
的参数。当我使用 Xamarin.Forms.View view
时,它显示 Cannot convert form 'Xamarin.Forms.ImageButton' to 'Android.Views.View'
。
但是当我使用 Android.View
时,在 Views/IntroPage.xml.cs
中我无法访问 SettingsButton
,我想要 Spotlight。
Views/IntroPage.xml.cs
public partial class IntroPage : ContentPage
{
public IntroPage()
{
DependencyService.Get<ISpotLight>().ShowIntro(SettingsButton, "settings");
InitializeComponent();
}
}
Services\ISpotLight.cs
using Xamarin.Forms;
namespace Mobile.App.Services
{
public interface ISpotLight
{
void ShowIntro(View view, string usageId);
}
}
Control\SpotLightService.cs
使用来自 AndroidSpotlight
的代码[assembly: Xamarin.Forms.Dependency(typeof(SpotLightService))]
namespace Mobile.App.Droid.Control
{
public class SpotLightService : ISpotLight
{
private bool isRevealEnabled = true;
private SpotlightView spotLight;
public void ShowIntro(Xamarin.Forms.View view, string usageId)
{
spotLight = new SpotlightView.Builder((Activity)Application.Context)
.IntroAnimationDuration(400)
.EnableRevealAnimation(isRevealEnabled)
.PerformClick(true)
.FadeinTextDuration(400)
.HeadingTvColor(Color.ParseColor("#eb273f"))
.HeadingTvSize(32)
.HeadingTvText("Love")
.SubHeadingTvColor(Color.ParseColor("#ffffff"))
.SubHeadingTvSize(16)
.SubHeadingTvText("Like the picture?\nLet others know.")
.MaskColor(Color.ParseColor("#dc000000"))
.Target(view)
.LineAnimDuration(400)
.LineAndArcColor(Color.ParseColor("#eb273f"))
.DismissOnTouch(true)
.DismissOnBackPress(true)
.EnableDismissAfterShown(true)
.UsageId(usageId)
.ShowTargetArc(true)
.Show();
}
}
}
将
Xamarin.Forms.View
转换为Android.Views.View
,可以试试下面的代码.public View ConvertFormsToNative(Xamarin.Forms.View view) { var vRenderer = Platform.CreateRendererWithContext(view, MainActivity.Instance); var Androidview = vRenderer.View; vRenderer.Tracker.UpdateLayout(); var size = view.Bounds; var layoutParams = new ViewGroup.LayoutParams((int)size.Width, (int)size.Height); Androidview.LayoutParameters = layoutParams; view.Layout(size); Androidview.Layout(0, 0, (int)view.WidthRequest, (int)view.HeightRequest); Androidview.SetBackgroundColor(Color.Red); return Androidview; }
并且
target
应该设置为.Target(ConvertFormsToNative(view))
将
new SpotlightView.Builder((Activity)Application.Context)
改为new SpotlightView.Builder(MainActivity.Instance)
.Instance
是在MainActivity
中定义的字段。public static MainActivity Instance; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); Instance = this;
将
Dependency service
的调用从构造函数移动到LayoutChanged
事件。public Page1() { InitializeComponent(); this.LayoutChanged += Page1_LayoutChanged; } bool isShown = false; private void Page1_LayoutChanged(object sender, EventArgs e) { if (!isShown) { DependencyService.Get<ISpotLight>().ShowIntro(SettingsButton, "settings"); isShown = true; } }