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>
MrGibbage
la source
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.

devmiles.com
la source
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.

Graeme
la source
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

Communauté
la source
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.

luca992
la source
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);
Mike
la source
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;
Guirlande d'Asher
la source
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éé.

codepeaker
la source
1

Ajoutez ces deux lignes dans votre ScrollView

 android:focusableInTouchMode="true"
 android:descendantFocusability="blocksDescendants"
Hemendra Gangwar
la source
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.

zapl
la source
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 .

Amit
la source
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 :)

Daniel Wilson
la source