Прокрутка экрана вверх, когда клавиатура открыта на странице входа. Xamarin
Я работаю над 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>
Но код выше не прокручивает раскладку вверх, когда клавиатура открыта и скрывает почти половину кнопки входа. Как реализовать прокрутку при открытой клавиатуре? Я не очень заинтересован в использовании пользовательских средств визуализации.
Смотрите страницу входа
1 ответ
Поскольку, насколько мне известно, нет хорошего способа получить фактическую высоту клавиатуры для Android с помощью DependencyService, использование этого scrollview является правильным подходом для начала, однако вам нужно настроить пользовательский интерфейс, который приведет к рендеры. "Я хочу классный пользовательский интерфейс, но я не заинтересован в пользовательских средствах визуализации" - это как "Я хочу водить, но я не интересуюсь колесами".
Однако, чтобы вам было легче, у меня есть код для пользовательского рендера, который дает желаемый результат:
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.