首页 文章

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

提问于
浏览
2

我正在研究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

enter image description here

1 回答

  • 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的新类 .

相关问题