xamarin表单:根据键盘高度向上移动视图

时间:2016-09-22 14:10:49

标签: xaml xamarin.forms

我正在使用xamarin表格。我在xaml中设计了一个登录表单页面。我想在键盘出现时向上移动登录表单视图,以便在平台AndroidIOS的情况下,文本字段和登录按钮都可见。如何计算键盘高度并通过动态计算键盘高度来向上移动登录表单视图。

enter image description here

以下是我的xaml代码:

<ContentPage>
    <ScrollView>
        <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <Grid Padding="20, 30, 20, 20" RowSpacing="20" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <Image Grid.Row="0" Source="login.png" HorizontalOptions="Center" VerticalOptions="Center"/>

                <Entry Grid.Row="2" x:Name="entryUserName" HorizontalOptions="Fill"  Placeholder="Username" PlaceholderColor="#707070" Text="{Binding UserName,Mode=TwoWay}" Margin="5"/>

                <BoxView Grid.Row="2" HeightRequest="1" HorizontalOptions="Fill" BackgroundColor="#707070" VerticalOptions="End"/>

                <Entry Grid.Row="3" x:Name="entryPassword" Text="{Binding Password,Mode=TwoWay}" Placeholder="Password" PlaceholderColor="#707070" Margin="5" HorizontalOptions="Fill" IsPassword="True"/>

                <BoxView Grid.Row="3" HeightRequest="1" HorizontalOptions="Fill" BackgroundColor="#707070" VerticalOptions="End"/>

                <Button Grid.Row="5" HorizontalOptions="Center" VerticalOptions="Center" Text="Login" Command="{Binding doLoginCommand}" CommandParameter="entryUserName,entryPassword" />

            </Grid>         
        </AbsoluteLayout>
    </ScrollView>
</ContentPage>

我不想对页面执行任何类型的自定义呈现。是否有任何资源可以通过它编写依赖服务来计算不同移动视图跨平台的键盘高度。 我经历了this,但它有一些我不想要的自定义渲染。

2 个答案:

答案 0 :(得分:6)

选项1:

机器人: 将此添加到您的清单:

<activity //Your MainActivity
        android:windowSoftInputMode="stateVisible|adjustResize" ... >
        ...
</activity>

奥斯: 添加此nuget包: https://www.nuget.org/packages/Xam.Plugins.Forms.KeyboardOverlap/

并初始化:

Xamarin.Forms.Init();//platform specific init
KeyboardOverlapRenderer.Init ();

选项2:

将此代码添加到您的Page类:

        protected override void OnAppearing()
        {
            base.OnAppearing();
            entryUserName.Focused += InputFocused;
            entryPassword.Focused += InputFocused;
            entryUserName.Unfocused += InputUnfocused;
            entryPassword.Unfocused += InputUnfocused;
        }

        protected override void OnDisappearing()
        {
            base.OnDisappearing();
            entryUserName.Focused -= InputFocused;
            entryPassword.Focused -= InputFocused;
            entryUserName.Unfocused -= InputUnfocused;
            entryPassword.Unfocused -= InputUnfocused;
        }
        void InputFocused(object sender, EventArgs args){
            Content.LayoutTo(new Rectangle(0,-360, Content.Bounds.Width, Content.Bounds.Height));
        }

        void InputUnfocused(object sender, EventArgs args){
            Content.LayoutTo(new Rectangle(0,0, Content.Bounds.Width, Content.Bounds.Height));
        }

答案 1 :(得分:2)

这是一个强制在Android上使用SoftInputMode的Entry渲染器,希望这会有所帮助:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Widget;
using Android.Util;
using Android.OS;
using Android.Views.InputMethods;
using System.Threading;
using Android.Views;
using Android.App;

[assembly: ExportRenderer(typeof(FormsEntry), typeof(DroidEntryRenderer))]
namespace XXX
{
    public class DroidEntryRenderer : EntryRenderer, IEntryMessages
    {
        private bool _inititialized = false;
        EditText editText;

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (e.OldElement != null) 
            {
                // unhook old events
            }
            if (e.NewElement != null)
            {
                // hook new events
                editText = (EditText)Control;
                var entry = e.NewElement as FormsEntry;

                (this.Element as FormsEntry).OnShowKeyboard += DroidEntryRenderer_showKeyboard;
                (this.Element as FormsEntry).OnChangeIme += DroidEntryRenderer_changeIme;

                if(entry.KeyboardInputMode == SoftInputMode.AdjustNothing)
                    (Forms.Context as Activity).Window.SetSoftInputMode(SoftInput.AdjustNothing );
                else if(entry.KeyboardInputMode == SoftInputMode.AdjustResize)
                    (Forms.Context as Activity).Window.SetSoftInputMode(SoftInput.AdjustResize );
                else
                    (Forms.Context as Activity).Window.SetSoftInputMode(SoftInput.AdjustPan );

                if(entry.SetImeToNext){
                    Control.ImeOptions = Android.Views.InputMethods.ImeAction.Next;
                    Control.SetImeActionLabel("Next", Android.Views.InputMethods.ImeAction.Next);

                    switch(entry.CustomImeAction){
                        case ImeAction.Email:
                            editText.EditorAction += (object sender, TextView.EditorActionEventArgs args) =>
                            {
                                MessagingCenter.Send<IEntryMessages>(this, "Email");
                            };
                            break;
                        case ImeAction.Password:
                            editText.EditorAction += (object sender, TextView.EditorActionEventArgs args) =>
                            {
                                MessagingCenter.Send<IEntryMessages>(this, "Password");
                            };
                            break;
                    }
                }

                if (entry.HasBorder)
                {
                    editText.SetBackgroundResource(Resource.Drawable.BorderEntry);
                }

                // edit properties
                if (entry.Font != Font.Default)
                {
                    RendererHelper.SetTextViewFont(editText, entry.Font);
                }
                if (entry.PlaceholderColor != Color.Default)
                    editText.SetHintTextColor(entry.PlaceholderColor.ToAndroid());

                switch (entry.XAlign)
                {
                case Xamarin.Forms.TextAlignment.Start:
                    editText.Gravity = Android.Views.GravityFlags.CenterVertical | Android.Views.GravityFlags.Left;
                    break;

                case Xamarin.Forms.TextAlignment.Center:
                    editText.Gravity = Android.Views.GravityFlags.Center;
                    break;

                case Xamarin.Forms.TextAlignment.End:
                    editText.Gravity = Android.Views.GravityFlags.CenterVertical | Android.Views.GravityFlags.Right;
                    editText.SetPadding(0, editText.PaddingTop, 0, editText.PaddingBottom);
                    break;
                }

                if (entry.ReturnKeyType == KeyboardType.Done)
                    editText.ImeOptions = global::Android.Views.InputMethods.ImeAction.Done;
                else if (entry.ReturnKeyType == KeyboardType.Next)
                    editText.ImeOptions = global::Android.Views.InputMethods.ImeAction.Next;

            }
        }

        void DroidEntryRenderer_showKeyboard()
        {
            ShowKeyboard();
        }

        void DroidEntryRenderer_changeIme()
        {
            ChangeIme();
        }

        public void ChangeIme(){
            Control.ImeOptions = Android.Views.InputMethods.ImeAction.Next;
            Control.SetImeActionLabel("Next", Android.Views.InputMethods.ImeAction.Next);
        }

        public void ShowKeyboard()
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                this.Control.RequestFocus();
                InputMethodManager inputMethodManager = this.Control.Context.
                GetSystemService(Android.Content.Context.InputMethodService) as InputMethodManager;
                inputMethodManager.ShowSoftInput(this.Control, ShowFlags.Forced);
                inputMethodManager.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
            });
        }

    }
}