如何使用Spotlight Xamarin.Android库在Xamarin.表单页面



我想在用户打开应用程序时第一次安装一个库来聚焦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。

它工作得很好,但现在他们是一个问题与聚光灯代码。在ControlSpotLightService.cs中,Target()需要一个名为view的参数。当我使用Xamarin.Forms.View view时,它显示为Cannot convert form 'Xamarin.Forms.ImageButton' to 'Android.Views.View'

但是当我使用Android.View时,在Views/IntroPage.xml.cs中我无法访问SettingsButton,我想聚焦。

Views/IntroPage.xml.cs

public partial class IntroPage : ContentPage
{
public IntroPage()
{
DependencyService.Get<ISpotLight>().ShowIntro(SettingsButton, "settings");

InitializeComponent();
}
}

ServicesISpotLight.cs

using Xamarin.Forms;
namespace Mobile.App.Services
{
public interface ISpotLight
{
void ShowIntro(View view, string usageId);
}
}

ControlSpotLightService.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.ViewAndroid.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)tonew SpotlightView.Builder(MainActivity.Instance).

    InstanceMainActivity中定义的字段。

    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;
    }
    }