我正在开发版本为2.9.0的phonegap应用程序;
使用RWD Bookmarklet(http://responsive.victorcoulon.fr/)在桌面浏览器中对布局进行了全面测试,并且工作正常.但是,在移动设备或仿真器中进行测试时,布局中断了.经过一点点测试,我发现问题是状态栏的高度.将应用程序更改为全屏,问题解决了.
但是现在,当我专注于输入字段时,屏幕没有被调整,因此,键盘覆盖输入字段!
在查看了所有问题和相关问题之后,我找到了这个,这对我来说很有意义,但我想知道是否有办法让调整盘全屏工作,所以我不需要调整我的所有组件高度,根据设备等计算不同的状态栏高度
代码
form.html
<form id="login-form">
<div class="form-group">
<input type="text" name="login" class="form-control" id="login"
placeholder="xxxxxxx@example.com">
</div>
<div class="form-group">
<input type="password" name="pass" class="form-control"
id="password" placeholder="*******">
</div>
<a class="pull-right login-btn" id="btn-login" href="#"><span
class="image-replacement"></span></a>
<a class="pull-right login-btn" id="btn-cadastro" href="#"><span class="image-replacement"></span></a>
</form>
Run Code Online (Sandbox Code Playgroud)
Android Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
package="com.com.app" android:versionName="1.0" android:versionCode="1" android:hardwareAccelerated="true">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true"
android:resizeable="true"
android:anyDensity="true"
/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:hardwareAccelerated="true"
android:debuggable="true">
<activity android:name="App" android:label="@string/app_name"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
android:windowSoftInputMode="stateVisible|adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17"/>
</manifest>
Run Code Online (Sandbox Code Playgroud)
App.java
package com.com.app;
import org.apache.cordova.Config;
import org.apache.cordova.DroidGap;
import android.os.Bundle;
import android.view.WindowManager;
public class BDH extends DroidGap
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Set by <content src="index.html" /> in config.xml
getWindow().setFlags(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN, WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.loadUrl(Config.getStartUrl());
//super.loadUrl("file:///android_asset/www/index.html")
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这可能不是更好的解决方法,但我已经找到了解决方案。检测事件并与 JS 通信对我来说不起作用,无论是使用 window.scrollTo 还是使用 jQuery 插件。不幸的是,我的时间很短,我更喜欢直接用 Java 来做。只要我有时间,我将重构它并基于此解决方案开发一个插件。随着代码更新,我也会在这里更新。事情是这样的:
\n\n /**\n * \n * Due to a well known bug on Phonegap\xc2\xb9, android softKeyboard adjustPan functionality wasn\'t working\n * as expected when an input field recieved focus. The common workaround(Change to adjustResize and),\n * however, was not applicable, due to an Android bug\xc2\xb2 that crashes fullscreen apps when in adjustResize mode.\n * This is an workaround, to detect when the softKeyboard is activated and then programatically scroll \n * whenever it needs;\n *\n * During the development proccess i came across an annoying behavior on android, that were making the\n * input field dispatch onFocusChange twice when focus was cleared, when it should dispatch only once.\n * The first one, without focus(Expected behavior), the second one WITH focus(Dafuq?), causing it to\n * not scroll back on blur. My workaround was to only enable it to set a flag(lostFocus parameter), and\n * only allow the method to calculate the scroll size IF the element had not lost it\'s focus;\n * \n * \xc2\xb9 - http://stackoverflow.com/questions/11968420/softkeyboard-in-phonegap-covers-input-elements\n * \xc2\xb2 - http://stackoverflow.com/questions/7417123/android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible\n **/\n\n final View activityRootView = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);\n\n activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {\n @Override\n public void onGlobalLayout(){\n\n View focused = appView.findFocus();\n activityRootView.getWindowVisibleDisplayFrame(r);\n\n if(focused instanceof TextView){\n\n if(focused.getOnFocusChangeListener() == null){\n focused.setOnFocusChangeListener(new OnFocusChangeListener() {\n\n @Override\n public void onFocusChange(View v, boolean hasFocus) {\n if(!hasFocus){\n activityRootView.scrollTo(0,0);\n lostFocus = true;\n showKeyBoard = false;\n }else{\n showKeyBoard = true;\n }\n }\n\n });\n }\n\n /**\n * \n * Really tricky one to find, that was the only way i found to detect when this listener call came from\n * the buggy input focus gain. If the element had lost its focus, r(A Rect representing the screen visible area)\n * would be the total height, what means that there would be no keyboard to be shown, as far as the screen\n * was completely visible.\n * \n **/\n if(showKeyBoard || r.top != activityRootView.getHeight()){\n\n int heightDiff = 0;\n int keyBoardSize = 0;\n int scrollTo = 0;\n\n\n heightDiff = activityRootView.getRootView().getHeight() - focused.getTop();\n keyBoardSize = activityRootView.getRootView().getHeight() - r.bottom;\n\n if((keyBoardSize < focused.getBottom() && keyBoardSize > 0) && !lostFocus){\n scrollTo = focused.getBottom() - keyBoardSize;\n }\n\n\n if(scrollTo == 0){\n activityRootView.scrollTo(0,scrollTo);\n lostFocus = false;\n showKeyBoard = true;\n }else if(heightDiff < r.bottom){\n activityRootView.scrollTo(0, scrollTo);\n lostFocus = false;\n showKeyBoard = false;\n }\n }\n }\n }\n });\n
Run Code Online (Sandbox Code Playgroud)\n\nr、lostFocus 和 showKeyboard 的阐述
\n\nr是一个 Rect 对象,通过getWindowVisibleDisplayFrame(Rect r)方法填充
\n\n来自文档:
\n\n\n\n\n检索该视图附加到的窗口所在的整体可见显示大小。这考虑了窗口上方的屏幕装饰,对于窗口本身位于其中的两种情况或窗口被放置在\n 下面,并且覆盖的插图用于窗口将其内容\n 放置在其中。实际上,这告诉您可以放置内容并对用户保持可见的可用区域。
\n
因此,如果显示键盘,r.bottom将与 rootView 高度不同。
\n\nshowKeyboard和lostFocus是两种解决方法,可以可靠地获得正确的焦点/模糊行为。showKeyboard很简单,只有一个标志来告诉应用程序是否应该滚动。从理论上讲,它可以工作,但是,我遇到了一个恼人的错误,该错误导致输入字段在失去焦点后、在软键盘隐藏之前立即聚焦(仅在应用程序内部、在设备上,该元素没有\ 无法获得焦点并且键盘已经隐藏)。为了解决这个问题,我使用lostFocus来告诉应用程序它何时真正失去了焦点,并且仅允许它计算在元素没有失去焦点的情况下滚动的位置。
\n 归档时间: |
|
查看次数: |
8794 次 |
最近记录: |