Comment faire pour désactiver le défilement de NestedScrollView&CollapsingToolbarLayout, par exemple quand il n'y a pas plus de contenu ci-dessous?
Fond
J'essaie d'ajouter la même fonctionnalité comme illustré sur de nombreuses applications, où la partie supérieure de l'écran se rétrécit&étend selon l'défiler le contenu.
Pour cela, j'utilise Google bibliothèque de conception, comme illustré sur le CheeseSquare exemple.
Le problème
Chose est, n'importe comment beaucoup de contenu, il est dans le NestedScrollView , ça me permet de faire défiler au-dessous de la dernière vue du contenu, juste de me laisser voir l'état final de l'actionbar, ayant la taille minimale de lui-même.
En bref, c'est ce que je vois lorsque le défilement vers le bas (modifié le contenu de CheeseSquare de l'échantillon):
alors que c'est ce que j'aimerais avoir en cas de défilement vers le bas (prises à partir de l'application de contacts) :
Je suis aussi en train d'essayer de corriger un bug sur ThreePhasesBottomSheet échantillon de défilement en bas de la feuille de contenu est possible, même quand il est en peek-état. De reproduire, de commencer à faire défiler horizontalement (ce qui ne veut pas faire n'importe quoi, comme il n'y a rien à faire défiler de cette façon) et puis à la verticale, ce qui serait en quelque sorte de déclencher le défilement du contenu de la partie inférieure de la feuille.
Donc, j'ai besoin de désactiver il y a le défilement dans "transformView()" la méthode, dans le cas que "la traduction
C'est la façon dont il fonctionne à l'aide de l'utilisation normale:
Et ce est la façon dont il se comporte avec le bug de ne pas bloquer le défilement:
Ce que j'ai essayé
J'ai essayé de jouer avec le "layout_scrollFlags" drapeaux, pour modifier la hauteur de wrap_content, et de supprimer les clipToPadding et fitsSystemWindows attributs.
Voici l'exemple de fichier XML, que j'ai modifié pour inclure qu'une seule cardView au lieu de plusieurs:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/detail_backdrop_height"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Info"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/cheese_ipsum" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
android:src="@drawable/ic_discuss"
android:layout_margin="@dimen/fab_margin"
android:clickable="true"/>
</android.support.design.widget.CoordinatorLayout>
J'ai essayé le code suivant: les
((AppBarLayout.LayoutParams) collapsingToolbar.getLayoutParams()).setScrollFlags(0);
mais il y a encore permis de défilement de la NestedScrollView lui-même dans le CheeseSquare exemple, et permet aussi la jetant dans le ThreePhasesBottomSheet de l'échantillon .
Les questions
-
Que puis-je faire afin de rendre le défilement s'arrêter quand il n'y a pas plus de contenu à afficher en bas?
-
En outre, ce qui peut être fait pour désactiver le défilement de la NestedScrollView en tout temps, je souhaite ( pour le ThreePhasesBottomSheet exemple) ? Quelque chose comme "setEnableScrolling(...)" ?
J'ai essayé d'étendre NestedScrollView et également s'étendre à partir de ScrollingViewBehavior, mais pas réussi à trouver ce qui peut être fait pour désactiver le défilement.
C'est probablement une chose très simple à changer, mais je ne peux pas trouver ce que...
EDIT: si nécessaire, c'est ce que j'utilise actuellement pour la conception&bibliothèque de prise en charge
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:design:23.1.0'
EDIT: pour le #2, j'ai trouvé une solution de contournement à partir de l'intérieur de la BottomSheetLayout.java fichier, de désactiver tout ce qui est lié à la variable "sheetViewOwnsTouch", comme si c'est toujours la valeur "false". Cela permettra de voler les événements tactiles sur le bas de la feuille. Cependant, c'est juste une solution de contournement, et seulement dans ce cas. Il provoque aussi certains événements tactiles qui doit avoir été traité par d'autres points de vue. Je souhaite toujours de savoir comment faire pour bloquer le défilement de la programmation, et aussi dans les autres cas de suffisamment d'espace-pour-afficher-le contenu.
- Aucune idée, mais s'il vous plaît donner la version de bibliothèque que vous avez utilisé trop, et comment vous imolement votre point de vue (de défilement drapeau, etc ..)
- J'ai seulement changé le contenu de la mise en page (pour avoir textViews au lieu de cardViews), de montrer à ces captures d'écran. J'ai mis à jour la question afin de montrer les bibliothèques versions. Pourquoi downvote pour cela ?
- Désolé, je ne pense pas que c'était moi à la baisse de voter à votre question. De toute façon je vais prendre un coup d'oeil
- Avez-vous essayé d'utiliser canScrollVertically? Peut-être que si vous retourne la valeur false, le défilement s'arrête.
- Return false sur lequel cas, et dans lequel la fonction de l'appeler?
- Vous utilisez votre propre
NestedScrollView
et de redéfinir cette méthode. Que peut-être vérifier votre dernièreView
getBottom
, siview.getBottom()==screenHeight - softButtonsHeight
alors vous êtes à la fin de l'écran, vous ne devriez pas faire défiler jusqu'à. Aussi n'oubliez pas d'obtenir à vérifier le sens du défilement. - Intéressant. Avez-vous essayé?
- Malheureusement, aucune. Mais si je devais faire quelque chose comme ça, ce serait mon premier essai.
- Ce qui est "softButtonsHeight" ? la hauteur de la vue d'en bas?
- Le bouton de retour, accueil et applications récentes des boutons sur le nouveau système d'exploitation android-es. Vous devez également supprimer la barre d'état de hauteur. C'est pour calculer exactement où est le bas de l'écran.
- Êtes-vous sûr que c'est nécessaire, au lieu de simplement obtenir la hauteur de la vue parent ?
- Cela devrait fonctionner, ouais. Je suppose que vous auriez besoin de les parents de la hauteur. Ligne du bas est-vous besoin de connaître la valeur sur laquelle arrêter le défilement vertical, comment vous obtenez cette valeur n'a pas vraiment d'importance, tant qu'il donne de la valeur correcte.
- Quelque chose de bizarre: j'ai créé une nouvelle classe qui étend la classe NestedScrollView , et seulement écrit pour le journal pour chaque temps canScrollVertically est appelé. Il semble qu'il n'est pas appelée assez souvent (seulement sur le premier événement de défilement vers le bas/haut lot d'événements), donc je ne pense pas que cette solution peut fonctionner . C'est bizarre, parce que je m'attends à être appelé très souvent, aussi longtemps que je me défiler. Non seulement cela, mais même si j'ai ajouté un si(sens>0) condition, il est appelé lorsque le défilement en haut et en bas, et pas un seul d'entre eux...
- C'est bizarre. Je suppose que cela ne marchera pas. Une autre solution je pense est de: Ajouter un
ScrollListener
à votreNestedScrollView
lorsque vous faites défiler un montant égal à votre contenu de hauteur, utiliser ViewCompat.setNestedScrollEnabled, avec des arguments de votreNestedScrollView
et fausse, contraire à la vraie. Je n'aime pas cette solution, mais je pense que cela pourrait fonctionner. - Il n'y a pas de scrollListener pour NestedScrollView (au moins pas quelque chose que Android Studio affiche). Seule chose que j'ai trouvé est setOnScrollChangeListener , mais ensuite il est dit: il a besoin de l'API 23 au travail, et même alors, il ne semble pas appelée.
- En outre, même lorsque l'extension de la NestedScrollView, à peine n'importe quelle fonction qui a le mot "arrêt" dans elle est appelée, et aucun n'est appelée plusieurs fois lorsque vous causer de multiples événements de défilement.
- setOnScrollChangeListener il dit que cela devrait fonctionner tout le chemin vers v4.
- Laissez-nous continuer cette discussion dans le chat.
- C'est donc un bug dans l'IDE ensuite. En tout cas, il n'est pas appelée à tous (testé sur Android 6) , de sorte qu'il ne peut pas l'aider.
- développeur si vous regardez de près, c'est une méthode différente. Il utilise
NestedScrollView.OnScrollChangedListener
au lieu deView.OnScrollChangedListener
. Pouvez-vous essayer à nouveau? - Oh, maintenant ça fonctionne. La Question est, maintenant ce qui? Je suis actuellement à la maison, donc j'y reviendrai quand je serai de retour au bureau. Assez curieux de voir maintenant...
- Bien l'idée reste la même. Utilisation scrollY et oldScrollY afin de déterminer si vous pouvez faire défiler vers le haut. Si pas de désactiver nestedScrolling sinon l'activer. Je vais essayer de faire de test de l'échantillon, si je le faire fonctionner, je vais poster une réponse.
- L'écoute de
NestedScrollView
faire défiler les changements ne fonctionne pas. Si leView
est trop petit pour faire défiler, vous ne recevrez pas les mises à jour. Je pense que votre meilleur pari est de mettre en œuvre un custom le Comportement. - Que voulez-vous dire qu'il ne fonctionne pas? Aussi, ce que je fais pour le faire bloquer le défilement de lui-même?
- Ce n'est pas vous voulez, je suppose, mais cela peut vous aider: vous pouvez décider s'est effondré taille en changeant android.de soutien.v7.widget de.La hauteur des barres d'outils
- Intéressant. Pouvez-vous démontrer?
- Peut-être liés: stackoverflow.com/questions/32404979/...
- Je parle NestedScrollView. Vous dites que je devrais utiliser RecyclerView à la place?
- Désolé, ne peut pas servir ici, seul le relais à un lien posté par un autre utilisateur (réponse a été depuis supprimé, car il était destiné à être un commentaire, mais l'utilisateur avait trop faible rep de commentaire).
- qu'avez-vous utilisé pour créer le Gif?
- D'abord capturer l'écran dans un fichier vidéo (utilisation de la BAD ou Android Studio), puis de le convertir en un fichier gif en utilisant n'importe quel outil que vous souhaitez, comme celui-ci: image.online-convert.com/convert-to-gif
- Pourquoi est-il utile? Premier lien ne fonctionne pas. Second lien a beaucoup de contenu à afficher dans la NestedScrollView, de sorte qu'il peut même pas la question, où suffisamment de contenu est affiché sur l'écran.
- Vous pourriez décompiler l'application(Contacts?) ou essayer de trouver le code source: github.com/android/platform_packages_apps_contacts
- Le code il est très complexe à lire, et nous avons un calendrier de travail avec. Aussi, je ne pense pas qu'ils utilisent NestedScrollView ou quoi que ce soit de la bibliothèque de conception.
- Le linearlayout ci-dessus cardview est d'avoir height = match_parent, avez-vous essayé avec wrap_content. c'est pour le 1er problème.
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, comme je l'ai expliqué ci-après, le défilement vous avez dit dans votre question n'est pas de la
NestedScrollView
. Il appartient à laCollapsingToolbarLayout
. LeNestedScrollView
's défiler événement ne se produit que lorsqueCollapsingToolbarLayout
complètement effondré, et bien sûr, il va arrêter le défilement quand il n'y a pas plus de contenu à l'intérieur (en bas atteint). Pour leCollapsingToolbarLayout
, il va s'effondrer à sa Barre d'outils du layout_height (comme dans le fichier xml, vous trouverez"?attr/actionBarSize"
). L'image suivante sera de démontrer que, prêter attention à la rouge rectangulaire qui est de la barre d'outils (j'ai mis son arrière-plan)Afin d'avoir une solution pour votre #1, vous devez calculer la hauteur de
NestedScrollView
, puis si elle est plus petite que la hauteur de l'écran, nous fixons la barre d'outils de la hauteur.En bref, vous pouvez mettre à jour
activity_detail.xml
comme suit:Et CheeseDetailActivity.java:
Voici le résultat:
Avec Cheesesquare exemple, j'ai personnalisé ce projet et téléchargés à Mon GitHub. Je suis d'accord qu'il y a encore quelques problèmes, mais, au moins, il peut être une solution pour ton 1er problème.
Veuillez jeter un oeil. Espérons que cela aide!
nestedScrollView.setOnScrollChangeListener
, vous pouvez le voir, il n'arrive que la vidéo suivante drive.google.com/file/d/0B2HGUM4c0YwpZkVwSEhYWWc1cnM/...toolbarHeight = toolbarLayoutParams.height;
etif (linearLayoutHeight + toolbarHeight < screenHeight)
activity_detail.xml
vous verrez que j'ai commenté un cardview 🙂the title moves in a very weird way compared to the original
, IMO c'est parce que j'utilise SnagIt pour capturer de la vidéo, puis de les convertir à l'ani-gif de sorte qu'il n'est pas très beau, en fait, dans le réel du téléphone et de l'AVDs, c'est sympa :). Je ne peux pas utiliserScreen Record
fonctionnalité dans Android Studio, mon téléphone est Android 4.1.2FloatingActionButton
disparu, je n'ai pas vérifié pourquoi, de toute façon, je pense que ce n'est pas la principale exigence dans votre #1 problème, donc je l'ai enlevé pour l'instant.collapsingToolbar's title disappeared
, pls attention àappbarLayoutParams.height = toolbarLayoutParams.height + 70;
. Je pense qu'il n'y a pas d'espace pour le titre après le réglage de la barre d'outils de la hauteur, donc, nécessité d'augmenter la hauteur de la barre d'applications, pourquoi 70, en fait, je ne sais pas, juste d'augmenter à partir de 40, 50,... je pense qu'il faut beaucoup d'appareils/avds pour tester plus. Veuillez noter que je l'ai mise à jour de cette réponse, pas de projet GitHub à cette époque (peut-être demain matin)android:layout_height="170dp"
, par exemple, pourandroid.support.v7.widget.Toolbar
, le titre n'est pas aligné pour le fond de l'en-tête arrière-plan, il se déplace beaucoup trop 🙂Pour désactiver le défilement, il suffit de mettre les deux NestedScrollView et c'est LinearLayout enfant hauteur de "wrap_content'.
Qui ne sera pas tout à fait comme vous le voulez, mais au moins il ne sera pas de défilement, si le contenu s'adapte à l'écran complètement.
Parler de votre application Contacts exemple, on dirait qu'elle n'est pas à l'aide de CoordinatorLayout et d'autres choses qui vont avec.
Ce comportement peut être fait de cette façon:
Et dans votre code vous permettra de déplacer l'image sur parchemin:
J'ai extrait d'un de mes projets et édité, donc je ne peux manquer de quelque chose.