web-dev-qa-db-fra.com

Pourquoi Android WebView refuse-t-il la saisie de l'utilisateur?

Je développe une application Android qui utilise une WebView pour afficher la page de connexion pour Facebook. La page se charge merveilleusement bien et je peux sélectionner les zones de texte nom d'utilisateur/mot de passe, mais leur saisie ne fonctionnera pas. C’est-à-dire qu’ils ont vraiment le focus (ils ont la zone de surbrillance orange et un curseur clignotant), mais leur saisie ne fait absolument rien. Je n'en suis pas certain, mais je pense que les boutons de formulaire sont également en cours de lecture. Ils semblent simplement rafraîchir la page plutôt que de soumettre le formulaire.

Soyons clairs: bien que je sois particulièrement intéressé par le fonctionnement de Facebook, je suis certain que ce n'est pas un problème pour Facebook, car d'autres sites Web (Google, etc.) affichent également le même comportement.

Quelqu'un a-t-il une idée de ce que pourrait être le problème?

35
Mac

Il s'avère que c'est apparemment la WebView n'ayant pas le focus qui était le problème.

J'ai découvert que l'utilisation des touches fléchées pour obtenir le focus sur les zones de texte les faisait fonctionner. J'ai donc émis l'hypothèse qu'il y avait un problème quelque part avec quelque chose qui n'avait pas le focus, très probablement la WebView. Effectivement, l'ajout de la ligne suivante a semblé résoudre le problème:

webView.requestFocus(View.FOCUS_DOWN);

Je n'arrive toujours pas à expliquer exactement pourquoi le problème est survenu en premier lieu - les zones de texte doivent fonctionner, peu importe si elles sont ciblées ou si elles sont mises au point - mais au moins, j'ai une solution qui semble fonctionner .

Merci pour votre contribution wf.

44
Mac

@Mac Est-ce que cette seule ligne: 

webView.requestFocus(View.FOCUS_DOWN);

résolu votre problème? Je n'ai pas dans mon cas, mais cela fait:

mWebView.setOnTouchListener(new View.OnTouchListener() { 
@Override
public boolean onTouch(View v, MotionEvent event) {
           switch (event.getAction()) { 
               case MotionEvent.ACTION_DOWN: 
               case MotionEvent.ACTION_UP: 
                   if (!v.hasFocus()) { 
                       v.requestFocus(); 
                   } 
                   break; 
           } 
           return false; 
        }
});

juste pour votre référence.

15
DiveInto

Ce sont la plupart ont

webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setUseWideViewPort(true);
webview.requestFocus(View.FOCUS_DOWN);

et si cela ne fonctionne toujours pas, utilisez une des solutions ci-dessous

Alternative 1

webview.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_UP:                     
                    if (!v.hasFocus()) {
                        v.requestFocus();
                    }
                    break;
            }               
            return false;
        }
    });

Alternative 2

webview.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_UP:
                v.requestFocusFromTouch();  
                break;
        }               
        return false;
    }

});
11
touchchandra

Je ne sais pas si mon cas est exactement le même que le vôtre,

J'ai trouvé que l'ajout d'une ligne CSS peut résoudre le problème.

Je viens d'ajouter 

input{
    -webkit-user-select: text;
}

à mon css, alors problème résolu!

8
newbeeep

Je suis désolé de dire que rien de tout cela n'a fonctionné pour moi. Je suppose que cela dépend de votre contexte. Dans mon cas, le problème est survenu dans une fenêtre html (div absolue). Tous les autres champs de saisie allaient bien.

Décrire le problème, j'ai découvert qu'il s'agissait d'un bogue dans la vue Web. Les div positionnés contenant d'autres div position fixe/absolue divisent les champs de saisie de la page. D'où une règle que j'ai formulée pour vous (n'hésitez pas à reformuler):

si dans votre page vous avez un div positionné fixe avec des div imbriqués positionnés sans défaut (c'est-à-dire absolu, fixe, etc.), l'un des div positionné absolu suivant de votre page contenant des champs aura le comportement inattendu.

Donc, placez vos champs de saisie en haut de la page (si vous le pouvez) ou évitez les divs absolus imbriqués dans d'autres divs fixes/absolus. Cela devrait aider.

J'ai posté quelque chose à ce sujet sur mon blog si vous avez besoin de plus d'explications et de solutions de rechange: http://Java-cerise.blogspot.com/2012/02/Android-web-view-inputfields-refuse-to.html

6
twingocerise

Dans mon cas, TabHost d'un fragment précédent de la pile arrière volait le focus de l'entrée WebView à chaque pression de touche. Voici comment je l'ai corrigé:

tabHost.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
  @Override
  public void onViewDetachedFromWindow(View v) {}

  @Override
  public void onViewAttachedToWindow(View v) {
    tabHost.getViewTreeObserver().removeOnTouchModeChangeListener(tabHost);
  }
});

Voir https://code.google.com/p/Android/issues/detail?id=2516 pour plus d'informations sur le sujet.

5
Maxim Kachurovskiy

Vous ne savez pas si c'est le problème, car d'autres sites Web affichent également le même comportement, mais avez-vous activé le javascript? A WebView ne l’active pas par défaut.

WebView webView = (WebView)findViewById(R.id.yourWebView);
webView.getSettings().setJavaScriptEnabled(true);
2
wf.

J'ai essayé toutes les autres solutions publiées ici, mais aucune d'entre elles n'a fonctionné.

Au lieu de cela, j'ai étendu WebView et redéfini InputConnection, ce qui a forcé KeyEvents à envoyer.

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
  return new BaseInputConnection(this, false);
}
2
afathman

Il m'est arrivé de charger une page en 4.1.2 et 4.2.2 et après une journée de recherche, j'ai trouvé la réponse ici (commentaire n ° 18) 

Citation de l'article original:

Certaines des différentes pages Web que je rendais avec WebView ne s'intégraient pas correctement dans WebView et, par conséquent, un div (ou un autre composant html) était placé de manière invisible sur les champs de saisie. Bien que les champs de saisie semblent sélectionnés lorsque vous les touchez, ils ne permettent pas la saisie de texte (même si j’ai réussi à obtenir le clavier virtuel avec la boule de commande).

Donc la solution.

webview.getSettings().setUseWideViewPort(true);

Cela n'arrêtera pas complètement le problème, mais rendra la vue plus semblable à un navigateur PC pour lequel les sites sont conçus. Moins de changement de la superposition.

1
Mohsen Afshin

J'ai rencontré ce problème car j'affichais une image de démarrage pendant que la vue Web chargeait la première page. Je configure la vue Web sur View.VISIBLE dans onPageFinished. Cependant, même si vous pouvez mettre au point des zones de texte, vous ne pouvez pas les saisir. Je peux également confirmer que le correctif permettant de définir Webview requestFocus sur View.FOCUS_DOWN fonctionne.

NB Si je règle la vue Web sur View.VISIBLE dans onResume, le problème ne se pose pas, mais dans mon cas, l'image de démarrage disparaît trop tôt.

1
jhad

Je passe beaucoup de temps à résoudre ce problème. Finalement, j'ai réalisé qu'il ne s'agissait pas de WebView. Dans mon cas, j'ai une vue Web dans la boîte de dialogue. Je veux manipuler le bouton enfoncé en arrière pour annuler le dialogue et terminer l'activité également. Et j'ai écrit le code ci-dessous:

private void setOnBackPressed() {
    this.setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                dialog.dismiss();
                activity.finish();
            }
            return true;
        }
    });
}

Ainsi, lorsque j'utilise le clavier, cette méthode rejette toutes les pressions sur les touches, puis n'apparaît pas dans les champs de texte.

J'ai seulement changé la valeur de retour en false . Donc, cela a fonctionné correctement.

J'espère que ça aide!!

PS: cette méthode est à l'intérieur de ma classe de dialogue qui étend la classe Dialog

1
sembozdemir

J'ai trouvé un problème qui pourrait être différent, mais cela semble similaire. Dans le navigateur natif d'Android 2.3, si vous avez des éléments de position fixes sur la page, cela casse parfois les zones de sélection.

Une solution de contournement à ce problème pour les périphériques 2.3 consiste à ne jamais autoriser d'éléments enfants vides pour un parent à position fixe. Ainsi,

<div style="position:fixed">
  <div>
    <span>not empty</span>
    <span></span>
  </div>
</div>

deviendrait

<div style="position:fixed">
  <div>
    <span>not empty</span>
    <span>&nbsp;</span>
  </div>
</div>

Cela a résolu mon problème.

Je ne sais pas si cela était votre problème, et c'est plus d'un an après les faits, mais je pensais que je le partagerais, car je suis actuellement confronté à un autre problème de positionnement fixe sur une application, et je n'ai pas t trouvé une solution de contournement pour cela.

0
Daniel

dans mon contexte (webview contenant une URL externe), ce fragment fonctionne:

    webview.setOnTouchListener(new View.OnTouchListener() {
       @Override
       public boolean onTouch(View v, MotionEvent event) {
           switch (event.getAction()) {
               case MotionEvent.ACTION_DOWN:
               case MotionEvent.ACTION_UP:
                   v.requestFocusFromTouch();  
                   break;
           }               
           return false;
       }

});

l'erreur est due au fait que la vue Web perdait de son intérêt à chaque contact!

0
edwindh

Je suis confronté à un problème similaire, que les entrées de texte ne fonctionnent pas sur WebView. Lorsque vous vous concentrez sur la saisie de texte, le clavier est affiché, mais vous ne pouvez saisir aucun caractère.

Après une longue recherche de solution, j'ai trouvé que cela corrigeait le problème:

body {
    -webkit-transform: translate3d(0,0,0);
    -moz-transform: translate3d(0,0,0);
    -ms-transform: translate3d(0,0,0);
    -o-transform: translate3d(0,0,0);
    transform: translate3d(0,0,0);
}

Si j'ai bien compris, cette règle fait que certains périphériques exécutent leur accélération matérielle . Plus d'informations sur translate3d (0,0,0) ici.

Par contre, selon cet article article , il n’est pas recommandé d’utiliser partout l’accélération GPU.