am bb829e3d: Merge "Add APIs to set AppBarLayout to be expanded or not" into lmp-mr1-ub-dev
* commit 'bb829e3d51be7da7e4d02c1abc58c5f9132197c2':
Add APIs to set AppBarLayout to be expanded or not
diff --git a/design/api/current.txt b/design/api/current.txt
index 7ecf0f8..6b5058f 100644
--- a/design/api/current.txt
+++ b/design/api/current.txt
@@ -7,6 +7,8 @@
method public float getTargetElevation();
method public final int getTotalScrollRange();
method public void removeOnOffsetChangedListener(android.support.design.widget.AppBarLayout.OnOffsetChangedListener);
+ method public void setExpanded(boolean);
+ method public void setExpanded(boolean, boolean);
method public void setTargetElevation(float);
}
diff --git a/design/res/values/attrs.xml b/design/res/values/attrs.xml
index a23b699..2dfeb41 100644
--- a/design/res/values/attrs.xml
+++ b/design/res/values/attrs.xml
@@ -172,6 +172,9 @@
<declare-styleable name="AppBarLayout">
<attr name="elevation" />
<attr name="android:background" />
+ <!-- The initial expanded state for the AppBarLayout. This only takes effect when this
+ view is a direct child of a CoordinatorLayout. -->
+ <attr name="expanded" format="boolean" />
</declare-styleable>
<declare-styleable name="AppBarLayout_LayoutParams">
diff --git a/design/src/android/support/design/widget/AppBarLayout.java b/design/src/android/support/design/widget/AppBarLayout.java
index 949ce5f..9808e5e 100644
--- a/design/src/android/support/design/widget/AppBarLayout.java
+++ b/design/src/android/support/design/widget/AppBarLayout.java
@@ -95,6 +95,11 @@
@CoordinatorLayout.DefaultBehavior(AppBarLayout.Behavior.class)
public class AppBarLayout extends LinearLayout {
+ private static final int PENDING_ACTION_NONE = 0x0;
+ private static final int PENDING_ACTION_EXPANDED = 0x1;
+ private static final int PENDING_ACTION_COLLAPSED = 0x2;
+ private static final int PENDING_ACTION_ANIMATE_ENABLED = 0x4;
+
/**
* Interface definition for a callback to be invoked when an {@link AppBarLayout}'s vertical
* offset changes.
@@ -121,6 +126,8 @@
private float mTargetElevation;
+ private int mPendingAction = PENDING_ACTION_NONE;
+
private WindowInsetsCompat mLastInsets;
private final List<WeakReference<OnOffsetChangedListener>> mListeners;
@@ -137,6 +144,9 @@
0, R.style.Widget_Design_AppBarLayout);
mTargetElevation = a.getDimensionPixelSize(R.styleable.AppBarLayout_elevation, 0);
setBackgroundDrawable(a.getDrawable(R.styleable.AppBarLayout_android_background));
+ if (a.hasValue(R.styleable.AppBarLayout_expanded)) {
+ setExpanded(a.getBoolean(R.styleable.AppBarLayout_expanded, false));
+ }
a.recycle();
// Use the bounds view outline provider so that we cast a shadow, even without a background
@@ -223,6 +233,40 @@
super.setOrientation(orientation);
}
+ /**
+ * Sets whether this {@link AppBarLayout} is expanded or not, animating if it has already
+ * been laid out.
+ *
+ * <p>As with {@link AppBarLayout}'s scrolling, this method relies on this layout being a
+ * direct child of a {@link CoordinatorLayout}.</p>
+ *
+ * @param expanded true if the layout should be fully expanded, false if it should
+ * be fully collapsed
+ *
+ * @attr ref android.support.design.R.styleable#AppBarLayout_expanded
+ */
+ public void setExpanded(boolean expanded) {
+ setExpanded(expanded, ViewCompat.isLaidOut(this));
+ }
+
+ /**
+ * Sets whether this {@link AppBarLayout} is expanded or not.
+ *
+ * <p>As with {@link AppBarLayout}'s scrolling, this method relies on this layout being a
+ * direct child of a {@link CoordinatorLayout}.</p>
+ *
+ * @param expanded true if the layout should be fully expanded, false if it should
+ * be fully collapsed
+ * @param animate Whether to animate to the new state
+ *
+ * @attr ref android.support.design.R.styleable#AppBarLayout_expanded
+ */
+ public void setExpanded(boolean expanded, boolean animate) {
+ mPendingAction = (expanded ? PENDING_ACTION_EXPANDED : PENDING_ACTION_COLLAPSED)
+ | (animate ? PENDING_ACTION_ANIMATE_ENABLED : 0);
+ requestLayout();
+ }
+
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
@@ -419,6 +463,14 @@
return mTargetElevation;
}
+ int getPendingAction() {
+ return mPendingAction;
+ }
+
+ void resetPendingAction() {
+ mPendingAction = PENDING_ACTION_NONE;
+ }
+
private void setWindowInsets(WindowInsetsCompat insets) {
// Invalidate the total scroll range...
mTotalScrollRange = INVALID_SCROLL_RANGE;
@@ -771,12 +823,31 @@
}
@Override
- public boolean onLayoutChild(CoordinatorLayout parent, AppBarLayout appBarLayout,
+ public boolean onLayoutChild(CoordinatorLayout parent, AppBarLayout abl,
int layoutDirection) {
- boolean handled = super.onLayoutChild(parent, appBarLayout, layoutDirection);
+ boolean handled = super.onLayoutChild(parent, abl, layoutDirection);
- if (mOffsetToChildIndexOnLayout >= 0) {
- View child = appBarLayout.getChildAt(mOffsetToChildIndexOnLayout);
+ final int pendingAction = abl.getPendingAction();
+ if (pendingAction != PENDING_ACTION_NONE) {
+ final boolean animate = (pendingAction & PENDING_ACTION_ANIMATE_ENABLED) != 0;
+ if ((pendingAction & PENDING_ACTION_COLLAPSED) != 0) {
+ final int offset = -abl.getUpNestedPreScrollRange();
+ if (animate) {
+ animateOffsetTo(parent, abl, offset);
+ } else {
+ setAppBarTopBottomOffset(parent, abl, offset);
+ }
+ } else if ((pendingAction & PENDING_ACTION_EXPANDED) != 0) {
+ if (animate) {
+ animateOffsetTo(parent, abl, 0);
+ } else {
+ setAppBarTopBottomOffset(parent, abl, 0);
+ }
+ }
+ // Finally reset the pending state
+ abl.resetPendingAction();
+ } else if (mOffsetToChildIndexOnLayout >= 0) {
+ View child = abl.getChildAt(mOffsetToChildIndexOnLayout);
int offset = -child.getBottom();
if (mOffsetToChildIndexOnLayoutIsMinHeight) {
offset += ViewCompat.getMinimumHeight(child);
@@ -788,7 +859,7 @@
}
// Make sure we update the elevation
- dispatchOffsetUpdates(appBarLayout);
+ dispatchOffsetUpdates(abl);
return handled;
}
diff --git a/design/src/android/support/design/widget/CollapsingTextHelper.java b/design/src/android/support/design/widget/CollapsingTextHelper.java
index 8b3bd84..46b3b82 100644
--- a/design/src/android/support/design/widget/CollapsingTextHelper.java
+++ b/design/src/android/support/design/widget/CollapsingTextHelper.java
@@ -85,6 +85,8 @@
private float mScale;
private float mCurrentTextSize;
+ private boolean mBoundsChanged;
+
private final TextPaint mTextPaint;
private Interpolator mPositionInterpolator;
@@ -140,11 +142,17 @@
}
void setExpandedBounds(int left, int top, int right, int bottom) {
- mExpandedBounds.set(left, top, right, bottom);
+ if (!rectEquals(mExpandedBounds, left, top, right, bottom)) {
+ mExpandedBounds.set(left, top, right, bottom);
+ mBoundsChanged = true;
+ }
}
void setCollapsedBounds(int left, int top, int right, int bottom) {
- mCollapsedBounds.set(left, top, right, bottom);
+ if (!rectEquals(mCollapsedBounds, left, top, right, bottom)) {
+ mCollapsedBounds.set(left, top, right, bottom);
+ mBoundsChanged = true;
+ }
}
void setExpandedTextGravity(int gravity) {
@@ -424,8 +432,9 @@
}
if (availableWidth > 0) {
- updateDrawText = mCurrentTextSize != newTextSize;
+ updateDrawText = (mCurrentTextSize != newTextSize) || mBoundsChanged;
mCurrentTextSize = newTextSize;
+ mBoundsChanged = false;
}
if (mTextToDraw == null || updateDrawText) {
@@ -552,4 +561,8 @@
}
return AnimationUtils.lerp(startValue, endValue, fraction);
}
+
+ private static boolean rectEquals(Rect r, int left, int top, int right, int bottom) {
+ return !(r.left != left || r.top != top || r.right != right || r.bottom != bottom);
+ }
}