Android - WebView在点击输入时显示键盘1秒钟

时间:2015-01-06 11:46:18

标签: android webview android-softkeyboard

我在WebView中遇到了一些非常奇怪的行为:

this.webView = new WebView(context);
addView(this.webView);

this.webView.setWebViewClient(new HtmlViewClient());
this.webView.setWebChromeClient(new HtmlViewChromeClient());
this.webView.getSettings().setJavaScriptEnabled(true);

如您所见,我动态创建它。

每当用户点击网页内的文本输入字段时,键盘就会出现并且输入会获得焦点,然后片刻之后,焦点会丢失并且键盘会消失。我似乎无法找到任何理由。

以下是WebViewClient和WebChromeClient(我不确定它是否相关 - 键盘出现时没有调用方法,但无论如何都是这样):

class HtmlViewClient extends WebViewClient
    {
        boolean loadingFinished = true;
        boolean redirect = false;

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) 
        {
            if (!webViewShouldStartLoadWithRequest(url, !redirect)) return true;

            if (!loadingFinished) redirect = true;
            loadingFinished = false;
            webView.loadUrl(url);
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) 
        {
            if (loadingFinished && !redirect) {

                webViewDidStartLoad();

            }
            loadingFinished = false;
        }

        @Override
        public void onPageFinished(WebView view, String url) 
        {
            if (!redirect) loadingFinished = true;
            if (loadingFinished && !redirect) webViewDidFinishLoad(); 
            else redirect = false; 
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) 
        {
            if (!redirect) loadingFinished = true;
            if (loadingFinished && !redirect) webViewDidFailLoadWithError(errorCode); 
            else redirect = false;
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) 
        {
            handler.proceed();
        }
    }

    class HtmlViewChromeClient extends WebChromeClient {

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {


            URI uri = null;

            try {
                uri = new URI(url);
            } catch (URISyntaxException ex) { }

            String hostString = (uri != null) ? uri.getHost() : "Dialog";

            final AlertDialog alertDialog = new AlertDialog.Builder(getContext())
            .setTitle(hostString)
            .setMessage(message)
            .setPositiveButton(android.R.string.ok,
                    new DialogInterface.OnClickListener()
            {
                public void onClick(DialogInterface dialog, int which)
                {
                    result.confirm();
                }
            })
            .setNegativeButton(android.R.string.cancel,
                    new DialogInterface.OnClickListener()
            {
                public void onClick(DialogInterface dialog, int which)
                {
                    result.cancel();
                }
            })
            .setCancelable(false)   
            .create();

            // add listener for back button in order to cancel JsResult
            alertDialog.setOnKeyListener(new AlertDialog.OnKeyListener() {

                @Override
                public boolean onKey(DialogInterface arg0, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        result.cancel();
                        alertDialog.dismiss();
                    }
                    return true;
                }
            });

            alertDialog.show();

            return true;
        }
    }

1 个答案:

答案 0 :(得分:0)

我设法通过覆盖WebView中的onLayout,onFocusChanged和onCheckIsEditor来解决这个问题:

this.webView = new WebView(context)
        {
            boolean layoutChangedOnce = false;

            @Override
            protected void onLayout(boolean changed, int l, int t, int r, int b)
            {
                if (!layoutChangedOnce)
                {
                    super.onLayout(changed, l, t, r, b);
                    layoutChangedOnce = true;
                }
            }

            @Override
            protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect)
            {
                super.onFocusChanged(true, direction, previouslyFocusedRect);
            }

            @Override
            public boolean onCheckIsTextEditor()
            {
                return true;
            }
        };

        this.webView.setFocusable(true);
        this.webView.setFocusableInTouchMode(true);
        this.webView.requestFocus(View.FOCUS_DOWN);

        addView(this.webView);