Xaml 在登录页面Xamarin上打开键盘时向上滚动屏幕

Xaml 在登录页面Xamarin上打开键盘时向上滚动屏幕,xaml,xamarin,xamarin.forms,scrollview,Xaml,Xamarin,Xamarin.forms,Scrollview,我正在研究Xamarin.Forms。我有一个登录页面,我正在使用带有ScrollView的StackLayout。 代码跟踪 <?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:Cla

我正在研究Xamarin.Forms。我有一个登录页面,我正在使用带有ScrollView的StackLayout。 代码跟踪

<?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="simpleListView.Pages.LoginPage">
<ContentPage.Content>
    <ScrollView Orientation="Vertical" x:Name="scroll">
    <StackLayout Padding="20">
        <Label Margin="20" HorizontalOptions="Center" Text="Login below" ></Label>
        <BoxView HeightRequest="150" Color="Accent"></BoxView>
        <Entry  Text="{Binding Email}" x:Name="txtEmail" Placeholder="Email"></Entry>
        <Entry Text="{Binding Password}" x:Name="txtPass" Placeholder="Paasword"></Entry>
        <Button x:Name="btnLogin" BackgroundColor="Blue" Text="Login" Command="{Binding SubmitCommand}"></Button>
    </StackLayout>
    </ScrollView>
</ContentPage.Content>
</ContentPage>

但上面的代码在键盘打开时并没有向顶部滚动布局&隐藏了几乎一半的登录按钮。键盘打开时如何实现滚动?我对使用自定义渲染器不太感兴趣

请参阅登录页面screeshot

因为(据我所知)没有好办法通过DependencyService获得android的实际键盘高度,所以使用滚动视图是正确的开始方法,但是您要做的是UI定制,这会导致定制渲染器。说“我想要一个很酷的自定义UI,但我对自定义渲染器不感兴趣”就像“我想开车,但我对轮子不感兴趣”

但是,为了让您更容易,我碰巧有一个自定义渲染器的代码,它提供了所需的结果:

Android

[assembly: ExportRenderer(typeof(ModernLogin), typeof(ModernLoginPageRenderer))]
namespace MyApp.Droid.Renderer
{
public class ModernLoginPageRenderer : PageRenderer
{
    public ModernLoginPageRenderer(Context context) : base(context)
    {

    }
    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);


        // Set SoftInput.AdjustResize for this window
        if (e.NewElement != null)
        {
            (this.Context as FormsApplicationActivity).Window.SetSoftInputMode(SoftInput.AdjustResize);             
        }
    }

    protected override void OnWindowVisibilityChanged([GeneratedEnum] ViewStates visibility)
    {
        // Revert to default SoftInputMode after moving away from this window
        if (visibility == ViewStates.Gone)
        {
            (this.Context as FormsApplicationActivity).Window.SetSoftInputMode(SoftInput.AdjustPan);
        }
        base.OnWindowVisibilityChanged(visibility);
    }

    protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
    {
        base.OnLayout(changed, left, top, right, bottom);
    }
}
}
确保将“ModernLogin”的名称替换为登录页面类的名称。如果您的登录页面是常规ContentPage,我建议您创建一个从ContentPage继承的新类

[assembly: ExportRenderer(typeof(ModernLogin), typeof(ModernLoginPageRenderer))]

namespace MyApp.iOS.Renderer
{
public class ModernLoginPageRenderer : PageRenderer
{
    NSObject observerHideKeyboard;
    NSObject observerShowKeyboard;

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var cp = Element as ModernLogin;
        if (cp != null)
        {
            foreach (var g in View.GestureRecognizers)
            {
                g.CancelsTouchesInView = true;
            }
        }
    }

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);

        observerHideKeyboard = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, OnKeyboardNotification);
        observerShowKeyboard = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, OnKeyboardNotification);
    }

    public override void ViewWillDisappear(bool animated)
    {
        base.ViewWillDisappear(animated);

        NSNotificationCenter.DefaultCenter.RemoveObserver(observerHideKeyboard);
        NSNotificationCenter.DefaultCenter.RemoveObserver(observerShowKeyboard);
    }

    void OnKeyboardNotification(NSNotification notification)
    {
        if (!IsViewLoaded) return;

        var frameBegin = UIKeyboard.FrameBeginFromNotification(notification);
        var frameEnd = UIKeyboard.FrameEndFromNotification(notification);

        var page = Element as ModernLogin;
        if (page != null)
        {
            var padding = page.Padding;
            page.Padding = new Thickness(padding.Left, padding.Top, padding.Right, padding.Bottom + frameBegin.Top - frameEnd.Top);
        }
    }
}
}