blob: ae8d8445040496cafa4ae281d8664ca8417ca438 [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;
Jorim Jaggi4e857f42014-11-17 19:14:04 +010044 private boolean mDark;
Selim Cinek24d7cfa2014-05-20 13:50:57 +020045 private ArrayList<View> mMatchParentViews = new ArrayList<View>();
Selim Cineka272dfe2015-02-20 18:12:28 +010046 private static Rect mClipRect = new Rect();
Selim Cinek2cd45df2015-06-09 18:00:07 -070047 private boolean mWillBeGone;
Selim Cinek9c17b772015-07-07 20:37:09 -070048 private int mMinClipTopAmount = 0;
Selim Cinek4ffd6362015-12-29 15:12:23 +010049 private boolean mClipToActualHeight = true;
Adrian Roos14503e22016-03-09 14:01:24 -080050 private boolean mChangingPosition = false;
Selim Cinekd1395642016-04-28 12:22:42 -070051 private ViewGroup mTransientContainer;
Selim Cinekeccb5de2016-10-28 15:04:05 -070052 private boolean mInShelf;
53 private boolean mTransformingInShelf;
Jorim Jaggibe565df2014-04-28 17:51:23 +020054
55 public ExpandableView(Context context, AttributeSet attrs) {
56 super(context, attrs);
Selim Cinek24d7cfa2014-05-20 13:50:57 +020057 }
58
59 @Override
60 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Selim Cinek471e31a2015-12-11 13:39:48 -080061 final int givenSize = MeasureSpec.getSize(heightMeasureSpec);
felkachang79ca96d2018-04-27 16:55:40 +080062 final int viewHorizontalPadding = getPaddingStart() + getPaddingEnd();
Selim Cinekd84a5932015-12-15 11:45:36 -080063 int ownMaxHeight = Integer.MAX_VALUE;
Selim Cinek6f145cf2015-05-18 15:16:08 -070064 int heightMode = MeasureSpec.getMode(heightMeasureSpec);
Selim Cineka69f2a62015-12-11 17:28:12 -080065 if (heightMode != MeasureSpec.UNSPECIFIED && givenSize != 0) {
Selim Cinek471e31a2015-12-11 13:39:48 -080066 ownMaxHeight = Math.min(givenSize, ownMaxHeight);
Selim Cinek6f145cf2015-05-18 15:16:08 -070067 }
Selim Cinek24d7cfa2014-05-20 13:50:57 +020068 int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
69 int maxChildHeight = 0;
70 int childCount = getChildCount();
71 for (int i = 0; i < childCount; i++) {
72 View child = getChildAt(i);
Selim Cinek263398f2015-10-21 17:40:23 -070073 if (child.getVisibility() == GONE) {
Selim Cinekb5605e52015-02-20 18:21:41 +010074 continue;
75 }
Selim Cinek24d7cfa2014-05-20 13:50:57 +020076 int childHeightSpec = newHeightSpec;
77 ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
78 if (layoutParams.height != ViewGroup.LayoutParams.MATCH_PARENT) {
79 if (layoutParams.height >= 0) {
80 // An actual height is set
Selim Cineka69f2a62015-12-11 17:28:12 -080081 childHeightSpec = layoutParams.height > ownMaxHeight
Selim Cinek24d7cfa2014-05-20 13:50:57 +020082 ? MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.EXACTLY)
83 : MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
84 }
felkachang79ca96d2018-04-27 16:55:40 +080085 child.measure(getChildMeasureSpec(
86 widthMeasureSpec, viewHorizontalPadding, layoutParams.width),
Jorim Jaggib741f052014-06-03 19:57:26 +020087 childHeightSpec);
Selim Cinek24d7cfa2014-05-20 13:50:57 +020088 int childHeight = child.getMeasuredHeight();
89 maxChildHeight = Math.max(maxChildHeight, childHeight);
90 } else {
91 mMatchParentViews.add(child);
92 }
93 }
Selim Cineka69f2a62015-12-11 17:28:12 -080094 int ownHeight = heightMode == MeasureSpec.EXACTLY
95 ? givenSize : Math.min(ownMaxHeight, maxChildHeight);
Selim Cinek24d7cfa2014-05-20 13:50:57 +020096 newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY);
97 for (View child : mMatchParentViews) {
Jorim Jaggib741f052014-06-03 19:57:26 +020098 child.measure(getChildMeasureSpec(
felkachang79ca96d2018-04-27 16:55:40 +080099 widthMeasureSpec, viewHorizontalPadding, child.getLayoutParams().width),
Jorim Jaggib741f052014-06-03 19:57:26 +0200100 newHeightSpec);
Selim Cinek24d7cfa2014-05-20 13:50:57 +0200101 }
102 mMatchParentViews.clear();
103 int width = MeasureSpec.getSize(widthMeasureSpec);
104 setMeasuredDimension(width, ownHeight);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200105 }
106
107 @Override
Jorim Jaggibe565df2014-04-28 17:51:23 +0200108 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Selim Cinek24d7cfa2014-05-20 13:50:57 +0200109 super.onLayout(changed, left, top, right, bottom);
Selim Cinekba67acf2015-04-10 17:00:42 -0700110 updateClipping();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200111 }
112
Jorim Jaggi00ebdfe2014-05-02 17:29:56 +0200113 @Override
Selim Cineka69f2a62015-12-11 17:28:12 -0800114 public boolean pointInView(float localX, float localY, float slop) {
115 float top = mClipTopAmount;
116 float bottom = mActualHeight;
117 return localX >= -slop && localY >= top - slop && localX < ((mRight - mLeft) + slop) &&
118 localY < (bottom + slop);
Jorim Jaggi00ebdfe2014-05-02 17:29:56 +0200119 }
120
Jorim Jaggibe565df2014-04-28 17:51:23 +0200121 /**
122 * Sets the actual height of this notification. This is different than the laid out
123 * {@link View#getHeight()}, as we want to avoid layouting during scrolling and expanding.
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200124 *
125 * @param actualHeight The height of this notification.
126 * @param notifyListeners Whether the listener should be informed about the change.
Jorim Jaggibe565df2014-04-28 17:51:23 +0200127 */
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200128 public void setActualHeight(int actualHeight, boolean notifyListeners) {
Jorim Jaggibe565df2014-04-28 17:51:23 +0200129 mActualHeight = actualHeight;
Selim Cineka272dfe2015-02-20 18:12:28 +0100130 updateClipping();
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200131 if (notifyListeners) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100132 notifyHeightChanged(false /* needsAnimation */);
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200133 }
134 }
135
Selim Cinekb0ee18f2017-12-21 16:15:53 -0800136 /**
137 * Set the distance to the top roundness, from where we should start clipping a value above
138 * or equal to 0 is the effective distance, and if a value below 0 is received, there should
139 * be no clipping.
140 */
141 public void setDistanceToTopRoundness(float distanceToTopRoundness) {
142 }
143
Selim Cinekeef84282015-10-30 16:28:00 -0700144 public void setActualHeight(int actualHeight) {
145 setActualHeight(actualHeight, true /* notifyListeners */);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200146 }
147
148 /**
149 * See {@link #setActualHeight}.
150 *
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200151 * @return The current actual height of this notification.
Jorim Jaggibe565df2014-04-28 17:51:23 +0200152 */
153 public int getActualHeight() {
154 return mActualHeight;
155 }
156
Selim Cinek2627d722018-01-19 12:16:49 -0800157 public boolean isExpandAnimationRunning() {
158 return false;
159 }
160
Jorim Jaggibe565df2014-04-28 17:51:23 +0200161 /**
162 * @return The maximum height of this notification.
163 */
Selim Cinekb5605e52015-02-20 18:21:41 +0100164 public int getMaxContentHeight() {
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200165 return getHeight();
166 }
167
168 /**
Selim Cinekeb3fc3d2017-09-15 13:37:14 -0700169 * @return The minimum content height of this notification. This also respects the temporary
170 * states of the view.
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200171 */
172 public int getMinHeight() {
Selim Cinekeb3fc3d2017-09-15 13:37:14 -0700173 return getMinHeight(false /* ignoreTemporaryStates */);
174 }
175
176 /**
177 * Get the minimum height of this view.
178 *
179 * @param ignoreTemporaryStates should temporary states be ignored like the guts or heads-up.
180 *
181 * @return The minimum height that this view needs.
182 */
183 public int getMinHeight(boolean ignoreTemporaryStates) {
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200184 return getHeight();
185 }
Jorim Jaggibe565df2014-04-28 17:51:23 +0200186
187 /**
Selim Cinek567e8452016-03-24 10:54:56 -0700188 * @return The collapsed height of this view. Note that this might be different
189 * than {@link #getMinHeight()} because some elements like groups may have different sizes when
190 * they are system expanded.
Selim Cinek816c8e42015-11-19 12:00:45 -0800191 */
Selim Cinek567e8452016-03-24 10:54:56 -0700192 public int getCollapsedHeight() {
Selim Cinek816c8e42015-11-19 12:00:45 -0800193 return getHeight();
194 }
195
196 /**
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200197 * Sets the notification as dimmed. The default implementation does nothing.
198 *
199 * @param dimmed Whether the notification should be dimmed.
200 * @param fade Whether an animation should be played to change the state.
201 */
202 public void setDimmed(boolean dimmed, boolean fade) {
203 }
204
205 /**
John Spurlockbf370992014-06-17 13:58:31 -0400206 * Sets the notification as dark. The default implementation does nothing.
207 *
208 * @param dark Whether the notification should be dark.
209 * @param fade Whether an animation should be played to change the state.
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100210 * @param delay If fading, the delay of the animation.
John Spurlockbf370992014-06-17 13:58:31 -0400211 */
Jorim Jaggi4e857f42014-11-17 19:14:04 +0100212 public void setDark(boolean dark, boolean fade, long delay) {
213 mDark = dark;
214 }
215
216 public boolean isDark() {
217 return mDark;
John Spurlockbf370992014-06-17 13:58:31 -0400218 }
219
Selim Cinekd9b7dd42017-11-10 17:53:47 -0800220 public boolean isRemoved() {
221 return false;
222 }
223
John Spurlockbf370992014-06-17 13:58:31 -0400224 /**
Jorim Jaggiae441282014-08-01 02:45:18 +0200225 * See {@link #setHideSensitive}. This is a variant which notifies this view in advance about
226 * the upcoming state of hiding sensitive notifications. It gets called at the very beginning
227 * of a stack scroller update such that the updated intrinsic height (which is dependent on
228 * whether private or public layout is showing) gets taken into account into all layout
229 * calculations.
230 */
231 public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) {
232 }
233
234 /**
235 * Sets whether the notification should hide its private contents if it is sensitive.
236 */
237 public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
238 long duration) {
239 }
240
241 /**
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200242 * @return The desired notification height.
243 */
244 public int getIntrinsicHeight() {
Selim Cineka5eaa602014-05-12 21:27:47 +0200245 return getHeight();
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200246 }
247
248 /**
Jorim Jaggibe565df2014-04-28 17:51:23 +0200249 * Sets the amount this view should be clipped from the top. This is used when an expanded
250 * notification is scrolling in the top or bottom stack.
251 *
252 * @param clipTopAmount The amount of pixels this view should be clipped from top.
253 */
254 public void setClipTopAmount(int clipTopAmount) {
255 mClipTopAmount = clipTopAmount;
Mady Mellorc128f222016-04-26 11:42:46 -0700256 updateClipping();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200257 }
258
Selim Cineka686b2c2016-10-26 13:58:27 -0700259 /**
260 * Set the amount the the notification is clipped on the bottom in addition to the regular
261 * clipping. This is mainly used to clip something in a non-animated way without changing the
262 * actual height of the notification and is purely visual.
263 *
264 * @param clipBottomAmount the amount to clip.
265 */
266 public void setClipBottomAmount(int clipBottomAmount) {
267 mClipBottomAmount = clipBottomAmount;
268 updateClipping();
269 }
270
Selim Cinekeb973562014-05-02 17:07:49 +0200271 public int getClipTopAmount() {
272 return mClipTopAmount;
273 }
274
Selim Cinekb3dadcc2016-11-21 17:21:13 -0800275 public int getClipBottomAmount() {
Selim Cineka686b2c2016-10-26 13:58:27 -0700276 return mClipBottomAmount;
277 }
278
Jorim Jaggibe565df2014-04-28 17:51:23 +0200279 public void setOnHeightChangedListener(OnHeightChangedListener listener) {
280 mOnHeightChangedListener = listener;
281 }
282
283 /**
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200284 * @return Whether we can expand this views content.
Jorim Jaggibe565df2014-04-28 17:51:23 +0200285 */
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200286 public boolean isContentExpandable() {
287 return false;
Jorim Jaggibe565df2014-04-28 17:51:23 +0200288 }
289
Selim Cinekb5605e52015-02-20 18:21:41 +0100290 public void notifyHeightChanged(boolean needsAnimation) {
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200291 if (mOnHeightChangedListener != null) {
Selim Cinekb5605e52015-02-20 18:21:41 +0100292 mOnHeightChangedListener.onHeightChanged(this, needsAnimation);
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200293 }
294 }
295
Selim Cinekc27437b2014-05-14 10:23:33 +0200296 public boolean isTransparent() {
297 return false;
298 }
299
Jorim Jaggibe565df2014-04-28 17:51:23 +0200300 /**
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200301 * Perform a remove animation on this view.
Jorim Jaggi60d07c52014-07-31 15:38:21 +0200302 * @param duration The duration of the remove animation.
Selim Cinek332c23f2018-03-16 17:37:50 -0700303 * @param delay The delay of the animation
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200304 * @param translationDirection The direction value from [-1 ... 1] indicating in which the
Selim Cinek332c23f2018-03-16 17:37:50 -0700305 * animation should be performed. A value of -1 means that The
306 * remove animation should be performed upwards,
307 * such that the child appears to be going away to the top. 1
308 * Should mean the opposite.
309 * @param isHeadsUpAnimation Is this a headsUp animation.
310 * @param endLocation The location where the horizonal heads up disappear animation should end.
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200311 * @param onFinishedRunnable A runnable which should be run when the animation is finished.
Selim Cinek332c23f2018-03-16 17:37:50 -0700312 * @param animationListener An animation listener to add to the animation.
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200313 */
Selim Cinek332c23f2018-03-16 17:37:50 -0700314 public abstract void performRemoveAnimation(long duration,
315 long delay, float translationDirection, boolean isHeadsUpAnimation, float endLocation,
316 Runnable onFinishedRunnable,
317 AnimatorListenerAdapter animationListener);
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200318
Selim Cinek332c23f2018-03-16 17:37:50 -0700319 public abstract void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear);
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200320
Selim Cinek281c2022016-10-13 19:14:43 -0700321 /**
Selim Cinekdb167372016-11-17 15:41:17 -0800322 * Set the notification appearance to be below the speed bump.
Selim Cinek281c2022016-10-13 19:14:43 -0700323 * @param below true if it is below.
324 */
Selim Cinekdb167372016-11-17 15:41:17 -0800325 public void setBelowSpeedBump(boolean below) {
Selim Cinek3d2b94bf2014-07-02 22:12:47 +0200326 }
327
Selim Cinekd127d792016-11-01 19:11:41 -0700328 public int getPinnedHeadsUpHeight() {
329 return getIntrinsicHeight();
330 }
331
332
Mady Mellor34958fa2016-02-23 09:52:17 -0800333 /**
334 * Sets the translation of the view.
335 */
336 public void setTranslation(float translation) {
337 setTranslationX(translation);
338 }
339
340 /**
341 * Gets the translation of the view.
342 */
343 public float getTranslation() {
344 return getTranslationX();
345 }
346
Selim Cinek31094df2014-08-14 19:28:15 +0200347 public void onHeightReset() {
Selim Cineke34c6512014-08-14 11:19:41 +0200348 if (mOnHeightChangedListener != null) {
349 mOnHeightChangedListener.onReset(this);
350 }
Selim Cineka5e211b2014-08-11 17:35:48 +0200351 }
352
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200353 /**
Selim Cineke32010a2014-08-20 23:50:41 +0200354 * This method returns the drawing rect for the view which is different from the regular
355 * drawing rect, since we layout all children in the {@link NotificationStackScrollLayout} at
356 * position 0 and usually the translation is neglected. Since we are manually clipping this
357 * view,we also need to subtract the clipTopAmount from the top. This is needed in order to
358 * ensure that accessibility and focusing work correctly.
359 *
360 * @param outRect The (scrolled) drawing bounds of the view.
361 */
362 @Override
363 public void getDrawingRect(Rect outRect) {
364 super.getDrawingRect(outRect);
365 outRect.left += getTranslationX();
366 outRect.right += getTranslationX();
367 outRect.bottom = (int) (outRect.top + getTranslationY() + getActualHeight());
368 outRect.top += getTranslationY() + getClipTopAmount();
369 }
370
Adrian Rooscd55f432015-06-10 16:42:53 -0700371 @Override
372 public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
373 super.getBoundsOnScreen(outRect, clipToParent);
Adrian Roos98dd7f12016-06-14 15:51:40 -0700374 if (getTop() + getTranslationY() < 0) {
375 // We got clipped to the parent here - make sure we undo that.
376 outRect.top += getTop() + getTranslationY();
377 }
Adrian Roosb44f5482015-06-11 12:19:16 -0700378 outRect.bottom = outRect.top + getActualHeight();
Mady Mellorc128f222016-04-26 11:42:46 -0700379 outRect.top += getClipTopAmount();
Adrian Rooscd55f432015-06-10 16:42:53 -0700380 }
381
Selim Cinek263398f2015-10-21 17:40:23 -0700382 public boolean isSummaryWithChildren() {
Selim Cinekb5605e52015-02-20 18:21:41 +0100383 return false;
384 }
385
386 public boolean areChildrenExpanded() {
387 return false;
388 }
389
Selim Cinek2627d722018-01-19 12:16:49 -0800390 protected void updateClipping() {
391 if (mClipToActualHeight && shouldClipToActualHeight()) {
Mady Mellorc128f222016-04-26 11:42:46 -0700392 int top = getClipTopAmount();
Selim Cinekb3dadcc2016-11-21 17:21:13 -0800393 mClipRect.set(0, top, getWidth(), Math.max(getActualHeight() + getExtraBottomPadding()
Anthony Chen04d1ea72017-04-21 14:30:11 -0700394 - mClipBottomAmount, top));
Selim Cinek4ffd6362015-12-29 15:12:23 +0100395 setClipBounds(mClipRect);
396 } else {
397 setClipBounds(null);
Selim Cinekf92a1fd2015-07-31 16:10:32 -0700398 }
Selim Cinek4ffd6362015-12-29 15:12:23 +0100399 }
400
Selim Cinek99e9adf2018-03-15 09:17:47 -0700401 public float getHeaderVisibleAmount() {
402 return 1.0f;
403 }
404
Selim Cinek2627d722018-01-19 12:16:49 -0800405 protected boolean shouldClipToActualHeight() {
406 return true;
407 }
408
Selim Cinek4ffd6362015-12-29 15:12:23 +0100409 public void setClipToActualHeight(boolean clipToActualHeight) {
410 mClipToActualHeight = clipToActualHeight;
411 updateClipping();
Selim Cineka272dfe2015-02-20 18:12:28 +0100412 }
413
Selim Cinek2cd45df2015-06-09 18:00:07 -0700414 public boolean willBeGone() {
415 return mWillBeGone;
416 }
417
418 public void setWillBeGone(boolean willBeGone) {
419 mWillBeGone = willBeGone;
420 }
421
Selim Cinek9c17b772015-07-07 20:37:09 -0700422 public int getMinClipTopAmount() {
423 return mMinClipTopAmount;
424 }
425
426 public void setMinClipTopAmount(int minClipTopAmount) {
427 mMinClipTopAmount = minClipTopAmount;
428 }
429
Selim Cinek471e31a2015-12-11 13:39:48 -0800430 @Override
431 public void setLayerType(int layerType, Paint paint) {
432 if (hasOverlappingRendering()) {
433 super.setLayerType(layerType, paint);
434 }
435 }
436
437 @Override
438 public boolean hasOverlappingRendering() {
Selim Cineka69f2a62015-12-11 17:28:12 -0800439 // Otherwise it will be clipped
440 return super.hasOverlappingRendering() && getActualHeight() <= getHeight();
Selim Cinek471e31a2015-12-11 13:39:48 -0800441 }
442
Selim Cinek277a8aa2016-01-22 12:12:37 -0800443 public float getShadowAlpha() {
444 return 0.0f;
445 }
446
447 public void setShadowAlpha(float shadowAlpha) {
448 }
449
Selim Cinek42357e02016-02-24 18:48:01 -0800450 /**
Selim Cineka7ed2c12017-01-23 20:47:24 -0800451 * @return an amount between -1 and 1 of increased padding that this child needs. 1 means it
452 * needs a full increased padding while -1 means it needs no padding at all. For 0.0f the normal
453 * padding is applied.
Selim Cinek42357e02016-02-24 18:48:01 -0800454 */
455 public float getIncreasedPaddingAmount() {
456 return 0.0f;
Selim Cinek61633a82016-01-25 15:54:10 -0800457 }
458
Selim Cinek3776fe02016-02-04 13:32:43 -0800459 public boolean mustStayOnScreen() {
460 return false;
461 }
462
Selim Cinek33223572016-02-19 19:32:22 -0800463 public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd,
464 int outlineTranslation) {
465 }
466
467 public float getOutlineAlpha() {
468 return 0.0f;
469 }
470
471 public int getOutlineTranslation() {
472 return 0;
473 }
474
Adrian Roos14503e22016-03-09 14:01:24 -0800475 public void setChangingPosition(boolean changingPosition) {
476 mChangingPosition = changingPosition;
477 }
478
479 public boolean isChangingPosition() {
480 return mChangingPosition;
481 }
482
Selim Cinekd1395642016-04-28 12:22:42 -0700483 public void setTransientContainer(ViewGroup transientContainer) {
484 mTransientContainer = transientContainer;
485 }
486
487 public ViewGroup getTransientContainer() {
488 return mTransientContainer;
489 }
490
Selim Cineke32010a2014-08-20 23:50:41 +0200491 /**
Mady Mellorb0a82462016-04-30 17:31:02 -0700492 * @return padding used to alter how much of the view is clipped.
493 */
494 public int getExtraBottomPadding() {
495 return 0;
496 }
497
498 /**
499 * @return true if the group's expansion state is changing, false otherwise.
500 */
501 public boolean isGroupExpansionChanging() {
502 return false;
503 }
504
505 public boolean isGroupExpanded() {
506 return false;
507 }
508
Selim Cinek9b9d6e12017-11-30 12:29:47 +0100509 public void setHeadsUpIsVisible() {
510 }
511
Mady Mellorb0a82462016-04-30 17:31:02 -0700512 public boolean isChildInGroup() {
513 return false;
514 }
515
Adrian Roos599be342016-06-13 14:54:39 -0700516 public void setActualHeightAnimating(boolean animating) {}
517
Selim Cinekbbcebde2016-11-09 18:28:20 -0800518 public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
519 return new ExpandableViewState();
520 }
521
Mady Mellorb0a82462016-04-30 17:31:02 -0700522 /**
Selim Cinek281c2022016-10-13 19:14:43 -0700523 * @return whether the current view doesn't add height to the overall content. This means that
524 * if it is added to a list of items, it's content will still have the same height.
525 * An example is the notification shelf, that is always placed on top of another view.
526 */
527 public boolean hasNoContentHeight() {
528 return false;
529 }
530
531 /**
Selim Cinekeccb5de2016-10-28 15:04:05 -0700532 * @param inShelf whether the view is currently fully in the notification shelf.
533 */
534 public void setInShelf(boolean inShelf) {
535 mInShelf = inShelf;
536 }
537
538 public boolean isInShelf() {
539 return mInShelf;
540 }
541
542 /**
543 * @param transformingInShelf whether the view is currently transforming into the shelf in an
544 * animated way
545 */
546 public void setTransformingInShelf(boolean transformingInShelf) {
547 mTransformingInShelf = transformingInShelf;
548 }
549
550 public boolean isTransformingIntoShelf() {
551 return mTransformingInShelf;
552 }
553
Selim Cinekd127d792016-11-01 19:11:41 -0700554 public boolean isAboveShelf() {
555 return false;
556 }
557
Selim Cinekc25989e2018-02-16 16:42:14 -0800558 public boolean hasExpandingChild() {
559 return false;
560 }
561
Selim Cinekeccb5de2016-10-28 15:04:05 -0700562 /**
Jorim Jaggibe565df2014-04-28 17:51:23 +0200563 * A listener notifying when {@link #getActualHeight} changes.
564 */
565 public interface OnHeightChangedListener {
Jorim Jaggi30c305c2014-07-01 23:34:41 +0200566
567 /**
568 * @param view the view for which the height changed, or {@code null} if just the top
569 * padding or the padding between the elements changed
Selim Cinekb5605e52015-02-20 18:21:41 +0100570 * @param needsAnimation whether the view height needs to be animated
Jorim Jaggi30c305c2014-07-01 23:34:41 +0200571 */
Selim Cinekb5605e52015-02-20 18:21:41 +0100572 void onHeightChanged(ExpandableView view, boolean needsAnimation);
Selim Cineka5e211b2014-08-11 17:35:48 +0200573
574 /**
575 * Called when the view is reset and therefore the height will change abruptly
576 *
577 * @param view The view which was reset.
578 */
579 void onReset(ExpandableView view);
Jorim Jaggibe565df2014-04-28 17:51:23 +0200580 }
581}