键盘隐藏 Android WebView 上的输入字段

Keyboard hides input fields on Android WebView

在我的 Android 应用程序中,我有一个 Activity 的布局几乎是 WebView 元素。在此 WebView 中,我正在加载在线表单供用户填写。但是,底部输入字段(文本框)位于软键盘后面,用户无法填写。

这种情况有哪些可能的解决方案?

这是我的代码:

AndroidManifest.xml(仅此布局部分)

<activity
        android:name=".home.SurveyActivity"
        android:configChanges="orientation"
        android:icon="@drawable/logo_white"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustResize">

    </activity>

布局文件:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/custom_header"
        style="@style/CustomHeader.Height"
        android:layout_alignParentTop="true"/>

    <WebView
        android:id="@+id/activity_portal_webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/activity_portal_bottom_layout"
        android:layout_below="@id/custom_header"
        android:scrollbars="none"/>

    <LinearLayout
        android:id="@id/activity_portal_bottom_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical">

    </LinearLayout>

</RelativeLayout>

Activity class:

public class SurveyActivity extends Activity {

    public static Intent makeIntent(Context context) {
        return new Intent(context, SurveyActivity.class);
    }

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Utils.updateLang();

        setContentView(R.layout.survey_activity_main);

        Utils.inflateCustomHeader(this);

        WebView webView = (WebView) findViewById(R.id.activity_portal_webview);

        webView.setWebChromeClient(new WebChromeClient());

        WebSettings webSettings = webView.getSettings();
        webSettings.setLoadsImagesAutomatically(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDefaultTextEncodingName("UTF-8");

        webView.loadUrl("WWW.EXAMPLE.COM");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Utils.updateLang();

        LinearLayout navigationBar = (LinearLayout) findViewById(R.id.activity_portal_bottom_layout);
        navigationBar.removeAllViews();
        navigationBar.addView(NavigationBarContract.makeNavigationBar(this, R.id.navigation_bar_home_button));
    }
}

Google Chrome on Android 中存在类似的问题(参见 http://crbug.com/398112),它也可能影响 Android 从 KitKat 开始的 WebView。由于您无法控制用户将在其设备上使用哪个版本的 WebView,因此最好提供一个通用的解决方法。

例如,您可以在页面底部的某处添加一个间隔符 div 以确保页面比屏幕高,这样它就可以滚动以显示输入字段。

我不确定这是否有帮助,但我的解决方案是向 webview 添加一些 javascript 来处理调整大小。

首先你需要两个 javascript 函数,我调用了我的 noFocus 它将 body 移回 0 位置。

function noFocus() {
    console.log('unfocus');
    Android.resetWindow(); // this removes the naigation and status bar via an interface
    $('body').css("margin-top", "0px");
 }

另一个叫 hasFocus 的决定天气 body 是否向上移动

function hasFocus(){
  var boxHeight = $(this).offset().top +60;
  var windowHei = $(window).height();
  var dTop      = boxHeight - (windowHei/2);
  // this logic may need to change depending on your implementation
  console.log('dtop' + dTop + ' as boxheight is ->' + boxHeight + 'windowHei ->' + windowHei )
if(boxHeight > (windowHei/2)) {
    $('body').css("margin-top", -dTop + "px");
}
this.addEventListener('blur', noFocus, false);
}

然后您需要遍历 DOM 添加以下输入侦听器

var input = document.querySelectorAll('input');       
for (var i = 0; i < input.length; i++) {
    input[i].removeEventListener('focus', hasFocus, false)
    input[i].addEventListener('focus', hasFocus, false)
};

我的方法的唯一限制是,如果键盘被关闭,则 noFocus 不会被调用,直到用户触摸输入字段之外。