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

时间:2018-08-03 12:32:33

标签: xaml xamarin xamarin.forms scrollview

我正在处理Xamarin.Forms。我有登录页面,我正在将StackLayout与ScrollView一起使用。 遵循代码

<?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>

但是,当键盘打开并隐藏“登录”按钮的几乎一半时,上面的代码未将布局朝顶部滚动。打开键盘时如何实现滚动?我对使用自定义渲染器不太感兴趣。

查看登录页面截图

enter image description here

1 个答案:

答案 0 :(得分:1)

由于(据我所知)没有一种好的方法可以通过DependencyService获取android的实际键盘高度,因此使用scrollview是正确的开始方法,但是您要做的是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);
    }
}
}

iOS

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

确保将“ ModernLogin”的名称替换为登录页面类的名称。如果您的LoginPage是常规的ContentPage,建议您创建一个从ContentPage继承的新类。