Xamarin Forms: перемещение вида вверх в соответствии с высотой клавиатуры

Я использую формы xamarin. Я разработал страницу формы входа в xaml. Я хочу переместить вид формы входа вверх, когда появится клавиатура, чтобы как текстовое поле, так и кнопка входа были видны как для платформы Android, так и для IOS. Как рассчитать высоту клавиатуры и сдвинуть вид формы входа вверх, динамически вычисляя высоту клавиатуры.

введите описание изображения здесь

Ниже мой код 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>

Я не хочу выполнять какой-либо пользовательский рендеринг страницы. Есть ли какой-либо ресурс, через который я могу написать службу зависимостей, чтобы вычислить высоту клавиатуры для разных мобильных кросс-платформенных видов. Я прошел через это, но у него есть какой-то пользовательский рендеринг, который мне не нужен.

+5
источник поделиться
2 ответа

Вариант 1:

Android: Добавьте это в свой манифест:

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

Добавьте этот код в свой класс страницы:

        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));
        }
+3
источник

Вот рендеринг ввода, чтобы заставить SoftInputMode на Android, надеюсь, это поможет:

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

    }
}
+2
источник

Посмотрите другие вопросы по меткам или Задайте вопрос