blob: 5cb1b782ca7238cce3cc1760205c6f66301f6894 [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
19import android.content.Context;
Jorim Jaggibe565df2014-04-28 17:51:23 +020020import android.util.AttributeSet;
Jorim Jaggi00ebdfe2014-05-02 17:29:56 +020021import android.view.MotionEvent;
Jorim Jaggibe565df2014-04-28 17:51:23 +020022import android.view.View;
Selim Cinekc9c00ae2014-05-20 03:33:40 +020023import android.view.ViewGroup;
Jorim Jaggibe565df2014-04-28 17:51:23 +020024
25/**
26 * An abstract view for expandable views.
27 */
Selim Cinekc9c00ae2014-05-20 03:33:40 +020028public abstract class ExpandableView extends ViewGroup {
Jorim Jaggibe565df2014-04-28 17:51:23 +020029
30 private OnHeightChangedListener mOnHeightChangedListener;
31 protected int mActualHeight;
32 protected int mClipTopAmount;
Jorim Jaggibe565df2014-04-28 17:51:23 +020033 private boolean mActualHeightInitialized;
34
35 public ExpandableView(Context context, AttributeSet attrs) {
36 super(context, attrs);
37 }
38
39 @Override
Jorim Jaggibe565df2014-04-28 17:51:23 +020040 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Selim Cinekc9c00ae2014-05-20 03:33:40 +020041 for (int i = 0; i < getChildCount(); i++) {
42 View child = getChildAt(i);
43 int height = child.getMeasuredHeight();
44 int width = child.getMeasuredWidth();
45 int center = getWidth() / 2;
46 int childLeft = center - width / 2;
47 child.layout(childLeft,
48 0,
49 childLeft + width,
50 height);
51 }
Jorim Jaggibe565df2014-04-28 17:51:23 +020052 if (!mActualHeightInitialized && mActualHeight == 0) {
Selim Cinekc27437b2014-05-14 10:23:33 +020053 mActualHeight = getInitialHeight();
Jorim Jaggibe565df2014-04-28 17:51:23 +020054 }
55 mActualHeightInitialized = true;
56 }
57
Selim Cinekc27437b2014-05-14 10:23:33 +020058 protected int getInitialHeight() {
59 return getHeight();
60 }
61
Jorim Jaggi00ebdfe2014-05-02 17:29:56 +020062 @Override
63 public boolean dispatchTouchEvent(MotionEvent ev) {
64 if (filterMotionEvent(ev)) {
65 return super.dispatchTouchEvent(ev);
66 }
67 return false;
68 }
69
70 private boolean filterMotionEvent(MotionEvent event) {
71 return event.getActionMasked() != MotionEvent.ACTION_DOWN
72 || event.getY() > mClipTopAmount && event.getY() < mActualHeight;
73 }
74
Jorim Jaggibe565df2014-04-28 17:51:23 +020075 /**
76 * Sets the actual height of this notification. This is different than the laid out
77 * {@link View#getHeight()}, as we want to avoid layouting during scrolling and expanding.
Jorim Jaggid552d9d2014-05-07 19:41:13 +020078 *
79 * @param actualHeight The height of this notification.
80 * @param notifyListeners Whether the listener should be informed about the change.
Jorim Jaggibe565df2014-04-28 17:51:23 +020081 */
Jorim Jaggid552d9d2014-05-07 19:41:13 +020082 public void setActualHeight(int actualHeight, boolean notifyListeners) {
Jorim Jaggibe565df2014-04-28 17:51:23 +020083 mActualHeight = actualHeight;
Jorim Jaggid552d9d2014-05-07 19:41:13 +020084 if (notifyListeners) {
85 notifyHeightChanged();
86 }
87 }
88
89 public void setActualHeight(int actualHeight) {
90 setActualHeight(actualHeight, true);
Jorim Jaggibe565df2014-04-28 17:51:23 +020091 }
92
93 /**
94 * See {@link #setActualHeight}.
95 *
Jorim Jaggi9cbadd32014-05-01 20:18:31 +020096 * @return The current actual height of this notification.
Jorim Jaggibe565df2014-04-28 17:51:23 +020097 */
98 public int getActualHeight() {
99 return mActualHeight;
100 }
101
102 /**
103 * @return The maximum height of this notification.
104 */
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200105 public int getMaxHeight() {
106 return getHeight();
107 }
108
109 /**
110 * @return The minimum height of this notification.
111 */
112 public int getMinHeight() {
113 return getHeight();
114 }
Jorim Jaggibe565df2014-04-28 17:51:23 +0200115
116 /**
Jorim Jaggid552d9d2014-05-07 19:41:13 +0200117 * Sets the notification as dimmed. The default implementation does nothing.
118 *
119 * @param dimmed Whether the notification should be dimmed.
120 * @param fade Whether an animation should be played to change the state.
121 */
122 public void setDimmed(boolean dimmed, boolean fade) {
123 }
124
125 /**
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200126 * @return The desired notification height.
127 */
128 public int getIntrinsicHeight() {
Selim Cineka5eaa602014-05-12 21:27:47 +0200129 return getHeight();
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200130 }
131
132 /**
Jorim Jaggibe565df2014-04-28 17:51:23 +0200133 * Sets the amount this view should be clipped from the top. This is used when an expanded
134 * notification is scrolling in the top or bottom stack.
135 *
136 * @param clipTopAmount The amount of pixels this view should be clipped from top.
137 */
138 public void setClipTopAmount(int clipTopAmount) {
139 mClipTopAmount = clipTopAmount;
Jorim Jaggibe565df2014-04-28 17:51:23 +0200140 }
141
Selim Cinekeb973562014-05-02 17:07:49 +0200142 public int getClipTopAmount() {
143 return mClipTopAmount;
144 }
145
Jorim Jaggibe565df2014-04-28 17:51:23 +0200146 public void setOnHeightChangedListener(OnHeightChangedListener listener) {
147 mOnHeightChangedListener = listener;
148 }
149
150 /**
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200151 * @return Whether we can expand this views content.
Jorim Jaggibe565df2014-04-28 17:51:23 +0200152 */
Jorim Jaggi4222d9a2014-04-23 16:13:15 +0200153 public boolean isContentExpandable() {
154 return false;
Jorim Jaggibe565df2014-04-28 17:51:23 +0200155 }
156
Jorim Jaggi9cbadd32014-05-01 20:18:31 +0200157 public void notifyHeightChanged() {
158 if (mOnHeightChangedListener != null) {
159 mOnHeightChangedListener.onHeightChanged(this);
160 }
161 }
162
Selim Cinekc27437b2014-05-14 10:23:33 +0200163 public boolean isTransparent() {
164 return false;
165 }
166
Jorim Jaggibe565df2014-04-28 17:51:23 +0200167 /**
168 * A listener notifying when {@link #getActualHeight} changes.
169 */
170 public interface OnHeightChangedListener {
171 void onHeightChanged(ExpandableView view);
172 }
173}