blob: 3cd5c6efdea1b4b29c565e02f57cce258e1eadf2 [file] [log] [blame]
Jorim Jaggibe565df2014-04-28 17:51:23 +02001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.systemui.statusbar;
18
Selim Cinek332c23f2018-03-16 17:37:50 -070019import android.animation.AnimatorListenerAdapter;
Jorim Jaggibe565df2014-04-28 17:51:23 +020020import android.content.Context;
Selim Cinek471e31a2015-12-11 13:39:48 -080021import android.graphics.Paint;
Selim Cineke32010a2014-08-20 23:50:41 +020022import android.graphics.Rect;
Jorim Jaggibe565df2014-04-28 17:51:23 +020023import android.util.AttributeSet;
24import android.view.View;
Selim Cinekc9c00ae2014-05-20 03:33:40 +020025import android.view.ViewGroup;
Selim Cinek24d7cfa2014-05-20 13:50:57 +020026import android.widget.FrameLayout;
Selim Cinekd84a5932015-12-15 11:45:36 -080027
Selim Cinekbbcebde2016-11-09 18:28:20 -080028import com.android.systemui.statusbar.stack.ExpandableViewState;
Anthony Chen04d1ea72017-04-21 14:30:11 -070029import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Selim Cinekbbcebde2016-11-09 18:28:20 -080030import com.android.systemui.statusbar.stack.StackScrollState;
Selim Cinek24d7cfa2014-05-20 13:50:57 +020031
32import java.util.ArrayList;
Jorim Jaggibe565df2014-04-28 17:51:23 +020033
34/**
35 * An abstract view for expandable views.
36 */
Selim Cinek24d7cfa2014-05-20 13:50:57 +020037public abstract class ExpandableView extends FrameLayout {
38
Selim Cinekeccf4942018-05-30 09:55:36 -070039 public static final float NO_ROUNDNESS = -1;
Selim Cinekb5605e52015-02-20 18:21:41 +010040 protected OnHeightChangedListener mOnHeightChangedListener;
Chris Wren310df312014-10-31 14:29:46 -040041 private int mActualHeight;
Jorim Jaggibe565df2014-04-28 17:51:23 +020042 protected int mClipTopAmount;
Selim Cinekb3dadcc2016-11-21 17:21:13 -080043 protected int mClipBottomAmount;
Selim Cinekffd3dc62018-11-30 18:06:57 -080044 protected int mMinimumHeightForClipping = 0;
45 protected float mExtraWidthForClipping = 0;
Jorim Jaggi4e857f42014-11-17 19:14:04 +010046 private boolean mDark;
Selim Cinek24d7cfa2014-05-20 13:50:57 +020047 private ArrayList<View> mMatchParentViews = new ArrayList<View>();
Selim Cineka272dfe2015-02-20 18:12:28 +010048 private static Rect mClipRect = new Rect();
Selim Cinek2cd45df2015-06-09 18:00:07 -070049 private boolean mWillBeGone;
Selim Cinek9c17b772015-07-07 20:37:09 -070050 private int mMinClipTopAmount = 0;
Selim Cinek4ffd6362015-12-29 15:12:23 +010051 private boolean mClipToActualHeight = true;
Adrian Roos14503e22016-03-09 14:01:24 -080052 private boolean mChangingPosition = false;
Selim Cinekd1395642016-04-28 12:22:42 -070053 private ViewGroup mTransientContainer;
Selim Cinekeccb5de2016-10-28 15:04:05 -070054 private boolean mInShelf;
55 private boolean mTransformingInShelf;
Jorim Jaggibe565df2014-04-28 17:51:23 +020056
57 public ExpandableView(Context context, AttributeSet attrs) {
58 super(context, attrs);
Selim Cinek24d7cfa2014-05-20 13:50:57 +020059 }
60
61 @Override
62 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Selim Cinek471e31a2015-12-11 13:39:48 -080063 final int givenSize = MeasureSpec.getSize(heightMeasureSpec);
felkachang79ca96d2018-04-27 16:55:40 +080064 final int viewHorizontalPadding = getPaddingStart() + getPaddingEnd();
Selim Cinekd84a5932015-12-15 11:45:36 -080065 int ownMaxHeight = Integer.MAX_VALUE;
Selim Cinek6f145cf2015-05-18 15:16:08 -070066 int heightMode = MeasureSpec.getMode(heightMeasureSpec);
Selim Cineka69f2a62015-12-11 17:28:12 -080067 if (heightMode != MeasureSpec.UNSPECIFIED && givenSize != 0) {
Selim Cinek471e31a2015-12-11 13:39:48 -080068 ownMaxHeight = Math.min(givenSize, ownMaxHeight);
Selim Cinek6f145cf2015-05-18 15:16:08 -070069 }
Selim Cinek24d7cfa2014-05-20 13:50:57 +020070 int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
71 int maxChildHeight = 0;
72 int childCount = getChildCount();
73 for (int i = 0; i < childCount; i++) {
74 View child = getChildAt(i);
Selim Cinek263398f2015-10-21 17:40:23 -070075 if (child.getVisibility() == GONE) {
Selim Cinekb5605e52015-02-20 18:21:41 +010076 continue;
77 }
Selim Cinek24d7cfa2014-05-20 13:50:57 +020078 int childHeightSpec = newHeightSpec;
79 ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
80 if (layoutParams.height != ViewGroup.LayoutParams.MATCH_PARENT) {
81 if (layoutParams.height >= 0) {
82 // An actual height is set
Selim Cineka69f2a62015-12-11 17:28:12 -080083 childHeightSpec = layoutParams.height > ownMaxHeight
Selim Cinek24d7cfa2014-05-20 13:50:57 +020084 ? MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.EXACTLY)
85 : MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
86 }
felkachang79ca96d2018-04-27 16:55:40 +080087 child.measure(getChildMeasureSpec(
88 widthMeasureSpec, viewHorizontalPadding, layoutParams.width),
Jorim Jaggib741f052014-06-03 19:57:26 +020089 childHeightSpec);
Selim Cinek24d7cfa2014-05-20 13:50:57 +020090 int childHeight = child.getMeasuredHeight();
91 maxChildHeight = Math.max(maxChildHeight, childHeight);
92 } else {
93 mMatchParentViews.add(child);
94 }
95 }
Selim Cineka69f2a62015-12-11 17:28:12 -080096 int ownHeight = heightMode == MeasureSpec.EXACTLY
97 ? givenSize : Math.min(ownMaxHeight, maxChildHeight);
Selim Cinek24d7cfa2014-05-20 13:50:57 +020098 newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY);
99 for (View child : mMatchParentViews) {
Jorim Jaggib741f052014-06-03 19:57:26 +0200100 child.measure(getChildMeasureSpec(
felkachang79ca96d2018-04-27 16:55:40 +0800101 widthMeasureSpec, viewHorizontalPadding, child.getLayoutParams().width),
Jorim Jaggib741f052014-06-03 19:57:26 +0200102 newHeightSpec);
Selim Cinek24d7cfa2014-05-20 13:50:57 +0200103 }
104 mMatchParentViews.clear();
105 int width = MeasureSpec.getSize(widthMeasureSpec);
106 setMeasuredDimension(width, ownHeight);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200107 }
108
109 @Override
Jorim Jaggibe565df2014-04-28 17:51:23 +0200110 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Selim Cinek24d7cfa2014-05-20 13:50:57 +0200111 super.onLayout(changed, left, top, right, bottom);
Selim Cinekba67acf2015-04-10 17:00:42 -0700112 updateClipping();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200113 }
114
Jorim Jaggi00ebdfe2014-05-02 17:29:56 +0200115 @Override
Selim Cineka69f2a62015-12-11 17:28:12 -0800116 public boolean pointInView(float localX, float localY, float slop) {
117 float top = mClipTopAmount;
118 float bottom = mActualHeight;
119 return localX >= -slop && localY >= top - slop && localX < ((mRight - mLeft) + slop) &&
120 localY < (bottom + slop);
Jorim Jaggi00ebdfe2014-05-02 17:29:56 +0200121 }
122
Jorim Jaggibe565df2014-04-28 17:51:23 +0200123 /**
124 * Sets the actual height of this notification. This is different than the laid out
125 * {@link View#getHeight()}, as we want to avoid layouting during scrolling and expanding.
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200126 *
127 * @param actualHeight The height of this notification.
128 * @param notifyListeners Whether the listener should be informed about the change.
Jorim Jaggibe565df2014-04-28 17:51:23 +0200129 */
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200130 public void setActualHeight(int actualHeight, boolean notifyListeners) {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200131 mActualHeight = actualHeight;
Selim Cineka272dfe2015-02-20 18:12:28 +0100132 updateClipping();
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200133 if (notifyListeners) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100134 notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200135 }
136 }
137
Selim Cinekb0ee18f2017-12-21 16:15:53 -0800138 /**
139 * Set the distance to the top roundness, from where we should start clipping a value above
140 * or equal to 0 is the effective distance, and if a value below 0 is received, there should
141 * be no clipping.
142 */
143 public void setDistanceToTopRoundness(float distanceToTopRoundness) {
144 }
145
Selim Cinekeef84282015-10-30 16:28:00 -0700146 public void setActualHeight(int actualHeight) {
147 setActualHeight(actualHeight, true /* notifyListeners */);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200148 }
149
150 /**
151 * See {@link #setActualHeight}.
152 *
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200153 * @return The current actual height of this notification.
Jorim Jaggibe565df2014-04-28 17:51:23 +0200154 */
155 public int getActualHeight() {
156 return mActualHeight;
157 }
158
Selim Cinek2627d722018-01-19 12:16:49 -0800159 public boolean isExpandAnimationRunning() {
160 return false;
161 }
162
Jorim Jaggibe565df2014-04-28 17:51:23 +0200163 /**
164 * @return The maximum height of this notification.
165 */
Selim Cinekb5605e52015-02-20 18:21:41 +0100166 public int getMaxContentHeight() {
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200167 return getHeight();
168 }
169
170 /**
Selim Cinekeb3fc3d2017-09-15 13:37:14 -0700171 * @return The minimum content height of this notification. This also respects the temporary
172 * states of the view.
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200173 */
174 public int getMinHeight() {
Selim Cinekeb3fc3d2017-09-15 13:37:14 -0700175 return getMinHeight(false /* ignoreTemporaryStates */);
176 }
177
178 /**
179 * Get the minimum height of this view.
180 *
181 * @param ignoreTemporaryStates should temporary states be ignored like the guts or heads-up.
182 *
183 * @return The minimum height that this view needs.
184 */
185 public int getMinHeight(boolean ignoreTemporaryStates) {
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200186 return getHeight();
187 }
Jorim Jaggibe565df2014-04-28 17:51:23 +0200188
189 /**
Selim Cinek567e8452016-03-24 10:54:56 -0700190 * @return The collapsed height of this view. Note that this might be different
191 * than {@link #getMinHeight()} because some elements like groups may have different sizes when
192 * they are system expanded.
Selim Cinek816c8e42015-11-19 12:00:45 -0800193 */
Selim Cinek567e8452016-03-24 10:54:56 -0700194 public int getCollapsedHeight() {
Selim Cinek816c8e42015-11-19 12:00:45 -0800195 return getHeight();
196 }
197
198 /**
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200199 * Sets the notification as dimmed. The default implementation does nothing.
200 *
201 * @param dimmed Whether the notification should be dimmed.
202 * @param fade Whether an animation should be played to change the state.
203 */
204 public void setDimmed(boolean dimmed, boolean fade) {
205 }
206
207 /**
John Spurlockbf370992014-06-17 13:58:31 -0400208 * Sets the notification as dark. The default implementation does nothing.
209 *
210 * @param dark Whether the notification should be dark.
211 * @param fade Whether an animation should be played to change the state.
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100212 * @param delay If fading, the delay of the animation.
John Spurlockbf370992014-06-17 13:58:31 -0400213 */
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100214 public void setDark(boolean dark, boolean fade, long delay) {
215 mDark = dark;
216 }
217
218 public boolean isDark() {
219 return mDark;
John Spurlockbf370992014-06-17 13:58:31 -0400220 }
221
Selim Cinekd9b7dd42017-11-10 17:53:47 -0800222 public boolean isRemoved() {
223 return false;
224 }
225
John Spurlockbf370992014-06-17 13:58:31 -0400226 /**
Jorim Jaggiae441282014-08-01 02:45:18 +0200227 * See {@link #setHideSensitive}. This is a variant which notifies this view in advance about
228 * the upcoming state of hiding sensitive notifications. It gets called at the very beginning
229 * of a stack scroller update such that the updated intrinsic height (which is dependent on
230 * whether private or public layout is showing) gets taken into account into all layout
231 * calculations.
232 */
233 public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
234 }
235
236 /**
237 * Sets whether the notification should hide its private contents if it is sensitive.
238 */
239 public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
240 long duration) {
241 }
242
243 /**
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200244 * @return The desired notification height.
245 */
246 public int getIntrinsicHeight() {
Selim Cineka5eaa602014-05-12 21:27:47 +0200247 return getHeight();
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200248 }
249
250 /**
Jorim Jaggibe565df2014-04-28 17:51:23 +0200251 * Sets the amount this view should be clipped from the top. This is used when an expanded
252 * notification is scrolling in the top or bottom stack.
253 *
254 * @param clipTopAmount The amount of pixels this view should be clipped from top.
255 */
256 public void setClipTopAmount(int clipTopAmount) {
257 mClipTopAmount = clipTopAmount;
Mady Mellorc128f222016-04-26 11:42:46 -0700258 updateClipping();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200259 }
260
Selim Cineka686b2c2016-10-26 13:58:27 -0700261 /**
262 * Set the amount the the notification is clipped on the bottom in addition to the regular
263 * clipping. This is mainly used to clip something in a non-animated way without changing the
264 * actual height of the notification and is purely visual.
265 *
266 * @param clipBottomAmount the amount to clip.
267 */
268 public void setClipBottomAmount(int clipBottomAmount) {
269 mClipBottomAmount = clipBottomAmount;
270 updateClipping();
271 }
272
Selim Cinekeb973562014-05-02 17:07:49 +0200273 public int getClipTopAmount() {
274 return mClipTopAmount;
275 }
276
Selim Cinekb3dadcc2016-11-21 17:21:13 -0800277 public int getClipBottomAmount() {
Selim Cineka686b2c2016-10-26 13:58:27 -0700278 return mClipBottomAmount;
279 }
280
Jorim Jaggibe565df2014-04-28 17:51:23 +0200281 public void setOnHeightChangedListener(OnHeightChangedListener listener) {
282 mOnHeightChangedListener = listener;
283 }
284
285 /**
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200286 * @return Whether we can expand this views content.
Jorim Jaggibe565df2014-04-28 17:51:23 +0200287 */
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200288 public boolean isContentExpandable() {
289 return false;
Jorim Jaggibe565df2014-04-28 17:51:23 +0200290 }
291
Selim Cinekb5605e52015-02-20 18:21:41 +0100292 public void notifyHeightChanged(boolean needsAnimation) {
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200293 if (mOnHeightChangedListener != null) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100294 mOnHeightChangedListener.onHeightChanged(this, needsAnimation);
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200295 }
296 }
297
Selim Cinekc27437b2014-05-14 10:23:33 +0200298 public boolean isTransparent() {
299 return false;
300 }
301
Jorim Jaggibe565df2014-04-28 17:51:23 +0200302 /**
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200303 * Perform a remove animation on this view.
Jorim Jaggi60d07c52014-07-31 15:38:21 +0200304 * @param duration The duration of the remove animation.
Selim Cinek332c23f2018-03-16 17:37:50 -0700305 * @param delay The delay of the animation
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200306 * @param translationDirection The direction value from [-1 ... 1] indicating in which the
Selim Cinek332c23f2018-03-16 17:37:50 -0700307 * animation should be performed. A value of -1 means that The
308 * remove animation should be performed upwards,
309 * such that the child appears to be going away to the top. 1
310 * Should mean the opposite.
311 * @param isHeadsUpAnimation Is this a headsUp animation.
312 * @param endLocation The location where the horizonal heads up disappear animation should end.
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200313 * @param onFinishedRunnable A runnable which should be run when the animation is finished.
Selim Cinek332c23f2018-03-16 17:37:50 -0700314 * @param animationListener An animation listener to add to the animation.
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200315 */
Selim Cinek332c23f2018-03-16 17:37:50 -0700316 public abstract void performRemoveAnimation(long duration,
317 long delay, float translationDirection, boolean isHeadsUpAnimation, float endLocation,
318 Runnable onFinishedRunnable,
319 AnimatorListenerAdapter animationListener);
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200320
Selim Cinek332c23f2018-03-16 17:37:50 -0700321 public abstract void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear);
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200322
Selim Cinek281c2022016-10-13 19:14:43 -0700323 /**
Selim Cinekdb167372016-11-17 15:41:17 -0800324 * Set the notification appearance to be below the speed bump.
Selim Cinek281c2022016-10-13 19:14:43 -0700325 * @param below true if it is below.
326 */
Selim Cinekdb167372016-11-17 15:41:17 -0800327 public void setBelowSpeedBump(boolean below) {
Selim Cinek3d2b94bf2014-07-02 22:12:47 +0200328 }
329
Selim Cinekd127d792016-11-01 19:11:41 -0700330 public int getPinnedHeadsUpHeight() {
331 return getIntrinsicHeight();
332 }
333
334
Mady Mellor34958fa2016-02-23 09:52:17 -0800335 /**
336 * Sets the translation of the view.
337 */
338 public void setTranslation(float translation) {
339 setTranslationX(translation);
340 }
341
342 /**
343 * Gets the translation of the view.
344 */
345 public float getTranslation() {
346 return getTranslationX();
347 }
348
Selim Cinek31094df2014-08-14 19:28:15 +0200349 public void onHeightReset() {
Selim Cineke34c6512014-08-14 11:19:41 +0200350 if (mOnHeightChangedListener != null) {
351 mOnHeightChangedListener.onReset(this);
352 }
Selim Cineka5e211b2014-08-11 17:35:48 +0200353 }
354
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200355 /**
Selim Cineke32010a2014-08-20 23:50:41 +0200356 * This method returns the drawing rect for the view which is different from the regular
357 * drawing rect, since we layout all children in the {@link NotificationStackScrollLayout} at
358 * position 0 and usually the translation is neglected. Since we are manually clipping this
359 * view,we also need to subtract the clipTopAmount from the top. This is needed in order to
360 * ensure that accessibility and focusing work correctly.
361 *
362 * @param outRect The (scrolled) drawing bounds of the view.
363 */
364 @Override
365 public void getDrawingRect(Rect outRect) {
366 super.getDrawingRect(outRect);
367 outRect.left += getTranslationX();
368 outRect.right += getTranslationX();
369 outRect.bottom = (int) (outRect.top + getTranslationY() + getActualHeight());
370 outRect.top += getTranslationY() + getClipTopAmount();
371 }
372
Adrian Rooscd55f432015-06-10 16:42:53 -0700373 @Override
374 public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
375 super.getBoundsOnScreen(outRect, clipToParent);
Adrian Roos98dd7f12016-06-14 15:51:40 -0700376 if (getTop() + getTranslationY() < 0) {
377 // We got clipped to the parent here - make sure we undo that.
378 outRect.top += getTop() + getTranslationY();
379 }
Adrian Roosb44f5482015-06-11 12:19:16 -0700380 outRect.bottom = outRect.top + getActualHeight();
Mady Mellorc128f222016-04-26 11:42:46 -0700381 outRect.top += getClipTopAmount();
Adrian Rooscd55f432015-06-10 16:42:53 -0700382 }
383
Selim Cinek263398f2015-10-21 17:40:23 -0700384 public boolean isSummaryWithChildren() {
Selim Cinekb5605e52015-02-20 18:21:41 +0100385 return false;
386 }
387
388 public boolean areChildrenExpanded() {
389 return false;
390 }
391
Selim Cinek2627d722018-01-19 12:16:49 -0800392 protected void updateClipping() {
393 if (mClipToActualHeight && shouldClipToActualHeight()) {
Mady Mellorc128f222016-04-26 11:42:46 -0700394 int top = getClipTopAmount();
Selim Cinekffd3dc62018-11-30 18:06:57 -0800395 int bottom = Math.max(Math.max(getActualHeight() + getExtraBottomPadding()
396 - mClipBottomAmount, top), mMinimumHeightForClipping);
397 int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
398 mClipRect.set(-halfExtraWidth, top, getWidth() + halfExtraWidth, bottom);
Selim Cinek4ffd6362015-12-29 15:12:23 +0100399 setClipBounds(mClipRect);
400 } else {
401 setClipBounds(null);
Selim Cinekf92a1fd2015-07-31 16:10:32 -0700402 }
Selim Cinek4ffd6362015-12-29 15:12:23 +0100403 }
404
Selim Cinekffd3dc62018-11-30 18:06:57 -0800405 public void setMinimumHeightForClipping(int minimumHeightForClipping) {
406 mMinimumHeightForClipping = minimumHeightForClipping;
407 updateClipping();
408 }
409
410 public void setExtraWidthForClipping(float extraWidthForClipping) {
411 mExtraWidthForClipping = extraWidthForClipping;
412 updateClipping();
413 }
414
Selim Cinek99e9adf2018-03-15 09:17:47 -0700415 public float getHeaderVisibleAmount() {
416 return 1.0f;
417 }
418
Selim Cinek2627d722018-01-19 12:16:49 -0800419 protected boolean shouldClipToActualHeight() {
420 return true;
421 }
422
Selim Cinek4ffd6362015-12-29 15:12:23 +0100423 public void setClipToActualHeight(boolean clipToActualHeight) {
424 mClipToActualHeight = clipToActualHeight;
425 updateClipping();
Selim Cineka272dfe2015-02-20 18:12:28 +0100426 }
427
Selim Cinek2cd45df2015-06-09 18:00:07 -0700428 public boolean willBeGone() {
429 return mWillBeGone;
430 }
431
432 public void setWillBeGone(boolean willBeGone) {
433 mWillBeGone = willBeGone;
434 }
435
Selim Cinek9c17b772015-07-07 20:37:09 -0700436 public int getMinClipTopAmount() {
437 return mMinClipTopAmount;
438 }
439
440 public void setMinClipTopAmount(int minClipTopAmount) {
441 mMinClipTopAmount = minClipTopAmount;
442 }
443
Selim Cinek471e31a2015-12-11 13:39:48 -0800444 @Override
445 public void setLayerType(int layerType, Paint paint) {
446 if (hasOverlappingRendering()) {
447 super.setLayerType(layerType, paint);
448 }
449 }
450
451 @Override
452 public boolean hasOverlappingRendering() {
Selim Cineka69f2a62015-12-11 17:28:12 -0800453 // Otherwise it will be clipped
454 return super.hasOverlappingRendering() && getActualHeight() <= getHeight();
Selim Cinek471e31a2015-12-11 13:39:48 -0800455 }
456
Selim Cinek277a8aa2016-01-22 12:12:37 -0800457 public float getShadowAlpha() {
458 return 0.0f;
459 }
460
461 public void setShadowAlpha(float shadowAlpha) {
462 }
463
Selim Cinek42357e02016-02-24 18:48:01 -0800464 /**
Selim Cineka7ed2c12017-01-23 20:47:24 -0800465 * @return an amount between -1 and 1 of increased padding that this child needs. 1 means it
466 * needs a full increased padding while -1 means it needs no padding at all. For 0.0f the normal
467 * padding is applied.
Selim Cinek42357e02016-02-24 18:48:01 -0800468 */
469 public float getIncreasedPaddingAmount() {
470 return 0.0f;
Selim Cinek61633a82016-01-25 15:54:10 -0800471 }
472
Selim Cinek3776fe02016-02-04 13:32:43 -0800473 public boolean mustStayOnScreen() {
474 return false;
475 }
476
Selim Cinek33223572016-02-19 19:32:22 -0800477 public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd,
478 int outlineTranslation) {
479 }
480
481 public float getOutlineAlpha() {
482 return 0.0f;
483 }
484
485 public int getOutlineTranslation() {
486 return 0;
487 }
488
Adrian Roos14503e22016-03-09 14:01:24 -0800489 public void setChangingPosition(boolean changingPosition) {
490 mChangingPosition = changingPosition;
491 }
492
493 public boolean isChangingPosition() {
494 return mChangingPosition;
495 }
496
Selim Cinekd1395642016-04-28 12:22:42 -0700497 public void setTransientContainer(ViewGroup transientContainer) {
498 mTransientContainer = transientContainer;
499 }
500
501 public ViewGroup getTransientContainer() {
502 return mTransientContainer;
503 }
504
Selim Cineke32010a2014-08-20 23:50:41 +0200505 /**
Mady Mellorb0a82462016-04-30 17:31:02 -0700506 * @return padding used to alter how much of the view is clipped.
507 */
508 public int getExtraBottomPadding() {
509 return 0;
510 }
511
512 /**
513 * @return true if the group's expansion state is changing, false otherwise.
514 */
515 public boolean isGroupExpansionChanging() {
516 return false;
517 }
518
519 public boolean isGroupExpanded() {
520 return false;
521 }
522
Selim Cinek9b9d6e12017-11-30 12:29:47 +0100523 public void setHeadsUpIsVisible() {
524 }
525
Mady Mellorb0a82462016-04-30 17:31:02 -0700526 public boolean isChildInGroup() {
527 return false;
528 }
529
Adrian Roos599be342016-06-13 14:54:39 -0700530 public void setActualHeightAnimating(boolean animating) {}
531
Selim Cinekbbcebde2016-11-09 18:28:20 -0800532 public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
533 return new ExpandableViewState();
534 }
535
Mady Mellorb0a82462016-04-30 17:31:02 -0700536 /**
Selim Cinek281c2022016-10-13 19:14:43 -0700537 * @return whether the current view doesn't add height to the overall content. This means that
538 * if it is added to a list of items, it's content will still have the same height.
539 * An example is the notification shelf, that is always placed on top of another view.
540 */
541 public boolean hasNoContentHeight() {
542 return false;
543 }
544
545 /**
Selim Cinekeccb5de2016-10-28 15:04:05 -0700546 * @param inShelf whether the view is currently fully in the notification shelf.
547 */
548 public void setInShelf(boolean inShelf) {
549 mInShelf = inShelf;
550 }
551
552 public boolean isInShelf() {
553 return mInShelf;
554 }
555
556 /**
557 * @param transformingInShelf whether the view is currently transforming into the shelf in an
558 * animated way
559 */
560 public void setTransformingInShelf(boolean transformingInShelf) {
561 mTransformingInShelf = transformingInShelf;
562 }
563
564 public boolean isTransformingIntoShelf() {
565 return mTransformingInShelf;
566 }
567
Selim Cinekd127d792016-11-01 19:11:41 -0700568 public boolean isAboveShelf() {
569 return false;
570 }
571
Selim Cinekc25989e2018-02-16 16:42:14 -0800572 public boolean hasExpandingChild() {
573 return false;
574 }
575
Selim Cinekeccb5de2016-10-28 15:04:05 -0700576 /**
Jorim Jaggibe565df2014-04-28 17:51:23 +0200577 * A listener notifying when {@link #getActualHeight} changes.
578 */
579 public interface OnHeightChangedListener {
Jorim Jaggi30c305c2014-07-01 23:34:41 +0200580
581 /**
582 * @param view the view for which the height changed, or {@code null} if just the top
583 * padding or the padding between the elements changed
Selim Cinekb5605e52015-02-20 18:21:41 +0100584 * @param needsAnimation whether the view height needs to be animated
Jorim Jaggi30c305c2014-07-01 23:34:41 +0200585 */
Selim Cinekb5605e52015-02-20 18:21:41 +0100586 void onHeightChanged(ExpandableView view, boolean needsAnimation);
Selim Cineka5e211b2014-08-11 17:35:48 +0200587
588 /**
589 * Called when the view is reset and therefore the height will change abruptly
590 *
591 * @param view The view which was reset.
592 */
593 void onReset(ExpandableView view);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200594 }
595}