Nativescript Vue Android 键盘覆盖 TextView 或键盘覆盖操作栏

Posted

技术标签:

【中文标题】Nativescript Vue Android 键盘覆盖 TextView 或键盘覆盖操作栏【英文标题】:Nativescript Vue Android Keyboard overlays TextView or Keyboard overlays actionbar 【发布时间】:2020-09-10 15:34:15 【问题描述】:

在用户可以发送文本的 NativeScript Vue 类聊天应用程序中打开键盘时,页面内容会覆盖 ActionBar。如果用户关闭应用程序并再次打开它,键盘输入会覆盖 TextView 组件。

我期待有类似“Fb Messenger 聊天”行为的结果:打开键盘时聊天向上滚动,但 ActionBar 和 TextField 组件中的“标题”保持固定在那里。 The actual result can be also seen from the attached image.

为了解决这个问题,我已经尝试过: "Stop keyboard overlay when interacting with TextField in a NativeScript application"

Template Flow:

ScrollView
  > StackLayout
    > GridLayout
      > SomeElement
    > GridLayout
      > TextField

我也尝试过(来自同一指南)

android Soft Input Mode:

    android:windowSoftInputMode="stateHidden | adjustPan">

这是我的代码:

<template>
<Page class="page">
    <ActionBar title="HHHH" class="action-bar header">
        <StackLayout orientation="horizontal"  alignItems="left"
            class="actionBarContainer">
            <StackLayout class="HLeft" style="margin-top:10;" @tap="$navigateBack">
                <Label :text="back" style="font-size:27;color:#fff;"
                    class="font-awesome" />
            </StackLayout>
            <StackLayout class="HMidEdited" alignItems="left">
                <Label textWrap="true" class = "action-bar-title" :text="chatRoom.chatroomName" paddingTop = "7.5%" color="white" id="searchField"></Label>
            </StackLayout>
            <StackLayout class="HRight">

            </StackLayout>
        </StackLayout>
    </ActionBar>

        <StackLayout ~mainContent>

            <DockLayout>
                <StackLayout dock="top"   >
                    <ListView  ref="listView" for="item in conversations" 
                        separatorColor="transparent" id="listView">
                        <v-template>

                            <StackLayout orientation="horizontal" style="border-bottom-width:1;border-bottom-color:#E4E4E4;"
                                padding="10">
                                <StackLayout >
                                   <Image :src="item.profilePicture"
                                        stretch="aspectFill" class="conImg" />
                                </StackLayout>
                                <StackLayout marginLeft="10" paddingTop="3"
                                    >
                                        <Label :text="item.username" />
                                    <Label :text="item.message" textWrap="true" />
                                </StackLayout>
                                <StackLayout marginLeft="10" paddingTop="3"
                                    >
                                    <Label :text="item.dataFormat"  class="convDateOut" />
                                </StackLayout>
                            </StackLayout>

                        </v-template>
                    </ListView>

                </StackLayout>
                <StackLayout dock="bottom"  style="border-color:#E4E4E4;border-width:1;background:#fff;">
                    <StackLayout orientation="horizontal">
                        <StackLayout class="textItem">
                        <TextView v-model="message" placeholderColor="black" 
                            :editable="isUserVerified" @tap="alertMessage" hint="Say Something" returnKeyType="send"
                            ios: ios:marginTop="3" 
                            android:paddingBottom="5" class="searchField font-awesome" textWrap="true"
                            color="#000000" :text="message" />
                        </StackLayout>
                        <StackLayout class="send" @tap="sendTap()">
                            <Label text="0" android:class="notificationAndroid"
                                ios:class="notification" opacity="0" />
                            <Label text="" android:style="font-size:23;margin-top:-15"
                                ios:style="font-size:29;margin-top:-15"
                                class="font-awesome" />
                        </StackLayout>
                    </StackLayout>
                </StackLayout>


            </DockLayout>

        </StackLayout>

</Page>

这是我尝试修复后的代码:

<template>
<Page class="page">
    <ActionBar title="HHHH" class="action-bar header">
        <StackLayout orientation="horizontal"  alignItems="left"
            class="actionBarContainer">
            <StackLayout class="HLeft" style="margin-top:10;" @tap="$navigateBack">
                <Label :text="back" style="font-size:27;color:#fff;"
                    class="font-awesome" />
            </StackLayout>
            <StackLayout class="HMidEdited" alignItems="left">
                <Label textWrap="true" class = "action-bar-title" :text="chatRoom.chatroomName" paddingTop = "7.5%" color="white" id="searchField"></Label>
            </StackLayout>
            <StackLayout class="HRight">

            </StackLayout>
        </StackLayout>
    </ActionBar>

<ScrollView orientation="vertical"  >
    <StackLayout ~mainContent>
            <GridLayout rows="*,60">
                    <ListView  ref="listView" for="item in conversations" 
                        separatorColor="transparent" id="listView" row="0" >
                        <v-template>

                            <StackLayout orientation="horizontal" style="border-bottom-width:1;border-bottom-color:#E4E4E4;"
                                padding="10">
                                <StackLayout >
                                   <Image :src="item.profilePicture"
                                        stretch="aspectFill" class="conImg" />
                                </StackLayout>
                                <StackLayout marginLeft="10" paddingTop="3"
                                    >
                                        <Label :text="item.username" />
                                    <Label :text="item.message" textWrap="true" />
                                </StackLayout>
                                <StackLayout marginLeft="10" paddingTop="3"
                                    >
                                    <Label :text="item.dataFormat"  class="convDateOut" />
                                </StackLayout>
                            </StackLayout>

                        </v-template>
                    </ListView>

                    <StackLayout orientation="horizontal" style="border-color:#E4E4E4;border-width:1;background:#fff;" row="1">
                        <StackLayout class="textItem">
                        <TextView v-model="message" placeholderColor="black" 
                            :editable="isUserVerified" @tap="alertMessage" hint="Say Something" returnKeyType="send"
                            ios: ios:marginTop="3" 
                            android:paddingBottom="5" class="searchField font-awesome" textWrap="true"
                            color="#000000" :text="message" />
                        </StackLayout>
                        <StackLayout class="send" @tap="sendTap()">
                            <Label text="0" android:class="notificationAndroid"
                                ios:class="notification" opacity="0" />
                            <Label text="" android:style="font-size:23;margin-top:-15"
                                ios:style="font-size:29;margin-top:-15"
                                class="font-awesome" />
                        </StackLayout>
                    </StackLayout>
            </GridLayout>
    </StackLayout>
</ScrollView>
</Page>

还补充道:

import * as app from "application"
export default 
    created() 
        var window = app.android.startActivity.getWindow();
            window.setSoftInputMode(android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

但它不起作用,因为使用 ScrollView 我将所有content of the page resized(附加屏幕截图)放在一行中,或者仍然与我使用 DockLayout 时的结果相同。

I'm also attaching the difference of code between the one I wrote and the changes I made.

Soft Input Mode additional changes here.

【问题讨论】:

你尝试调整调整大小了吗? 是的,我试过了,但没有成功。我尝试了“隐藏状态”、“调整平移”和“调整大小”,但一切都发生了变化。如果使用滚动视图或仅键盘覆盖文本视图和/或操作栏,则一切都很紧凑。 【参考方案1】:

我遇到过这种问题,这里有一些解决方法,你可以试试,希望对你有帮助

首先,您将所有列表包装在&lt;page&gt; 中,它支持在页面加载后发出的loaded 事件,此时您可以获得一个事件数据,即您的Page 对象,它是可观察的数据,所以它有点帮助您的页面在软键盘出现时收听视图变化。

获得Page 后,您可以检查它是否为android 并将setFitsSystemWindows 设置为true

我放了一些代码给你试试:

   <template>
      <Page @loaded="pageLoaded">
      <ActionBar title="HHHH" class="action-bar header">
        <StackLayout orientation="horizontal"  alignItems="left"
            class="actionBarContainer">
            <StackLayout class="HLeft" style="margin-top:10;" @tap="$navigateBack">
                <Label :text="back" style="font-size:27;color:#fff;"
                    class="font-awesome" />
            </StackLayout>
            <StackLayout class="HMidEdited" alignItems="left">
                <Label textWrap="true" class = "action-bar-title" :text="chatRoom.chatroomName" paddingTop = "7.5%" color="white" id="searchField"></Label>
            </StackLayout>
            <StackLayout class="HRight">

            </StackLayout>
        </StackLayout>
    </ActionBar>

<ScrollView orientation="vertical"  >
    <StackLayout ~mainContent>
            <GridLayout rows="*,60">
                    <ListView  ref="listView" for="item in conversations" 
                        separatorColor="transparent" id="listView" row="0" >
                        <v-template>

                            <StackLayout orientation="horizontal" style="border-bottom-width:1;border-bottom-color:#E4E4E4;"
                                padding="10">
                                <StackLayout >
                                   <Image :src="item.profilePicture"
                                        stretch="aspectFill" class="conImg" />
                                </StackLayout>
                                <StackLayout marginLeft="10" paddingTop="3"
                                    >
                                        <Label :text="item.username" />
                                    <Label :text="item.message" textWrap="true" />
                                </StackLayout>
                                <StackLayout marginLeft="10" paddingTop="3"
                                    >
                                    <Label :text="item.dataFormat"  class="convDateOut" />
                                </StackLayout>
                            </StackLayout>

                        </v-template>
                    </ListView>

                    <StackLayout orientation="horizontal" style="border-color:#E4E4E4;border-width:1;background:#fff;" row="1">
                        <StackLayout class="textItem">
                        <TextView v-model="message" placeholderColor="black" 
                            :editable="isUserVerified" @tap="alertMessage" hint="Say Something" returnKeyType="send"
                            ios: ios:marginTop="3" 
                            android:paddingBottom="5" class="searchField font-awesome" textWrap="true"
                            color="#000000" :text="message" />
                        </StackLayout>
                        <StackLayout class="send" @tap="sendTap()">
                            <Label text="0" android:class="notificationAndroid"
                                ios:class="notification" opacity="0" />
                            <Label text="" android:style="font-size:23;margin-top:-15"
                                ios:style="font-size:29;margin-top:-15"
                                class="font-awesome" />
                        </StackLayout>
                    </StackLayout>
            </GridLayout>
    </StackLayout>
</ScrollView>
      </Page>
    </template>

还有这个

import  EventData  from "tns-core-modules/data/observable";
import  Page  from "tns-core-modules/ui/page";

export default 
    methods: 
      pageLoaded(args: EventData) 
       let page = <Page>args.object;
       if (page.android) 
         page.android.setFitsSystemWindows(true);
       
     ,

【讨论】:

以上是关于Nativescript Vue Android 键盘覆盖 TextView 或键盘覆盖操作栏的主要内容,如果未能解决你的问题,请参考以下文章

tns 预览不适用于带有 nativescript-vue 的 android

NativeScript 使用 Vue 获取当前的 android 上下文?

尝试在 android (Nativescript-vue) 上使用 RadListView 时出现 Webpack 错误

如何在nativescript vue中处理webview上的android后退按钮

android中的后退按钮打破nativescript-vue访问控制登录注销

NativeScript Vue + Fastlane - 自定义 iOS/Android 项目路径?