【问题标题】:The keyboard in my Xamarin Forms PCL Carousel Page covers my Entry fields我的 Xamarin Forms PCL Carousel 页面中的键盘覆盖了我的输入字段
【发布时间】:2017-09-13 06:40:52
【问题描述】:

我使用的是最新版本的 Xamarin Forms。我有一个带有内容页面的轮播页面。内容页面有一个滚动视图,它有一个包含一些标签和条目输入的堆栈布局。当我触摸 Entry 输入文本时,键盘盖住了输入框,所以我看不到我正在输入的内容。

我已经在一个基本应用程序上测试了这个功能,只使用了一个内容页面(没有轮播),它有 8 个标签和 8 个条目,当键盘按我的预期显示时,条目框会向上滚动(以保持在视图中) .

但是,当我使用将上述内容页面添加为子项的轮播页面时,键盘会覆盖我的输入字段。

所以,下面的工作:

    public App()
    {
        InitializeComponent();

        MainPage = new MainPage1();
    }


namespace App2
{

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MainPage1 : ContentPage
    {
        public MainPage1()
        {
            InitializeComponent();

            var vScrollView = new ScrollView
            {
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.FillAndExpand,
                Margin = new Thickness(0, 5, 15, 25),

            };
            var vStackLayout = new StackLayout
            {
                Orientation = StackOrientation.Vertical,
                Spacing = 10,
                HorizontalOptions = LayoutOptions.Start,
                VerticalOptions = LayoutOptions.Start,
                Margin = new Thickness(15, 0, 15, 25),
                WidthRequest = 700
            };

            //Create the form label for the item
            var lblItemLabel = new Label
            {
                Text = "Label 1",
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                Margin = new Thickness(10, 0, 0, 0),
            };
            vStackLayout.Children.Add(lblItemLabel);

            var entry = new Entry
            {
                //HorizontalOptions = LayoutOptions.Fill,
                MinimumWidthRequest = 300,
                Margin = new Thickness(20, 0, 15, 15),
            };
            vStackLayout.Children.Add(entry);

            var lblItemLabel2 = new Label
            {
                Text = "Label 2",
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                Margin = new Thickness(10, 0, 0, 0),
            };
            vStackLayout.Children.Add(lblItemLabel2);

            var entry2 = new Entry
            {
                //HorizontalOptions = LayoutOptions.Fill,
                MinimumWidthRequest = 300,
                Margin = new Thickness(20, 0, 15, 15),
            };
            vStackLayout.Children.Add(entry2);

            var lblItemLabel3 = new Label
            {
                Text = "Label 3",
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                Margin = new Thickness(10, 0, 0, 0),
            };
            vStackLayout.Children.Add(lblItemLabel3);

            var entry3 = new Entry
            {
                //HorizontalOptions = LayoutOptions.Fill,
                MinimumWidthRequest = 300,
                Margin = new Thickness(20, 0, 15, 15),
            };
            vStackLayout.Children.Add(entry3);

            var lblItemLabel4 = new Label
            {
                Text = "Label 4",
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                Margin = new Thickness(10, 0, 0, 0),
            };
            vStackLayout.Children.Add(lblItemLabel4);

            var entry4 = new Entry
            {
                //HorizontalOptions = LayoutOptions.Fill,
                MinimumWidthRequest = 300,
                Margin = new Thickness(20, 0, 15, 15),
            };
            vStackLayout.Children.Add(entry4);

            var lblItemLabel5 = new Label
            {
                Text = "Label 5",
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                Margin = new Thickness(10, 0, 0, 0),
            };
            vStackLayout.Children.Add(lblItemLabel5);

            var entry5 = new Entry
            {
                //HorizontalOptions = LayoutOptions.Fill,
                MinimumWidthRequest = 300,
                Margin = new Thickness(20, 0, 15, 15),
            };
            vStackLayout.Children.Add(entry5);

            var lblItemLabel6 = new Label
            {
                Text = "Label 6",
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                Margin = new Thickness(10, 0, 0, 0),
            };
            vStackLayout.Children.Add(lblItemLabel6);

            var entry6 = new Entry
            {
                //HorizontalOptions = LayoutOptions.Fill,
                MinimumWidthRequest = 300,
                Margin = new Thickness(20, 0, 15, 15),
            };
            vStackLayout.Children.Add(entry6);

            var lblItemLabel7 = new Label
            {
                Text = "Label 7",
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                Margin = new Thickness(10, 0, 0, 0),
            };
            vStackLayout.Children.Add(lblItemLabel7);

            var entry7 = new Entry
            {
                //HorizontalOptions = LayoutOptions.Fill,
                MinimumWidthRequest = 300,
                Margin = new Thickness(20, 0, 15, 15),
            };
            vStackLayout.Children.Add(entry7);

            var lblItemLabel8 = new Label
            {
                Text = "Label 8",
                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
                Margin = new Thickness(10, 0, 0, 0),
            };
            vStackLayout.Children.Add(lblItemLabel8);

            var entry8 = new Entry
            {
                //HorizontalOptions = LayoutOptions.Fill,
                MinimumWidthRequest = 300,
                Margin = new Thickness(20, 0, 15, 15),
            };
            vStackLayout.Children.Add(entry8);


            vScrollView.Content = vStackLayout;
            Content = vScrollView;
        }
    }

}

但是,当我创建一个 CarouselPage 并将上述内容页面作为子项添加到其中时,键盘不再将视图向上推。相反,它覆盖了 Entry 字段。

下面的,不起作用:

public App()
{
    InitializeComponent();

    MainPage = new CarouselPage1();
}

namespace App2
{

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class CarouselPage1 : CarouselPage
    {
        public CarouselPage1()
        {
            InitializeComponent();

            var page = new MainPage1(); //Same exact MainPage1 as in first code block above.
            this.Children.Add(page);
        }
    }
}

如何在使用 CarouselPage 时不覆盖我的输入字段来使键盘正常工作?

【问题讨论】:

  • 有人吗?当键盘出现时,它根本无法识别页面中的任何变化(我可以说)。我打算尝试使用 Page.Height 更改方法或 Page.LayoutChange 方法,但是当键盘出现时,它们都不能识别任何更改。任何人都知道如何编写解决方法?我需要同时打开 Windows 和 iOS。

标签: keyboard xamarin.forms


【解决方案1】:

我要非常感谢 Kym Phillpotts @ Microsoft(Xamarin 大学)提供的帮助和解决此问题的方法。感谢我的 Xamarin University 订阅,我能够使用 1:1 的课堂时间与 Kym 一起审查这个问题,他最终为我提供了以下代码作为修复。

该修复适用于 UWP 和 WinPhone 8.1(iOS 没有该错误)。 Kym 使用 Xamarin Effects 捕获键盘 Showing & Hiding 事件并将效果注册到滚动视图元素。

在我的 PCL 中,我创建了一个类并放置了来自 Kym 的以下代码:

using Xamarin.Forms;

namespace App2
{
    public class KeyboardSpacingEffect : RoutingEffect
    {
        public KeyboardSpacingEffect() : base("Xamarin.KeyboardSpacingEffect")
        {
        }
    }
}

然后在 UWP 和 WinPhone 平台特定的项目中,我创建了一个类并放置了来自 Kym 的代码:

using App2.WinPhone; //Make sure this using statement correctly points to the platform specific project and not the PCL project or you will get an error.
using System.Diagnostics;
using Windows.UI.ViewManagement;
using Xamarin.Forms;
using Xamarin.Forms.Platform.WinRT;

[assembly: ResolutionGroupName("Xamarin")]
[assembly: ExportEffect(typeof(KeyboardSpacingEffect), "KeyboardSpacingEffect")]
namespace App2.WinPhone
{
    public class KeyboardSpacingEffect : PlatformEffect
    {
        protected override void OnAttached()
        {
            InputPane.GetForCurrentView().Showing += Keyboard_OnShow;
            InputPane.GetForCurrentView().Hiding += Keyboard_OnHide;

        }

        private void Keyboard_OnHide(InputPane sender, InputPaneVisibilityEventArgs args)
        {
            // debug stuff
            Debug.WriteLine("Keyboard hide");
            var x = Element;
            var y = Control;
            var z = Container;
            Debug.WriteLine($"{x} - {y} - {z}");

            // get the scrollview element and remove the margin
            ScrollView scrollView = Element as ScrollView;
            scrollView.Margin = new Thickness(0, 0, 0, 0);
        }

        private void Keyboard_OnShow(InputPane sender, InputPaneVisibilityEventArgs args)
        {
            // debug stuff
            var x = Element;
            var y = Control;
            var z = Container;
            Debug.WriteLine($"{x} - {y} - {z}");

            // get the scrollview element and add some margin to the bottom = size of keyboard
            ScrollView scrollView = Element as ScrollView;
            scrollView.Margin = new Thickness(0, 0, 0, args.OccludedRect.Height + 20);
        }

        protected override void OnDetached()
        {
            InputPane.GetForCurrentView().Showing += Keyboard_OnShow;
            InputPane.GetForCurrentView().Hiding += Keyboard_OnHide;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2018-12-22
    • 2021-04-02
    • 2018-03-12
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多