ExpandableOutlineView.java revision 3322357b5045fdcc3e3b04c65219d39ce1ae441f
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.graphics.Outline;
217b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craikimport android.graphics.Rect;
228efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinekimport android.graphics.RectF;
23be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggiimport android.util.AttributeSet;
247b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craikimport android.view.View;
257b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craikimport android.view.ViewOutlineProvider;
26be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
27be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi/**
28be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi * Like {@link ExpandableView}, but setting an outline for the height and clipping.
29be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi */
30be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggipublic abstract class ExpandableOutlineView extends ExpandableView {
31be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
327b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik    private final Rect mOutlineRect = new Rect();
338efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek    private boolean mCustomOutline;
34d35c2793a3f4986f0513c17d729bdca57086c994Selim Cinek    private float mOutlineAlpha = -1f;
35be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
36be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public ExpandableOutlineView(Context context, AttributeSet attrs) {
37be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super(context, attrs);
387b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik        setOutlineProvider(new ViewOutlineProvider() {
397b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik            @Override
4031ba192dd201df2cad96a8c503f730130ab0d80fChris Craik            public void getOutline(View view, Outline outline) {
417b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik                if (!mCustomOutline) {
427b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik                    outline.setRect(0,
437b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik                            mClipTopAmount,
447b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik                            getWidth(),
45310df3127aace5a82cdc107fdb1e2d6957f38bccChris Wren                            Math.max(getActualHeight(), mClipTopAmount));
467b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik                } else {
47ca85ef85379d918f476a58d84b1529d640297629Selim Cinek                    outline.setRect(mOutlineRect);
487b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik                }
4983eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi                outline.setAlpha(mOutlineAlpha);
507b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik            }
517b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik        });
52be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
53be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
54be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
55d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi    public void setActualHeight(int actualHeight, boolean notifyListeners) {
56d552d9d8e964c102e6832610be46cf2c041e8829Jorim Jaggi        super.setActualHeight(actualHeight, notifyListeners);
577b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik        invalidateOutline();
58be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
59be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
60be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    @Override
61be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    public void setClipTopAmount(int clipTopAmount) {
62be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi        super.setClipTopAmount(clipTopAmount);
637b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik        invalidateOutline();
64be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi    }
65be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi
6683eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi    protected void setOutlineAlpha(float alpha) {
67d35c2793a3f4986f0513c17d729bdca57086c994Selim Cinek        if (alpha != mOutlineAlpha) {
68d35c2793a3f4986f0513c17d729bdca57086c994Selim Cinek            mOutlineAlpha = alpha;
69d35c2793a3f4986f0513c17d729bdca57086c994Selim Cinek            invalidateOutline();
70d35c2793a3f4986f0513c17d729bdca57086c994Selim Cinek        }
7183eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi    }
7283eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi
733322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek    @Override
743322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek    public float getOutlineAlpha() {
753322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek        return mOutlineAlpha;
763322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek    }
773322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek
788efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek    protected void setOutlineRect(RectF rect) {
798efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek        if (rect != null) {
808efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek            setOutlineRect(rect.left, rect.top, rect.right, rect.bottom);
818efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek        } else {
828efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek            mCustomOutline = false;
83560e64d3d95a17123048bebe2fb06ffe4567fb78Selim Cinek            setClipToOutline(false);
847b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik            invalidateOutline();
858efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek        }
868efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek    }
878efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek
883322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek    @Override
893322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek    public int getOutlineTranslation() {
903322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek        return mCustomOutline ? mOutlineRect.left : 0;
913322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek    }
923322357b5045fdcc3e3b04c65219d39ce1ae441fSelim Cinek
938efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek    protected void setOutlineRect(float left, float top, float right, float bottom) {
944b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        setOutlineRect(true, left, top, right, bottom);
954b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    }
964b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor
974b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor    protected void setOutlineRect(boolean clipToOutline, float left, float top, float right,
984b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor            float bottom) {
998efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek        mCustomOutline = true;
1004b80b1025f82fa7becc8e126bfa4aea39affcf65Mady Mellor        setClipToOutline(clipToOutline);
1018efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek
1027b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik        mOutlineRect.set((int) left, (int) top, (int) right, (int) bottom);
1038efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek
1048efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek        // Outlines need to be at least 1 dp
1053969ffa2f5830a680490d03fbb113a7fee900b56Selim Cinek        mOutlineRect.bottom = (int) Math.max(top, mOutlineRect.bottom);
1063969ffa2f5830a680490d03fbb113a7fee900b56Selim Cinek        mOutlineRect.right = (int) Math.max(left, mOutlineRect.right);
1078efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek
1087b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik        invalidateOutline();
1098efa6dde2b4f2cdbf046b87b7366404c3cc46219Selim Cinek    }
1107b7ca3cdf25bee73aa9e58aaaf6ce75fe81bd045Chris Craik
111be565dfc1c17b7ddafa9753851b8f82849fd3f42Jorim Jaggi}
112