ExpandableView.java revision a5eaa6034dd48fab0f5a232c09ebed35f359963e
1be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi/*
2be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * Copyright (C) 2014 The Android Open Source Project
3be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi *
4be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License");
5be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * you may not use this file except in compliance with the License.
6be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * You may obtain a copy of the License at
7be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi *
8be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi *      http://www.apache.org/licenses/LICENSE-2.0
9be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi *
10be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * Unless required by applicable law or agreed to in writing, software
11be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS,
12be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * See the License for the specific language governing permissions and
14be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * limitations under the License
15be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi */
16be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
17be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggipackage com.android.systemui.statusbar;
18be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
19be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggiimport android.content.Context;
20be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggiimport android.util.AttributeSet;
2100ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggiimport android.view.MotionEvent;
22be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggiimport android.view.View;
23be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggiimport android.widget.FrameLayout;
24be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
25be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi/**
26be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * An abstract view for expandable views.
27be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi */
28be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggipublic abstract class ExpandableView extends FrameLayout {
29be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
30be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private OnHeightChangedListener mOnHeightChangedListener;
31be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    protected int mActualHeight;
32be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    protected int mClipTopAmount;
33be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    private boolean mActualHeightInitialized;
34be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
35be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public ExpandableView(Context context, AttributeSet attrs) {
36be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super(context, attrs);
37be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
38be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
39be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
40be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
41be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.onLayout(changed, left, top, right, bottom);
42be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        if (!mActualHeightInitialized && mActualHeight == 0) {
43be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi            mActualHeight = getHeight();
44be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        }
45be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mActualHeightInitialized = true;
46be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
47be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
4800ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi    @Override
4900ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi    public boolean dispatchTouchEvent(MotionEvent ev) {
5000ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi        if (filterMotionEvent(ev)) {
5100ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi            return super.dispatchTouchEvent(ev);
5200ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi        }
5300ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi        return false;
5400ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi    }
5500ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi
5600ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi    private boolean filterMotionEvent(MotionEvent event) {
5700ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi        return event.getActionMasked() != MotionEvent.ACTION_DOWN
5800ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi                || event.getY() > mClipTopAmount && event.getY() < mActualHeight;
5900ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi    }
6000ebdfe8ba98c05a767660de2ed7c9a19fb49d74Jorim Jaggi
61be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    /**
62be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     * Sets the actual height of this notification. This is different than the laid out
63be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     * {@link View#getHeight()}, as we want to avoid layouting during scrolling and expanding.
64d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi     *
65d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi     * @param actualHeight The height of this notification.
66d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi     * @param notifyListeners Whether the listener should be informed about the change.
67be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     */
68d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int actualHeight, boolean notifyListeners) {
69be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mActualHeight = actualHeight;
70d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi        if (notifyListeners) {
71d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi            notifyHeightChanged();
72d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi        }
73d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    }
74d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi
75d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int actualHeight) {
76d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi        setActualHeight(actualHeight, true);
77be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
78be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
79be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    /**
80be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     * See {@link #setActualHeight}.
81be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     *
829cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi     * @return The current actual height of this notification.
83be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     */
84be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public int getActualHeight() {
85be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        return mActualHeight;
86be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
87be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
88be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    /**
89be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     * @return The maximum height of this notification.
90be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     */
914222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public int getMaxHeight() {
924222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi        return getHeight();
934222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
944222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi
954222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    /**
964222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi     * @return The minimum height of this notification.
974222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi     */
984222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public int getMinHeight() {
994222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi        return getHeight();
1004222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    }
101be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
102be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    /**
103d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi     * Sets the notification as dimmed. The default implementation does nothing.
104d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi     *
105d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi     * @param dimmed Whether the notification should be dimmed.
106d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi     * @param fade Whether an animation should be played to change the state.
107d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi     */
108d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setDimmed(boolean dimmed, boolean fade) {
109d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    }
110d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi
111d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    /**
1129cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi     * @return The desired notification height.
1139cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi     */
1149cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public int getIntrinsicHeight() {
115a5eaa6034dd48fab0f5a232c09ebed35f359963eSelim Cinek        return getHeight();
1169cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    }
1179cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi
1189cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    /**
119be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     * Sets the amount this view should be clipped from the top. This is used when an expanded
120be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     * notification is scrolling in the top or bottom stack.
121be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     *
122be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     * @param clipTopAmount The amount of pixels this view should be clipped from top.
123be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     */
124be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
125be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mClipTopAmount = clipTopAmount;
126be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
127be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
128eb973565f3efc6417ca35363e4d6c642947775d8Selim Cinek    public int getClipTopAmount() {
129eb973565f3efc6417ca35363e4d6c642947775d8Selim Cinek        return mClipTopAmount;
130eb973565f3efc6417ca35363e4d6c642947775d8Selim Cinek    }
131eb973565f3efc6417ca35363e4d6c642947775d8Selim Cinek
132be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setOnHeightChangedListener(OnHeightChangedListener listener) {
133be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        mOnHeightChangedListener = listener;
134be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
135be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
136be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    /**
1374222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi     * @return Whether we can expand this views content.
138be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     */
1394222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi    public boolean isContentExpandable() {
1404222d9a7fb87d73e1443ec1a2de9782b05741af6Jorim Jaggi        return false;
141be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
142be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
1439cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    public void notifyHeightChanged() {
1449cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi        if (mOnHeightChangedListener != null) {
1459cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi            mOnHeightChangedListener.onHeightChanged(this);
1469cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi        }
1479cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi    }
1489cbadd3c08a7d7dd3412743dd04aecb16c5a1595Jorim Jaggi
149be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    /**
150be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     * A listener notifying when {@link #getActualHeight} changes.
151be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi     */
152be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public interface OnHeightChangedListener {
153be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        void onHeightChanged(ExpandableView view);
154be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
155be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi}
156