2014-07-14 6 views
5

Ce que je veux archiver peut être mieux expliqué avec une imageConserver la position de défilement ScrollView pour le contenu dynamique

enter image description here

La boîte grise représente l'écran, la boîte bleue est méta information, la boîte arrondie blanche un SearchView et les cases rouges sont des éléments renvoyés par la recherche.

J'ai eu ce travail jusqu'à présent, mais le problème se produit lorsque l'utilisateur cherche quelque chose et les éléments dépassent l'écran (1). Ensuite, l'utilisateur fait défiler vers le bas, de sorte que les informations méta sont en dehors de l'écran (2). L'utilisateur peut maintenant entrer une nouvelle requête de recherche et ainsi modifier les éléments. Cependant, lorsque la nouvelle requête retourne trop peu d'éléments pour remplir le reste de l'écran (3), ScrollView va "revenir" en haut (pas dans l'image, pas désiré). Ce que je veux, c'est un comportement où le SearchView reste en place (3). Une fois dans cet état, l'utilisateur peut revenir en haut (4). Si elle le fait, elle ne peut pas revenir en arrière, à la place, les indicateurs de surréglementation s'afficheront.

Un comportement similaire peut être observé dans l'application Google+. De l'écran de démarrage allez à votre profil (appuyez sur votre nom en haut). Vous verrez trois registres ("À propos de moi", "Messages", "Photos" *). J'ai par exemple pas de photos là-bas et le comportement est tel que décrit.

éditer Le ScrollView est la racine de la vue.

modifier structure de mise en page de base

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="fill_parent" 
    android:overScrollMode="always" 
    android:fillViewport="true"> 

    <LinearLayout 
     android:orientation="vertical" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 
     <View /> <!-- Meta info --> 
     <SearchView /> 
     <View /> <!-- Item representing search result --> 
     <View /> <!-- Item representing search result --> 
     <View /> <!-- Item representing search result --> 
     <View /> <!-- Item representing search result --> 
     <View /> <!-- Item representing search result --> 
    </LinearLayout> 
</ScrollView> 

*) Traduction de l'App On suppose allemande.

+0

Comme je ne suis pas familier avec la façon dont cela est fait, peut-être que vous pouvez fournir des extraits de quelles classes sont utilisées pour atteindre ce comportement de défilement que vous avez travaillé jusqu'à présent. Réfléchir au processus et essayer de trouver une approche. –

+1

Avez-vous essayé d'utiliser scrollTo() pour décaler le ScrollView? Je ne sais pas si c'est ce que vous devriez utiliser, mais cela peut aider. – zgc7009

+0

C'est juste un ScrollView simple autour de tout le reste. Rien d'extraordinaire. – Mene

Répondre

0

Puisqu'il ne semble y avoir aucune solution standard dans l'android sdk, ni aucun code public faisant cela, j'ai bricolé ma propre solution. Ceci est ma solution de travail:

J'ai enveloppé les résultats de recherche dans un LinearLayout et utilisé minimumHeight pour archiver le comportement souhaité. De cette façon, je n'ai pas besoin de manipuler les mesures lorsque des éléments sont ajoutés à la liste.

<LinearLayout 
    android:id="@+id/scroll_placeholder" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    > 
    <View /> <!-- result --> 
    <View /> <!-- result --> 
    <View /> <!-- result --> 
</LinearLayout> 

Résultats de la recherche sont récupérés asynchrones donc j'effacer la liste et commencer un indicateur de recherche quand une nouvelle recherche est déclenchée. À ce stade, j'ai également fixé la hauteur minimale à la taille du rectangle visible du itemList. Notez que le itemList n'est pas un ScrollView, sinon il y aurait un ScrollView dans un ScrollView ce qui est problématique. C'est fondamentalement un LinearLayout contenant les résultats.

int scrollY = rootScrollView.getScrollY(); 
if (scrollY > 0) { 
    final Rect visibleListViewRect = new Rect(); 
    placeholder.getGlobalVisibleRect(visibleListViewRect); 
    placeholder.setMinimumHeight(visibleListViewRect.height()); 
} else { 
    placeholder.setMinimumHeight(0); 
} 

Ceci donnera le comportement comme vu dans l'image 3) de la question.

Pour désactiver le défilement vers le bas une fois que l'utilisateur a fait défiler vers le haut (Image 4) J'ai ajouté un ScrollChangedListener:

placeholder.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { 
    @Override 
    public void onScrollChanged() { 
     int scrollY = placeholder.getScrollY(); 
     if (scrollY > 0) { 
      final Rect visibleListViewRect = new Rect(); 
      placeholder.getGlobalVisibleRect(visibleListViewRect); 
      placeholder.setMinimumHeight(visibleListViewRect.height()); 
     } else { 
      placeholder.setMinimumHeight(0); 
     } 
    } 
}); 

Et voilà.

0

puisque vous n'avez mentionné aucun code. concentrer.

Essayez d'utiliser

ScrollView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); 

et aussi lorsque votre SearchBox est utilisé, vous pouvez le faire par programme

searchBox.requestFocus() 

pour plus de contrôle, vous pouvez également essayer MotionListener.If vous pouvez également ajouter le code I pourrait être plus spécifique. Et ne pas oublier de vérifier les méthodes d'affichage de défilement http://developer.android.com/reference/android/widget/ScrollView.html

jouant FYI avec un accent vous donnera beaucoup de scénarios intéressants et des animations/motions aussi :)

+0

J'ai ajouté un aperçu de ma mise en page. Mais honnêtement, je ne peux pas voir comment cela a quelque chose à voir avec l'accent. – Mene

+1

Ok .. Que faire si vous avez ajouté une autre disposition en dessous de votre linearlayout (vues de liste) .. Pour remplir la partie restante de la disposition de la vue de défilement. – Droidekas

+0

Oui, c'est la solution que je suis en train de mettre en œuvre maintenant. C'était aussi la première façon de le résoudre qui m'est venue à l'esprit, mais c'est en fait assez compliqué si vous gardez à l'esprit l'image 4). J'espérais quelque chose de plus simple, d'autant plus que c'est fait dans Google+. – Mene

0

Peut-être que je vais avoir le temps de revenir à plus tard et mettre à jour avec des détails supplémentaires sur la façon dont je pense que j'aborderais cela. Mais pour l'instant je vais juste poster quelque chose que j'ai le temps pour.

Je crois que cela serait fait avec un scrollview ci-dessous et juste une vue ci-dessus. Un sur les méta-données et le searchview et un autre sur les éléments que vous voulez faire défiler dans une liste simulée.

Une vérification devrait être effectuée lorsque vous faites défiler la liste simulée ci-dessous. Diminuer la taille de la vue ci-dessus par des actions de la scrollview ci-dessous en fonction des auditeurs sur la scrollview; à la limite de la taille de la vue de recherche. Ensuite, lorsque la condition est remplie que la vue de défilement ci-dessous a atteint la fin, agrandissez la vue supérieure pour remplir l'espace.

Questions connexes