如何解决打开软键盘时如何防止特定的 Xamarin View 向上滚动?
我有以下 xamarin 布局模式:
<StackLayout>
<Grid>...</Grid> <!-- TOP GRID - This must be fixed -->
<ScrollView>...</ScrollView> <!-- This must scroll -->
<Grid><Entry></Entry>/Grid> <!-- BottOM GRID - This must scroll -->
</StackLayout>
iOS 的行为出人意料地如我所愿(这是一个聊天布局,所以顶部栏有图片和用户名,我希望一直可见),但 android 行为是向上滚动整个页面并只保留 ScrollView 的条目和底部可见,这几乎是我所需要的,但顶部网格正在消失。只有 Srollview 和底部网格必须滚动。
我怎样才能做到这一点?
编辑 1
示例项目:
https://wetransfer.com/downloads/46b455cb7148189a0d1f84affa77b7e120210428144025/02b001
解决方法
你能不能试试这个。
基本的布局结构将是这样的。
<Grid RowDefinitions="50,*,Auto">
<StackLayout Grid.Row="0" >
<!-- Username and Profile image -->
</StackLayout>
<CollectionView Grid.Row="1">
<!-- Your COllectionView -->
</CollectionView>
<controls:KeyboardView Grid.Row="2">
<controls:KeyboardView.Margin>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0,10" />
<On Platform="Android" Value="0,5" />
</OnPlatform>
</controls:KeyboardView.Margin>
<!-- Your entry and Send Button -->
</controls:KeyboardView>
</Grid>
在您的 PCL 上,创建 KeyboardView
public class KeyboardView : Grid { }
在 ios 创建 KeyboardViewRenderer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CoreGraphics;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(KeyboardView),typeof(KeyboardViewRenderer))]
namespace YourAppName.iOS.CustomRender
{
public class KeyboardViewRenderer : ViewRenderer
{
NSObject _keyboardShowObserver;
NSObject _keyboardHideObserver;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
RegisterForKeyboardNotifications();
}
if (e.OldElement != null)
{
UnregisterForKeyboardNotifications();
}
}
void RegisterForKeyboardNotifications()
{
if (_keyboardShowObserver == null)
_keyboardShowObserver = UIKeyboard.Notifications.ObserveWillShow(OnKeyboardShow);
if (_keyboardHideObserver == null)
_keyboardHideObserver = UIKeyboard.Notifications.ObserveWillHide(OnKeyboardHide);
}
void OnKeyboardShow(object sender,UIKeyboardEventArgs args)
{
NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey));
CGSize keyboardSize = result.RectangleFValue.Size;
if (Element != null)
{
Element.Margin = new Thickness(0,keyboardSize.Height); //push the entry up to keyboard height when keyboard is activated
}
}
void OnKeyboardHide(object sender,UIKeyboardEventArgs args)
{
if (Element != null)
{
Element.Margin = new Thickness(0); //set the margins to zero when keyboard is dismissed
}
}
void UnregisterForKeyboardNotifications()
{
if (_keyboardShowObserver != null)
{
_keyboardShowObserver.Dispose();
_keyboardShowObserver = null;
}
if (_keyboardHideObserver != null)
{
_keyboardHideObserver.Dispose();
_keyboardHideObserver = null;
}
}
}
}
对于 Android,在 App.Xaml 中添加这个
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="KeyboardSample.App"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:Application.WindowSoftInputModeAdjust="Resize">
<Application.Resources>
</Application.Resources>
</Application>
更新 1
根据您的解决方案,您需要进行 3 次更改。
-
以您的风格从 MainTheme.Base 中删除此行。
<item name="android:windowFullscreen">true</item>
-
从 MainActivity
中删除这一行Window.SetSoftInputMode(Android.Views.SoftInput.AdjustResize);
-
添加
Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);
在主要活动中的 LoadApplication 之后。
更新 2
如果去除 android:windowFullscreen
混乱的状态栏颜色以及底部栏颜色,我们可以使用自定义渲染。
创建接口 IStatusBarPlatformSpecific
public interface IStatusBarPlatformSpecific
{
void SetStatusBarColor(Color color);
void SetBottomBarColor(Color color);
}
在 android 项目中创建名为 Statusbar
的渲染
[assembly: Dependency(typeof(Statusbar))]
namespace YourAppName.Droid.CustomRender.StatusBar_Color
{
public class Statusbar : IStatusBarPlatformSpecific
{
public Statusbar()
{
}
public void SetStatusBarColor(System.Drawing.Color color)
{
CrossCurrentActivity.Current.Activity.Window.SetStatusBarColor(ToAndroidColor(color));
}
public void SetBottomBarColor(System.Drawing.Color color)
{
CrossCurrentActivity.Current.Activity.Window.SetNavigationBarColor(ToAndroidColor(color));
}
public static Android.Graphics.Color ToAndroidColor(System.Drawing.Color color)
{
return new Android.Graphics.Color(color.ToArgb());
}
}
}
现在你可以从你想要的页面调用它OnAppearing
像这样。
protected override async void OnAppearing()
{
base.OnAppearing();
if (Device.RuntimePlatform == Device.Android)
{
var statusbar =
DependencyService.Get<IStatusBarPlatformSpecific>();
statusbar.SetStatusBarColor(Color.FromHex("#112330"));
statusbar.SetBottomBarColor(Color.FromHex("#304E62"));
}
}
您现在可以将状态栏颜色和底部颜色设置为与您的页面匹配。如果这对您有用,请告诉我。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。