49 votes

Empêcher ScrollView de défiler automatiquement vers un EditText

Semble être un problème commun sans une excellente solution que j'ai trouvé. L'objectif est d'arrêter une ScrollView de défilement automatique pour un EditText (ou de n'importe quelle vue d'ailleurs) qui a le focus.

Vous avez un tas de points de vue (boutons, textviews, etc) dans un Scrollview, dont l'un est un EditText. En cliquant sur le dire d'un Bouton à l'intérieur de la Scrollview, la Scrollview défile vers le bas à l'EditText (son hors de l'écran). Ce n'est pas souhaité, comme il y a d'autres éléments que vous ne voulez pas d'un défilement de l'écran.

Maintenant, je peux arrêter ce qui se passe lorsque l'écran montre d'abord par le fait d'avoir d'autres focusable éléments dans la scrollview. Cependant, le problème existe toujours. L'utilisateur fait défiler manuellement à l'EditText, entre quelques chiffres, puis défiler vers le haut vers le haut (EditText hors de l'écran, maintenant), ils cliquent sur un bouton dans la ScrollView, et devinez quoi? La ScrollView défile vers le bas à ce fameux EditText.

Je suis en train de réfléchir sous-classement de la Scrollview et en remplaçant certaines des méthodes privées comme findFocusableViewInBounds, mais j'ai le sentiment que je vais juste être moi-même en plus de problèmes.

S'il vous plaît aider si vous le pouvez.

J'ai joué avec des choses comme avoir un 0 hauteur EditText en haut de mon Scrollview, en ajoutant de la Prochaine Focusable les propriétés d'un élément parmi les autres éléments de la ScrollView, etc. Je suppose que l'une des "hack" est peut-être pour obtenir le EditText à perdre le focus quand le virtuel ou le clavier manuel obtient cachés ou quelque chose.

38voto

thomas88wp Points 801

Après avoir lutté avec le problème pour un certain temps, j'ai trouvé une solution qui semble fonctionner sans être trop laid. Tout d'abord, assurez-vous que quelle que soit ViewGroup (directement) contient votre EditText a DescendantFocusability mis à "Avant de Descendants," Focusable à "true", et FocusableInTouchMode définie sur "true". Ce ne sera pas le ScrollView lui-même, mais la mise en page à l'intérieur où vous avez vos différents points de vue. Ajoutez ensuite un onTouchListener à votre ScrollView qui enlève le focus de l'EditText chaque fois qu'il est touché, comme suit:

ScrollView scroll = (ScrollView)findViewById(R.id.scrollView1);
scroll.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (myEditText.hasFocus()) {
            myEditText.clearFocus();
        }
        return false;
    }
});

Dites-moi si cela ne résout pas le problème. Ce qui devait arriver est que la Mise en page obtient le focus au lieu de l'EditText, donc pas de défilement doit arriver.

27voto

KeT4yn Points 31

Créez simplement une vue vide en haut de la présentation linéaire

 <View android:layout_width="fill_parent" android:id="@+id/focus_view" android:layout_height="0dp" android:focusable="true" android:focusableInTouchMode="true"><requestFocus/></View>
 

Une seule ligne résout le problème

10voto

pawelzieba Points 10393

J'ai eu le même problème. Il y a une astuce que j'utilise pour résoudre ce problème:

 public void onClick(View v) {
    button.requestFocusFromTouch(); //prevents from loosing focus and scrolling view down
    ....
}
 

9voto

Corbella Points 558

Le problème ne concerne pas le code java, mais le code manifeste.

Dans votre AndroidManifest.xml, ajoutez un attribut à l'activité:

         <activity android:name=".MyActivity" android:windowSoftInputMode="adjustPan"> </activity>
 

4voto

SaKet Points 844

Voici ce que j'ai fait

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" style="@style/measurementTableRowStyle"
    android:focusable="true" android:layout_height="fill_parent">
    <requestFocus></requestFocus>
    <LinearLayout android:id="@+id/linearLayout1"
        android:orientation="horizontal" android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <TextView android:id="@+id/desc_text" android:text="Value : "
            style="@style/attributeNameTextStyle" android:layout_width="wrap_content"
            android:focusable="true" android:layout_height="wrap_content">
            <requestFocus></requestFocus>
        </TextView>

        <TextView style="@style/attributeValueStyle" android:id="@+id/value_text"
            android:text="TextView" android:layout_width="wrap_content"
            android:layout_height="wrap_content"></TextView>
    </LinearLayout>
 

La raison est que dans de tels cas, vous devez rendre toutes les autres vues focalisables dans la vue de défilement par un android:focusable="true" explicite, puis <requestFocus></requestFocus> . Cela devrait fonctionner à chaque fois que l'OMI

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X