【问题标题】:Can webpage be aware of android virtual keyboard网页可以知道android虚拟键盘吗
【发布时间】:2012-07-01 03:26:19
【问题描述】:

我有web page with jquery terminal 和隐藏的文本区域(触发 Android 虚拟键盘),我可以输入字符,但是当我输入几个命令时,内容隐藏在虚拟键盘后面。终端内容正在滚动到底部,因为当我键入更多命令时它正在滚动。当我在手机中使用硬件键盘时,滚动是正确的(触摸滚动还不起作用)。

我添加了这个 CSS

.terminal textarea { top: 0; width:0; margin-left: -8px; pointer-events: none; }

上一个

.terminal .clipboard {
    position: absolute;
    bottom: 0;
    left: 0;
    opacity: 0.01;
    filter: alpha(opacity = 0.01);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01);
    width: 2px;
}
.cmd > .clipboard {
    position: fixed;
}

并将此代码放入插件中(textarea 用于剪贴板)。

 self.click(function() {
     self.find('textarea').focus();
 });

我的问题是:javascript 可以检测虚拟键盘的大小吗?或者也许有其他方法可以改变网页的大小,所以它只是在视觉部分(不是键盘所在的位置)?或者我的代码可能有问题,它不是为在移动设备上工作而设计的。 键盘的大小是否始终相同,即使用户安装了不同的键盘?

【问题讨论】:

    标签: android jquery browser virtual-keyboard


    【解决方案1】:

    1 您可以使用Manifest.xml<activity> 元素中的android:windowSoftInputMode 属性在IME 弹出时选择各种调整大小的策略。其中包括(不限于):

    adjustResize,它将调整 Activity 的内容视图(以及其中的 WebView)的大小以适应剩余空间。

    adjustPan,这将使内容视图充满整个屏幕,部分被 IME 的窗口遮挡。

    玩这些可能已经给你你正在寻找的行为。

    2 Android 在 IME 弹出时滚动 (Web)View 的默认行为是尝试保持光标可见。在您的情况下,您将光标(或:焦点)放在隐藏视图上。这解释了您所看到的奇怪行为,我认为您最好更改您的实现。你为什么不首先使用可见的文本区域?您的文本必须在某个地方结束,对吗?然后Android会自动处理焦点/滚动。

    作为一种解决方法:您可以尝试更智能地定位隐藏视图并不时清除其内容,从而避免滚动问题。当然,此选项的可行性取决于您的具体用例。

    3 这将是您所问问题的答案,但我不确定这将如何帮助您(可能是因为我对 html 缺乏经验):

    要在您的 javascript 中获取 WebView 的高度(即屏幕大小 - IME 高度),请执行以下操作:

    • 在您的清单中,将android:windowSoftInputMode="adjustResize" 属性添加到您的元素。
    • 像这样扩展你的外部布局:

      public class RelativeLayoutWithLayoutListener extends RelativeLayout {
      
      public interface LayoutListener {
          public void onLayout();
      }
      
      private LayoutListener mListener;
      
      public RelativeLayoutWithLayoutListener(Context context) {
          super(context);
      }
      
      public RelativeLayoutWithLayoutListener(Context context, AttributeSet attrs, int defStyle) {
          super(context, attrs, defStyle);
      }
      
      public RelativeLayoutWithLayoutListener(Context context, AttributeSet attrs) {
          super(context, attrs);
      }
      
      public void setLayoutListener(LayoutListener aListener) {
          mListener = aListener;
      }
      
      @Override
      protected void onLayout(boolean changed, int l, int t, int r, int b) {
          super.onLayout(changed, l, t, r, b);
          if (mListener != null) {
              mListener.onLayout();
          }
      }
      }
      
    • 用您的 layout.xml 文件中新创建的布局替换旧布局。

    • 在您的活动代码中,执行以下操作:

      public class MainActivity extends Activity {
      
      private RelativeLayoutWithLayoutListener mMainLayout;
      
      private WebView mWebView;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          mMainLayout = (RelativeLayoutWithLayoutListener)findViewById(R.id.main_layout);
      
          mMainLayout.setLayoutListener(new LayoutListener() {
      
              @Override
              public void onLayout() {
                  mWebView.loadUrl("javascript:setSize(" + mMainLayout.getWidth() + "," + mMainLayout.getHeight() + ")");             
              }
          });
      
          mWebView = (WebView)findViewById(R.id.webview);
      }
      }
      

    当然,在 loadUrl() 调用中,您必须调用您定义的 javascript 方法。如果您先进行一些计算,当然也可以传入 IME 的高度。

    【讨论】:

      【解决方案2】:

      据我所知,当虚拟键盘弹出时,页面没有调整大小(以适应较小的视图区域,在虚拟键盘打开时可见)。所以这不会给你的页面提示键盘是否启动。而且我真的不认为还有其他方法可以获取这些信息。

      您可以在查看用户代理的位置进行设置,如果是针对 Android 手机,当用户单击各种文本输入元素时,您会在屏幕底部为虚拟键盘腾出一些空间。

      对于键盘的尺寸,现有的 Android 可能有一个标准的尺寸或比例或百分比,但结合有很多 Android 模块的事实以及有多种屏幕分辨率和屏幕比例的事实那里意味着无法为此设置固定数字(例如键盘高 x 像素或屏幕空间的 y%)。但是,您可以做出一个常识性的假设,即底部大约占屏幕的一半。

      所以基本上,使用用户代理、屏幕分辨率和用户“点击”文本输入字段这一事实,您可以大致了解是否显示虚拟键盘,以及有多少空间可以显示留着吧。

      【讨论】:

      • 我不明白为什么这是公认的答案。我知道 SO 是精英管理,我很高兴它是,但我实际上描述了一种您可以找到我的回答中虚拟键盘的大小(或者更好的是:Activity 的可用屏幕空间的大小)。此外,我还提出了一些关于实现的替代想法,因为至少可以说使用“不可见视图”之类的东西来启动键盘听起来有点生硬。我一点也不在乎我的答案不是公认的答案,但现在每个阅读该问题的人都会,IMO,阅读一个不正确的答案。
      • @baske 也许是因为这将它作为一个网页来处理,而不是使用原生应用程序的 java 代码?阅读标题。
      • 如果你再次阅读我的回答,你会发现虽然它包含“native”(java)代码,但这段代码的最终目的是将可见窗口的大小传递给 javascript 代码您的网络视图(使用 loadUrl() 方法)。问题是“javascript 可以检测到虚拟键盘有多大吗?”,简短的回答是“否”。但事实证明,您可以使用 java (native) 代码获取请求的大小并将其传递给 javascript,我的回答解释了如何..
      • 旁白:我认为在 javascript 中获得这个 IME/Window 大小所遇到的麻烦已经表明应该完全采用不同的方法,仅出于这个原因,我很高兴承认我的答案不应该被实施 :-) 如果你真的想这样做的话,这更像是一个下午的练习,看看是否可以完成......
      【解决方案3】:

      如果您想在键盘弹出时也能保持终端内容可见,则无需知道键盘大小。问题在于您的"#shell" 高度。尝试在 Chrome(桌面)上打开开发者工具并调整窗口大小。您会看到"#shell" div 的高度始终适合设备高度,而不是内容区域高度。因此,当键盘弹出时,内容将在键盘的背面。要使其正常工作,您应该强制您的 "#shell" 高度适合内容区域。我尝试修改 css,它在我的 android 模拟器中正常工作。还要从您的页面中删除touch-scroll js,这是不必要的。您可以将此 css 代码附加到您的 css 文件中。

      #shell {
          position: fixed !important;
          top: 0; left: 0;
          width: 100% !important; height: 100% !important;
          margin: 0 !important; padding: 0 !important;
          -webkit-transition: none !important;
          -webkit-transform: none !important;
          overflow-y: visible !important;
      }
      
      #shell .terminal-output, #shell .cmd {
          margin: 10px;
      }
      

      希望对您有所帮助。 :)

      【讨论】:

      • 它在实际手机上不起作用,当我不使用虚拟键盘滚动到底部时,当我按下回车键但使用手指滚动不起作用时。当我删除position: fixed !important; top: 0; left: 0; 使用figer 滚动但不滚动到底部时。终端仍在虚拟键盘下方。
      • 很抱歉,我还没有真正的安卓手机。但它在android模拟器和ios模拟器中都能正常工作。我认为您要做的是删除所有元素位置(固定或相对)并将元素显示设置为块。然后将float: left; 设置为.terminal, .cmd。最后,添加单击和键事件以聚焦到输入。也不要隐藏任何溢出。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2011-09-09
      • 1970-01-01
      • 2011-12-29
      • 2011-01-04
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多