如何在 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;
           }
       }