微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

打开软键盘时如何防止特定的 Xamarin View 向上滚动?

如何解决打开软键盘时如何防止特定的 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 次更改。

  1. 以您的风格从 MainTheme.Base 中删除此行。

    <item name="android:windowFullscreen">true</item>
    
  2. 从 MainActivity Window.SetSoftInputMode(Android.Views.SoftInput.AdjustResize);

    中删除这一行
  3. 添加 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 举报,一经查实,本站将立刻删除。