Pourquoi mon activité Android commence-t-elle toujours à défiler vers le bas?


91

Chaque fois que je commence cette activité, elle commence toujours par le bas - défilée jusqu'en bas. Je ne fais rien de bizarre dans l'activité OnCreate (ou n'importe où d'ailleurs) dont je m'attendrais à changer la position du défilement. J'ai essayé de définir le focus sur le contrôle focusable le plus haut et la méthode scrollto, mais aucun d'eux ne fonctionne. D'ailleurs, aucune de mes autres activités n'a ce problème. Voici la mise en page:

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/edit_refresh_update_header"
            android:textSize="18sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Variable:"
            android:textSize="18sp"/>

        <Spinner
            android:id="@+id/edit_refresh_variables_spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Network:"
            android:textSize="18sp"/>

        <RadioGroup
            android:id="@+id/widget1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical">

            <RadioButton
                android:text="Web"
                android:id="@+id/edit_refresh_update_rb_web"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="NetRadioButtonSelected"
                android:checked="true"/>

            <RadioButton
                android:text="Socket Server"
                android:id="@+id/edit_refresh_update_rb_socket_server"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="NetRadioButtonSelected"/>
        </RadioGroup>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Socket server request type:"
            android:textSize="18sp"/>

        <Spinner
            android:id="@+id/edit_refresh_socket_server_req_types_spinner"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Socket server body:"
            android:textSize="18sp"/>

        <EditText
            android:layout_width="match_parent"
            android:id="@+id/edit_refresh_update_ss_body"
            android:layout_height="wrap_content"
            android:enabled="false"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Url:"
            android:textSize="18sp"/>

        <EditText
            android:layout_width="match_parent"
            android:id="@+id/edit_refresh_update_url"
            android:layout_height="wrap_content"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>

        <Button
            android:text="Save refresh update"
            android:id="@+id/edit_refresh_save_btn"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:layout_marginLeft="20dip"
            android:layout_marginRight="20dip"
            android:layout_marginBottom="20dp"
            android:layout_alignParentBottom="true"
            android:onClick="SaveRefreshUpdate">
        </Button>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="\n"
            android:textSize="4sp"/>
    </LinearLayout>
</ScrollView>

Comment avez-vous essayé de changer d'orientation?
devmiles.com

1
en utilisant la méthode fulscroll comme décrit ci-dessous et la méthode scrollto comme également décrite ci-dessous. Cela ne me dérange pas nécessairement de le réparer de cette façon, mais il doit y avoir une raison pour laquelle cela commence comme ça et je préfère le réparer en corrigeant cela.
MrGibbage

Réponses:


306

Lorsque Android démarre une activité, certains contrôles doivent être mis au point. Lorsqu'il n'y a pas de contrôle désigné pour prendre le focus, le système choisit le premier contrôle éligible qui souhaite le focus. Si vous définissez la propriété suivante dans votre LinearLayout, android:focusableInTouchMode="true"vous LinearLayoutserez concentré sur le démarrage et votre activité ne défilera pas jusqu'en EditTextbas.


Ne fonctionne pas dans mon GridLayout. J'ai un GridView au milieu de la mise en page, et il obtient le focus à chaque fois.
Iqbal

2
Je me suis gratté la tête pendant une journée complète et je n'ai pas pu trouver pourquoi cela se produisait dans une seule activité particulière et je ne comprends toujours pas car je n'ai activé la mise au point sur aucune vue. Mais grâce à vous, j'ai réussi à résoudre ce problème. Ce serait formidable si quelqu'un pouvait jeter un peu de lumière sur ce qui pourrait être la raison possible, car il n'y a rien de nouveau que je fais dans la nouvelle activité.
Shubhral

2
Remarque importante: ceci doit être ajouté en tant que propriété à l' LinearLayoutintérieur du ScrollView, et non à la vue de défilement elle-même.
Boris Strandjev

@BorisStrandjev note très importante. Doit être ajouté à la réponse. Au fait, merci pour cela: P
Coreggon

Il est littéralement mentionné dans la réponse.
devmiles.com

35

Au lieu d'éléments polluants dans votre mise en page, vous pouvez ajouter ceci à votre activité / classe:

    ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
    scrollView.setFocusableInTouchMode(true); 
    scrollView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);

De cette façon, ce n'est pas un élément dans votre scrollView qui obtient le focus, c'est votre scrollView en tant que conteneur qui obtient le premier focus, se déplaçant vers la vue enfant après cela.


Fonctionne partiellement pour moi lorsque j'essaie de définir la hauteur de ListView en fonction des enfants à l'intérieur de ScrollView
Konstantin Konopko

Cela a aidé! (alors que les mêmes attributs en xml ne fonctionnaient pas.)
Matan Dahan

Fonctionne comme un charme! Thx
Bogy

Cela a fonctionné pour moi, mais j'ai ajouté cette ligne: scrollView.fullScroll (ScrollView.FOCUS_UP) Les deux séparément ne fonctionnaient pas.
Juan Giorello

3

Vous pouvez essayer ce code:

scroller.post(new Runnable() { 
    public void run() { 
        scroller.fullScroll(ScrollView.FOCUS_DOWN); 
    } 
}); 

[N: B] [lien de référence] 1


1
c'est une bonne option mais elle simule une secousse après l'ouverture, donc pas une bonne expérience utilisateur je pense
iBabur

2

Avec ce que devmiles.com a dit.

Si vous définissez la propriété suivante dans votre LinearLayout - android: focusableInTouchMode = "true", votre LinearLayout sera concentré sur le démarrage et votre activité ne défilera pas jusqu'à EditText en bas.

Si vous appelez requestLayout () sur une vue en bas de votre mise en page linéaire, cela peut voler le focus de votre vue la plus haute. Appelez donc simplement requestFocus () sur la vue la plus en haut de la disposition linéaire après avoir appelé requestLayout () sur une vue inférieure.


1

Avez-vous essayé d'utiliser la méthode fullScroll? Http: //developer.android.com/reference/android/widget/ScrollView.html#fullScroll (int)

yourScrollView.fullScroll(ScrollView.FOCUS_UP);

1

Pour le développement Xamarin Android, si vous souhaitez faire une solution @Graeme,

// Set Focus to ScrollView
ScrollView scrollView = (ScrollView)FindViewById(Resource.Id.scrollView);
scrollView.FocusableInTouchMode = true;
scrollView.DescendantFocusability = Android.Views.DescendantFocusability.BeforeDescendants;

1

Rendez-le simplement non focalisable dans onCreate ()

editText.setFocusable(false);

et utilise

editText.setOnClickListener(new ....){
 ......
  editText.setFocusable(true);
  editText.setFocusableInTouchMode(true);
  editText.requestFocus();

  showSoftKeyboard(); //Use InputMethodManager to open soft Keyboard

 ......
 };

et il ne défilera pas jusqu'à Edittext la prochaine fois, un fragment ou une activité est créé.


1

Ajoutez ces deux lignes dans votre ScrollView

 android:focusableInTouchMode="true"
 android:descendantFocusability="blocksDescendants"

0

Je ne sais pas pourquoi mais tu pourrais expérimenter avec

ScrollView sv = (ScrollView) findViewById(R.id.scroll);
sv.scrollTo(0,0);

dans votre onCreatepour le faire défiler manuellement là où vous le souhaitez.


0

scrollView.requestFocus(View.FOCUS_UP)a résolu mon problème lorsque je voulais que la vue de dessus soit visible. La spécification du paramètre de direction à la méthode requestFocus(int direction)est un bon moyen de contrôler la ScrollViewposition. Plus de détails ici .


0

Dans mon cas, j'avais un VideoViewintérieur un ConstraintLayoutintérieur un ScrollView. Le VideoViewvolais toujours mise au point, et il y a des problèmes avec elle . La solution consiste à utiliser un fichier TextureView. J'espère que cela aide quelqu'un, cela m'a coûté une heure au moins :)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.