J'essaie d'obtenir un comportement similaire à celui de Telegram, sur la page des paramètres, c'est-à-dire qu'il y a un CircleImage qui, lorsque le défilement monte à gauche du titre de la barre supérieure, et celui qui défile vers le bas, se déplacent au milieu de la barre d'outils développée .
Je basais mon travail sur cet exemple:
https://github.com/saulmm/CoordinatorBehaviorExample
Mais dans ce cas, le codeur d'origine recrée deux fois la barre supérieure. Je ne veux pas faire cela, le comportement par défaut de la barre supérieure est ce dont j'ai besoin et je veux aussi profiter du menu hamburger et du menu options qui sortent de la boîte.
Voici ma hiérarchie de vues:
DrawerLayout
|
|---CoordinatorLayout
|--AppBarLayout
| |-CollapsingToolbarLayout
| |-ImageView (backdrop image)
| |-Toolbar
|--NestedScrollView
|--ImageView (circleimage avatar)
Comme vous pouvez le constater, je ne peux pas faire de la disposition de la barre d’outils un frère de CircleImage, je ne peux donc pas les lier ensemble avec la méthode layoutDependsOn
. J'ai essayé de me lier à AppBarLayout en me basant sur le code du dépôt github, mais je ne peux vraiment pas comprendre ce qui se passe dans le code d'origine.
Mon comportement a été mis en œuvre de la même manière que celui de Saul. La plus grande différence est que j'aime mettre une vue non visible comme une Space
où je voulais que l'image du cercle se termine, puis utiliser les limites de cette vue pour déterminer comment déplacer et redimensionner l'image du cercle.
public class CollapsingImageBehavior extends CoordinatorLayout.Behavior<View> {
private final static int X = 0;
private final static int Y = 1;
private final static int WIDTH = 2;
private final static int HEIGHT = 3;
private int mTargetId;
private int[] mView;
private int[] mTarget;
public CollapsingImageBehavior() {
}
public CollapsingImageBehavior(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CollapsingImageBehavior);
mTargetId = a.getResourceId(R.styleable.CollapsingImageBehavior_collapsedTarget, 0);
a.recycle();
}
if (mTargetId == 0) {
throw new IllegalStateException("collapsedTarget attribute not specified on view for behavior");
}
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof AppBarLayout;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
setup(parent, child);
AppBarLayout appBarLayout = (AppBarLayout) dependency;
int range = appBarLayout.getTotalScrollRange();
float factor = -appBarLayout.getY() / range;
int left = mView[X] + (int) (factor * (mTarget[X] - mView[X]));
int top = mView[Y] + (int) (factor * (mTarget[Y] - mView[Y]));
int width = mView[WIDTH] + (int) (factor * (mTarget[WIDTH] - mView[WIDTH]));
int height = mView[HEIGHT] + (int) (factor * (mTarget[HEIGHT] - mView[HEIGHT]));
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
lp.width = width;
lp.height = height;
child.setLayoutParams(lp);
child.setX(left);
child.setY(top);
return true;
}
private void setup(CoordinatorLayout parent, View child) {
if (mView != null) return;
mView = new int[4];
mTarget = new int[4];
mView[X] = (int) child.getX();
mView[Y] = (int) child.getY();
mView[WIDTH] = child.getWidth();
mView[HEIGHT] = child.getHeight();
View target = parent.findViewById(mTargetId);
if (target == null) {
throw new IllegalStateException("target view not found");
}
mTarget[WIDTH] += target.getWidth();
mTarget[HEIGHT] += target.getHeight();
View view = target;
while (view != parent) {
mTarget[X] += (int) view.getX();
mTarget[Y] += (int) view.getY();
view = (View) view.getParent();
}
}
}
Et voici la mise en page. Une chose importante que j'ai découverte est que la vue de l'image circulaire doit avoir un ensemble d'altitude de sorte qu'elle se trouve au sommet de la barre d'outils en mode réduit, sinon elle serait derrière la barre d'outils et non affichée.
<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/coordinator_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
tools:context="com.krislarson.customcoordinatorlayoutbehavior.ScrollingActivity">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/app_bar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:fitsSystemWindows="true"
Android:theme="@style/AppTheme.AppBarOverlay">
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/toolbar_layout"
Android:layout_width="match_parent"
Android:layout_height="280dp"
Android:minHeight="108dp"
Android:fitsSystemWindows="true"
app:title="Abby"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="center_horizontal"
app:expandedTitleMarginTop="140dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
Android:id="@+id/background"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:src="@drawable/sunset"
app:layout_collapseMode="parallax"
Android:scaleType="centerCrop"/>
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay">
<Space
Android:id="@+id/circle_collapsed_target"
Android:layout_width="40dp"
Android:layout_height="40dp"/>
</Android.support.v7.widget.Toolbar>
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<include layout="@layout/content_scrolling"/>
<de.hdodenhof.circleimageview.CircleImageView
Android:id="@+id/circle_image_view"
Android:layout_width="120dp"
Android:layout_height="120dp"
Android:src="@drawable/abby"
Android:layout_marginTop="220dp"
Android:layout_gravity="top|center_horizontal"
Android:elevation="8dp"
app:border_color="@Android:color/black"
app:border_width="2dp"
app:collapsedTarget="@id/circle_collapsed_target"
app:layout_behavior="com.krislarson.customcoordinatorlayoutbehavior.CollapsingImageBehavior"/>
</Android.support.design.widget.CoordinatorLayout>
Vous pouvez voir le projet de démonstration dans son intégralité à https://github.com/klarson2/CustomCoordinatorLayoutBehavior
Une possibilité serait de créer une vue personnalisée pour votre ToolBar
et de masquer le point rouge dans la ToolBar
si elle est développée et d'afficher une ImageView
avec le point rouge à la place (masqué lorsque la barre d'outils est réduite).
Vous pouvez voir comment ajouter une vue personnalisée à une ToolBar
à cette réponse: https://stackoverflow.com/a/27859966/5052976
Cela fait, créez simplement une ImageView
visible lorsque la ToolBar
est développée.
final CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsingToolbarLayout);
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
//show toolbar dot and hide imageview dot
isShow = true;
} else if(isShow) {
//hide toolbar dot and show imageview dot
isShow = false;
}
}
});
Malheureusement, je ne peux pas tester cela maintenant mais je pense que cela devrait fonctionner ;-)