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