J'essaie d'implémenter CollapsingToolbarLayout avec une vue personnalisée, mais je ne peux pas le faire:
Ce que je veux faire (désolé, je ne peux pas publier d'images, c'est donc imgur):
Développé, l'en-tête est un écran de profil avec image et titre
Pas développé (sur défilement), l'image et le titre seront sur la barre d'outils
Mais tout ce que j'ai vu ne fonctionnait pas comme je m'y attendais
Je suis novice dans ce domaine et dans les animations Lollipop, donc si quelqu'un pouvait m'aider, je vous en serais très reconnaissant!
(Je ne publie pas d'exemple de code car je n'ai rien de pertinent à publier)
Ma solution
J'avais le même scénario à mettre en œuvre, j'ai donc commencé avec l'exemple de chien et j'ai apporté quelques modifications pour qu'il fonctionne exactement comme vous le décrivez. Mon code peut être trouvé en tant que fork sur ce projet, voir https://github.com/hanscappelle/CoordinatorBehaviorExample
Les modifications les plus importantes concernent la mise en page:
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
>
<Android.support.design.widget.AppBarLayout
Android:id="@+id/main.appbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
>
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/main.collapsing"
Android:layout_width="match_parent"
Android:layout_height="@dimen/expanded_toolbar_height"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
>
<FrameLayout
Android:id="@+id/main.framelayout.title"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_gravity="bottom"
>
<LinearLayout
Android:id="@+id/main.linearlayout.title"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="bottom|center_horizontal"
Android:orientation="vertical"
Android:paddingBottom="@dimen/spacing_small"
>
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center_horizontal"
Android:gravity="bottom|center_horizontal"
Android:text="@string/tequila_name"
Android:textColor="@Android:color/white"
Android:textSize="@dimen/textsize_xlarge"
/>
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center_horizontal"
Android:layout_marginTop="@dimen/spacing_xxsmall"
Android:text="@string/tequila_tagline"
Android:textColor="@Android:color/white"
/>
</LinearLayout>
</FrameLayout>
</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"
Android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:lineSpacingExtra="@dimen/spacing_xsmall"
Android:padding="@dimen/spacing_normal"
Android:text="@string/lorem"
Android:textSize="@dimen/textsize_medium"
/>
</Android.support.v4.widget.NestedScrollView>
<Android.support.v7.widget.Toolbar
Android:id="@+id/main.toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="@color/primary"
app:layout_anchor="@id/main.collapsing"
app:theme="@style/ThemeOverlay.AppCompat.Dark"
app:title=""
>
<LinearLayout
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:orientation="horizontal"
>
<Space
Android:layout_width="@dimen/image_final_width"
Android:layout_height="@dimen/image_final_width"
/>
<TextView
Android:id="@+id/main.textview.title"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_marginLeft="8dp"
Android:gravity="center_vertical"
Android:text="@string/tequila_title"
Android:textColor="@Android:color/white"
Android:textSize="@dimen/textsize_large"
/>
</LinearLayout>
</Android.support.v7.widget.Toolbar>
<de.hdodenhof.circleimageview.CircleImageView
Android:layout_width="@dimen/image_width"
Android:layout_height="@dimen/image_width"
Android:layout_gravity="top|center_horizontal"
Android:layout_marginTop="@dimen/spacing_normal"
Android:src="@drawable/ninja"
app:border_color="@Android:color/white"
app:border_width="@dimen/border_width"
app:finalHeight="@dimen/image_final_width"
app:finalXPosition="@dimen/spacing_small"
app:finalYPosition="@dimen/spacing_small"
app:finalToolbarHeight="?attr/actionBarSize"
app:layout_behavior="saulmm.myapplication.AvatarImageBehavior"
/>
</Android.support.design.widget.CoordinatorLayout>
Et dans la classe AvatarImageBehaviour que j'ai optimisée pour déplacer uniquement l'avatar de la position d'origine vers la position configurée dans les attributs. Donc, si vous souhaitez que l'image se déplace d'un autre emplacement, déplacez-la simplement dans la mise en page. Lorsque vous le faites, assurez-vous que AppBarLayout en est toujours un frère ou qu'il ne sera pas trouvé dans le code.
package saulmm.myapplication;
import Android.content.Context;
import Android.content.res.TypedArray;
import Android.support.design.widget.AppBarLayout;
import Android.support.design.widget.CoordinatorLayout;
import Android.util.AttributeSet;
import Android.view.View;
import de.hdodenhof.circleimageview.CircleImageView;
public class AvatarImageBehavior extends CoordinatorLayout.Behavior<CircleImageView> {
// calculated from given layout
private int startXPositionImage;
private int startYPositionImage;
private int startHeight;
private int startToolbarHeight;
private boolean initialised = false;
private float amountOfToolbarToMove;
private float amountOfImageToReduce;
private float amountToMoveXPosition;
private float amountToMoveYPosition;
// user configured params
private float finalToolbarHeight, finalXPosition, finalYPosition, finalHeight;
public AvatarImageBehavior(
final Context context,
final AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AvatarImageBehavior);
finalXPosition = a.getDimension(R.styleable.AvatarImageBehavior_finalXPosition, 0);
finalYPosition = a.getDimension(R.styleable.AvatarImageBehavior_finalYPosition, 0);
finalHeight = a.getDimension(R.styleable.AvatarImageBehavior_finalHeight, 0);
finalToolbarHeight = a.getDimension(R.styleable.AvatarImageBehavior_finalToolbarHeight, 0);
a.recycle();
}
}
@Override
public boolean layoutDependsOn(
final CoordinatorLayout parent,
final CircleImageView child,
final View dependency) {
return dependency instanceof AppBarLayout; // change if you want another sibling to depend on
}
@Override
public boolean onDependentViewChanged(
final CoordinatorLayout parent,
final CircleImageView child,
final View dependency) {
// make child (avatar) change in relation to dependency (toolbar) in both size and position, init with properties from layout
initProperties(child, dependency);
// calculate progress of movement of dependency
float currentToolbarHeight = startToolbarHeight + dependency.getY(); // current expanded height of toolbar
// don't go below configured min height for calculations (it does go passed the toolbar)
currentToolbarHeight = currentToolbarHeight < finalToolbarHeight ? finalToolbarHeight : currentToolbarHeight;
final float amountAlreadyMoved = startToolbarHeight - currentToolbarHeight;
final float progress = 100 * amountAlreadyMoved / amountOfToolbarToMove; // how much % of expand we reached
// update image size
final float heightToSubtract = progress * amountOfImageToReduce / 100;
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
lp.width = (int) (startHeight - heightToSubtract);
lp.height = (int) (startHeight - heightToSubtract);
child.setLayoutParams(lp);
// update image position
final float distanceXToSubtract = progress * amountToMoveXPosition / 100;
final float distanceYToSubtract = progress * amountToMoveYPosition / 100;
float newXPosition = startXPositionImage - distanceXToSubtract;
//newXPosition = newXPosition < endXPosition ? endXPosition : newXPosition; // don't go passed end position
child.setX(newXPosition);
child.setY(startYPositionImage - distanceYToSubtract);
return true;
}
private void initProperties(
final CircleImageView child,
final View dependency) {
if (!initialised) {
// form initial layout
startHeight = child.getHeight();
startXPositionImage = (int) child.getX();
startYPositionImage = (int) child.getY();
startToolbarHeight = dependency.getHeight();
// some calculated fields
amountOfToolbarToMove = startToolbarHeight - finalToolbarHeight;
amountOfImageToReduce = startHeight - finalHeight;
amountToMoveXPosition = startXPositionImage - finalXPosition;
amountToMoveYPosition = startYPositionImage - finalYPosition;
initialised = true;
}
}
}
Sources
L'exemple le plus courant est celui avec le chien répertorié à https://github.com/saulmm/CoordinatorBehaviorExample . C'est un bon exemple mais a en effet la barre d'outils au milieu de la vue développée avec une image de fond qui se déplace également. Tout cela a été supprimé dans mon exemple.
Une autre explication se trouve à http://www.devexchanges.info/2016/03/Android-tip-custom-coordinatorlayout.html mais puisque cette image de fond de nuage/mer référencée y est également trouvée dans le exemple de chien l'un est clairement construit au-dessus de l'autre.
J'ai également trouvé cette SO question avec une prime accordée mais je n'ai pas vraiment pu trouver quelle était la solution finale Ajouter une icône avec un titre dans CollapsingToolbarLayout
Et enfin, cela devrait être une bibliothèque de travail qui fait le travail. Je l'ai vérifié mais l'image initiale n'était pas centrée et j'ai plutôt travaillé sur l'exemple de chien que j'avais regardé auparavant. Voir https://github.com/datalink747/CollapsingAvatarToolbar
Plus à lire
http://saulmm.github.io/mastering-coordinatorhttp://www.androidauthority.com/using-coordinatorlayout-Android-apps-703720/https://developer.Android.com/reference/Android/support/design/widget/CoordinatorLayout.htmlhttps://guides.codepath.com/Android/handling-scrolls-with-coordinatorlayout