├── .gitignore
├── LICENSE.txt
├── README.md
├── ZDepthShadowLayout
    ├── .gitignore
    ├── ZDepthShadowLayout.iml
    ├── build.gradle
    ├── proguard-rules.pro
    └── src
    │   ├── androidTest
    │       └── java
    │       │   └── app
    │       │       └── mosn
    │       │           └── zdepthshadowlayout
    │       │               └── ApplicationTest.java
    │   └── main
    │       ├── AndroidManifest.xml
    │       ├── java
    │           └── app
    │           │   └── mosn
    │           │       └── zdepthshadowlayout
    │           │           ├── ShadowView.java
    │           │           ├── ZDepth.java
    │           │           ├── ZDepthParam.java
    │           │           ├── ZDepthShadowLayout.java
    │           │           ├── shadow
    │           │               ├── Shadow.java
    │           │               ├── ShadowOval.java
    │           │               └── ShadowRect.java
    │           │           └── utils
    │           │               └── DisplayUtils.java
    │       └── res
    │           └── values
    │               ├── attrs.xml
    │               └── strings.xml
├── blobs
    ├── demo.gif
    ├── screen_capture.png
    ├── shadow_zdepth.png
    ├── zdepthshadow_layout_1.png
    ├── zdepthshadow_layout_2.png
    └── zdepthshadow_zdepth_5.png
├── build.gradle
├── gradle.properties
├── gradle
    └── wrapper
    │   ├── gradle-wrapper.jar
    │   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── rippleeffect
    ├── .gitignore
    ├── build.gradle
    ├── proguard-rules.pro
    └── src
    │   ├── androidTest
    │       └── java
    │       │   └── com
    │       │       └── andexert
    │       │           └── library
    │       │               └── ApplicationTest.java
    │   └── main
    │       ├── AndroidManifest.xml
    │       ├── java
    │           └── com
    │           │   └── andexert
    │           │       └── library
    │           │           └── RippleView.java
    │       └── res
    │           ├── drawable-hdpi
    │               └── ic_launcher.png
    │           ├── drawable-mdpi
    │               └── ic_launcher.png
    │           ├── drawable-xhdpi
    │               └── ic_launcher.png
    │           ├── drawable-xxhdpi
    │               └── ic_launcher.png
    │           ├── drawable
    │               └── shape_rounded.xml
    │           └── values
    │               ├── attrs.xml
    │               ├── colors.xml
    │               ├── strings.xml
    │               └── styles.xml
├── sample
    ├── .gitignore
    ├── build.gradle
    ├── proguard-rules.pro
    ├── sample.iml
    └── src
    │   ├── androidTest
    │       └── java
    │       │   └── app
    │       │       └── mosn
    │       │           └── zdepthshadowsample
    │       │               └── ApplicationTest.java
    │   └── main
    │       ├── AndroidManifest.xml
    │       ├── java
    │           └── app
    │           │   └── mosn
    │           │       └── zdepthshadowsample
    │           │           ├── ChangeZDepthActivity.java
    │           │           ├── MainActivity.java
    │           │           ├── SampleFloatingActionMenuActivity.java
    │           │           ├── SimpleZDepthActivity.java
    │           │           ├── WithRippleEffectActivity.java
    │           │           └── fam
    │           │               ├── FloatingActionMenu.java
    │           │               ├── FloatingActionMenuButton.java
    │           │               └── FloatingActionMenuToggle.java
    │       └── res
    │           ├── drawable-hdpi
    │               └── ic_launcher.png
    │           ├── drawable-mdpi
    │               └── ic_launcher.png
    │           ├── drawable-xhdpi
    │               └── ic_launcher.png
    │           ├── drawable-xxhdpi
    │               └── ic_launcher.png
    │           ├── drawable
    │               └── drawable_circle.xml
    │           ├── layout
    │               ├── activity_change_zdepth.xml
    │               ├── activity_floating_action_menu.xml
    │               ├── activity_main.xml
    │               ├── activity_simple_zdepth.xml
    │               └── activity_with_ripple_effect.xml
    │           ├── menu
    │               └── menu_main.xml
    │           ├── values-w820dp
    │               └── dimens.xml
    │           └── values
    │               ├── dimens.xml
    │               ├── strings.xml
    │               └── styles.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
 1 | # Created by .gitignore support plugin (hsz.mobi)
 2 | 
 3 | ### Android template
 4 | # Built application files
 5 | *.apk
 6 | *.ap_
 7 | 
 8 | # Files for the Dalvik VM
 9 | *.dex
10 | 
11 | # Java class files
12 | *.class
13 | 
14 | # Generated files
15 | bin/
16 | gen/
17 | 
18 | # Gradle files
19 | .gradle/
20 | build/
21 | 
22 | # Local configuration file (sdk path, etc)
23 | local.properties
24 | 
25 | # Proguard folder generated by Eclipse
26 | proguard/
27 | 
28 | # Log Files
29 | *.log
30 | 
31 | 
32 | ### OSX template
33 | .DS_Store
34 | .AppleDouble
35 | .LSOverride
36 | 
37 | # Icon must end with two \r
38 | Icon  
39 | 
40 | # Thumbnails
41 | ._*
42 | 
43 | # Files that might appear on external disk
44 | .Spotlight-V100
45 | .Trashes
46 | 
47 | # Directories potentially created on remote AFP share
48 | .AppleDB
49 | .AppleDesktop
50 | Network Trash Folder
51 | Temporary Items
52 | .apdisk
53 | 
54 | 
55 | ### JetBrains template
56 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
57 | 
58 | ## Directory-based project format
59 | .idea/
60 | /*.iml
61 | # if you remove the above rule, at least ignore user-specific stuff:
62 | # .idea/workspace.xml
63 | # .idea/tasks.xml
64 | # .idea/dictionaries
65 | # and these sensitive or high-churn files:
66 | # .idea/dataSources.ids
67 | # .idea/dataSources.xml
68 | # .idea/sqlDataSources.xml
69 | # .idea/dynamic.xml
70 | # and, if using gradle::
71 | # .idea/gradle.xml
72 | # .idea/libraries
73 | 
74 | ## File-based project format
75 | *.ipr
76 | *.iws
77 | 
78 | ## Additional for IntelliJ
79 | out/
80 | 
81 | # generated by mpeltonen/sbt-idea plugin
82 | .idea_modules/
83 | 
84 | # generated by JIRA plugin
85 | atlassian-ide-plugin.xml
86 | 
87 | # generated by Crashlytics plugin (for Android Studio and Intellij)
88 | com_crashlytics_export_strings.xml
89 | 
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2014 Shogo Mizumoto
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
  1 | ZDepthShadowLayout
  2 | ==================
  3 | 
  4 | Android - draw z-depth shadow of MaterialDesign
  5 | 
  6 | ## Demo
  7 | 
  8 | 
  9 | 
 10 | ## Screen Capture
 11 | 
 12 | 
 13 | 
 14 | ## Download
 15 | 
 16 | ```groovy
 17 | apply plugin: 'com.android.application'
 18 | 
 19 | repositories {
 20 |     maven {
 21 |         url "https://jitpack.io"
 22 |     }
 23 | }
 24 | 
 25 | android {
 26 |     // something code...
 27 | }
 28 | 
 29 | dependencies {
 30 |     compile 'com.github.ShogoMizumoto:ZDepthShadowLayout:1.0.4'
 31 | }
 32 | ```
 33 | 
 34 | ## How to Use
 35 | 
 36 | ```xml
 37 | 
 42 | 
 43 |     
 49 | 
 50 |         
 55 | 
 56 |     
 57 | 
 58 | 
 59 | ```
 60 | 
 61 | ### Attribute
 62 | 
 63 | #### configuration
 64 | 
 65 | ```xml
 66 | 
 73 | ```
 74 | 
 75 | #### attrs.xml
 76 | 
 77 | ```xml
 78 | 
 79 |     
 80 |         
 81 |             
 82 |             
 83 |             
 84 |             
 85 |             
 86 |             
 87 |         
 88 |         
 89 |             
 90 |             
 91 |         
 92 |         
 93 |             
 94 |             
 95 |             
 96 |             
 97 |             
 98 |             
 99 |         
100 |         
101 |             
102 |             
103 |             
104 |             
105 |             
106 |             
107 |         
108 |         
109 |             
110 |             
111 |             
112 |             
113 |             
114 |             
115 |         
116 |         
117 |             
118 |             
119 |             
120 |             
121 |             
122 |             
123 |         
124 |         
125 |             
126 |             
127 |             
128 |             
129 |             
130 |             
131 |         
132 |         
133 |         
134 |     
135 | 
136 | ```
137 | 
138 | ## What is ZDepth?
139 | 
140 | 
141 | 
142 | #### Example : z-depth 5
143 | 
144 | 
145 | 
146 | ### Outline
147 | 
148 | 
149 | 
150 | #### Example
151 | 
152 | 
153 | 
154 | ## MIT License
155 | 
156 | This library is released under the MIT License, see LICENSE.txt.
157 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | *.iml
3 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/ZDepthShadowLayout.iml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |   
 4 |     
 5 |       
 6 |         
 7 |       
 8 |     
 9 |     
10 |       
11 |         
12 |         
13 |         
14 |         
15 |         
16 |         
17 |         
18 |         
19 |         
20 |         
21 |         
22 |         
23 |         
24 |       
25 |     
26 |   
27 |   
28 |     
29 |     
30 |     
31 |     
32 |       
33 |       
34 |       
35 |       
36 |       
37 |       
38 |       
39 |       
40 |       
41 |       
42 |       
43 |       
44 |       
45 |       
46 |       
47 |       
48 |       
49 |       
50 |       
51 |       
52 |       
53 |       
54 |       
55 |       
56 |       
57 |       
58 |       
59 |       
60 |       
61 |       
62 |       
63 |       
64 |       
65 |       
66 |       
67 |       
68 |       
69 |       
70 |       
71 |       
72 |       
73 |       
74 |       
75 |       
76 |       
77 |       
78 |       
79 |       
80 |       
81 |       
82 |       
83 |       
84 |       
85 |       
86 |       
87 |     
88 |     
89 |     
90 |   
91 | 
92 | 
93 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/build.gradle:
--------------------------------------------------------------------------------
 1 | apply plugin: 'com.android.library'
 2 | apply plugin: 'android-maven'
 3 | 
 4 | android {
 5 |     compileSdkVersion 21
 6 |     buildToolsVersion "21.1.2"
 7 | 
 8 |     defaultConfig {
 9 |         minSdkVersion 14
10 |         targetSdkVersion 21
11 |         versionCode 1
12 |         versionName "1.0"
13 |     }
14 |     buildTypes {
15 |         release {
16 |             minifyEnabled false
17 |             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 |         }
19 |     }
20 | }
21 | 
22 | dependencies {
23 |     compile fileTree(dir: 'libs', include: ['*.jar'])
24 | }
25 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/proguard-rules.pro:
--------------------------------------------------------------------------------
 1 | # Add project specific ProGuard rules here.
 2 | # By default, the flags in this file are appended to flags specified
 3 | # in /Users/Shogo/Development/Android/SDK/SDK/tools/proguard/proguard-android.txt
 4 | # You can edit the include path and order by changing the proguardFiles
 5 | # directive in build.gradle.
 6 | #
 7 | # For more details, see
 8 | #   http://developer.android.com/guide/developing/tools/proguard.html
 9 | 
10 | # Add any project specific keep options here:
11 | 
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | #   public *;
17 | #}
18 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/androidTest/java/app/mosn/zdepthshadowlayout/ApplicationTest.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowlayout;
 2 | 
 3 | import android.app.Application;
 4 | import android.test.ApplicationTestCase;
 5 | 
 6 | /**
 7 |  * Testing Fundamentals
 8 |  */
 9 | public class ApplicationTest extends ApplicationTestCase {
10 |     public ApplicationTest() {
11 |         super(Application.class);
12 |     }
13 | }
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 | 
2 |     
3 | 
4 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/java/app/mosn/zdepthshadowlayout/ShadowView.java:
--------------------------------------------------------------------------------
  1 | package app.mosn.zdepthshadowlayout;
  2 | 
  3 | import android.animation.PropertyValuesHolder;
  4 | import android.animation.ValueAnimator;
  5 | import android.content.Context;
  6 | import android.graphics.Canvas;
  7 | import android.os.Build;
  8 | import android.util.AttributeSet;
  9 | import android.view.View;
 10 | import android.view.animation.LinearInterpolator;
 11 | 
 12 | 
 13 | import app.mosn.zdepthshadowlayout.shadow.Shadow;
 14 | import app.mosn.zdepthshadowlayout.shadow.ShadowOval;
 15 | import app.mosn.zdepthshadowlayout.shadow.ShadowRect;
 16 | 
 17 | 
 18 | public class ShadowView extends View {
 19 |     protected static final String TAG = "ShadowView";
 20 | 
 21 |     protected static final String ANIM_PROPERTY_ALPHA_TOP_SHADOW = "alphaTopShadow";
 22 |     protected static final String ANIM_PROPERTY_ALPHA_BOTTOM_SHADOW = "alphaBottomShadow";
 23 |     protected static final String ANIM_PROPERTY_OFFSET_TOP_SHADOW = "offsetTopShadow";
 24 |     protected static final String ANIM_PROPERTY_OFFSET_BOTTOM_SHADOW = "offsetBottomShadow";
 25 |     protected static final String ANIM_PROPERTY_BLUR_TOP_SHADOW = "blurTopShadow";
 26 |     protected static final String ANIM_PROPERTY_BLUR_BOTTOM_SHADOW = "blurBottomShadow";
 27 | 
 28 |     protected Shadow mShadow;
 29 |     protected ZDepthParam mZDepthParam;
 30 |     protected int mZDepthPaddingLeft;
 31 |     protected int mZDepthPaddingTop;
 32 |     protected int mZDepthPaddingRight;
 33 |     protected int mZDepthPaddingBottom;
 34 |     protected long mZDepthAnimDuration;
 35 |     protected boolean mZDepthDoAnimation;
 36 | 
 37 |     protected ShadowView(Context context) {
 38 |         this(context, null);
 39 |         init();
 40 |     }
 41 | 
 42 |     protected ShadowView(Context context, AttributeSet attrs) {
 43 |         this(context, attrs, 0);
 44 |         init();
 45 |     }
 46 | 
 47 |     protected ShadowView(Context context, AttributeSet attrs, int defStyle) {
 48 |         super(context, attrs, defStyle);
 49 |         init();
 50 |     }
 51 | 
 52 |     protected void init() {
 53 |         setWillNotDraw(false);
 54 |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
 55 |             setLayerType(View.LAYER_TYPE_SOFTWARE, null);
 56 |         }
 57 |     }
 58 | 
 59 |     protected void setZDepthDoAnimation(boolean doAnimation) {
 60 |         mZDepthDoAnimation = doAnimation;
 61 |     }
 62 | 
 63 |     protected void setZDepthAnimDuration(long duration) {
 64 |         mZDepthAnimDuration = duration;
 65 |     }
 66 | 
 67 |     protected void setZDepthPaddingLeft(int zDepthPaddingLeftValue) {
 68 |         ZDepth zDepth = getZDepthWithAttributeValue(zDepthPaddingLeftValue);
 69 |         mZDepthPaddingLeft = measureZDepthPadding(zDepth);
 70 |     }
 71 | 
 72 |     protected void setZDepthPaddingTop(int zDepthPaddingTopValue) {
 73 |         ZDepth zDepth = getZDepthWithAttributeValue(zDepthPaddingTopValue);
 74 |         mZDepthPaddingTop = measureZDepthPadding(zDepth);
 75 |     }
 76 | 
 77 |     protected void setZDepthPaddingRight(int zDepthPaddingRightValue) {
 78 |         ZDepth zDepth = getZDepthWithAttributeValue(zDepthPaddingRightValue);
 79 |         mZDepthPaddingRight = measureZDepthPadding(zDepth);
 80 |     }
 81 | 
 82 |     protected void setZDepthPaddingBottom(int zDepthPaddingBottomValue) {
 83 |         ZDepth zDepth = getZDepthWithAttributeValue(zDepthPaddingBottomValue);
 84 |         mZDepthPaddingBottom = measureZDepthPadding(zDepth);
 85 |     }
 86 | 
 87 |     protected int measureZDepthPadding(ZDepth zDepth) {
 88 |         float maxAboveBlurRadius = zDepth.getBlurTopShadowPx(getContext());
 89 |         float maxAboveOffset     = zDepth.getOffsetYTopShadowPx(getContext());
 90 |         float maxBelowBlurRadius = zDepth.getBlurBottomShadowPx(getContext());
 91 |         float maxBelowOffset     = zDepth.getOffsetYBottomShadowPx(getContext());
 92 | 
 93 |         float maxAboveSize = maxAboveBlurRadius + maxAboveOffset;
 94 |         float maxBelowSize = maxBelowBlurRadius + maxBelowOffset;
 95 | 
 96 |         return (int) Math.max(maxAboveSize, maxBelowSize);
 97 |     }
 98 | 
 99 |     protected int getZDepthPaddingLeft() {
100 |         return mZDepthPaddingLeft;
101 |     }
102 | 
103 |     protected int getZDepthPaddingTop() {
104 |         return mZDepthPaddingTop;
105 |     }
106 | 
107 |     protected int getZDepthPaddingRight() {
108 |         return mZDepthPaddingRight;
109 |     }
110 | 
111 |     protected int getZDepthPaddingBottom() {
112 |         return mZDepthPaddingBottom;
113 |     }
114 | 
115 |     protected void setShape(int shape) {
116 |         switch (shape) {
117 |             case ZDepthShadowLayout.SHAPE_RECT:
118 |                 mShadow = new ShadowRect();
119 |                 break;
120 | 
121 |             case ZDepthShadowLayout.SHAPE_OVAL:
122 |                 mShadow = new ShadowOval();
123 |                 break;
124 | 
125 |             default:
126 |                 throw new IllegalArgumentException("unknown shape value.");
127 |         }
128 |     }
129 | 
130 |     protected void setZDepth(int zDepthValue) {
131 |         ZDepth zDepth = getZDepthWithAttributeValue(zDepthValue);
132 |         setZDepth(zDepth);
133 |     }
134 | 
135 |     protected void setZDepth(ZDepth zDepth) {
136 |         mZDepthParam = new ZDepthParam();
137 |         mZDepthParam.initZDepth(getContext(), zDepth);
138 |     }
139 | 
140 |     private ZDepth getZDepthWithAttributeValue(int zDepthValue) {
141 |         switch (zDepthValue) {
142 |             case 0: return ZDepth.Depth0;
143 |             case 1: return ZDepth.Depth1;
144 |             case 2: return ZDepth.Depth2;
145 |             case 3: return ZDepth.Depth3;
146 |             case 4: return ZDepth.Depth4;
147 |             case 5: return ZDepth.Depth5;
148 |             default: throw new IllegalArgumentException("unknown zDepth value.");
149 |         }
150 |     }
151 | 
152 |     @Override
153 |     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
154 |         int wSize = MeasureSpec.getSize(widthMeasureSpec);
155 |         int hSize = MeasureSpec.getSize(heightMeasureSpec);
156 | 
157 |         int wMode = MeasureSpec.getMode(widthMeasureSpec);
158 |         int hMode = MeasureSpec.getMode(heightMeasureSpec);
159 | 
160 |         switch (wMode) {
161 |             case MeasureSpec.EXACTLY:
162 |                 // NOP
163 |                 break;
164 | 
165 |             case MeasureSpec.AT_MOST:
166 |             case MeasureSpec.UNSPECIFIED:
167 |                 wSize = 0;
168 |                 break;
169 |         }
170 | 
171 |         switch (hMode) {
172 |             case MeasureSpec.EXACTLY:
173 |                 // NOP
174 |                 break;
175 | 
176 |             case MeasureSpec.AT_MOST:
177 |             case MeasureSpec.UNSPECIFIED:
178 |                 hSize = 0;
179 |                 break;
180 |         }
181 | 
182 |         super.onMeasure(
183 |                 MeasureSpec.makeMeasureSpec(wSize, wMode),
184 |                 MeasureSpec.makeMeasureSpec(hSize, hMode));
185 |     }
186 | 
187 |     @Override
188 |     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
189 |         int parentWidth  = (right - left);
190 |         int parentHeight = (bottom - top);
191 | 
192 |         mShadow.setParameter(mZDepthParam,
193 |                 mZDepthPaddingLeft,
194 |                 mZDepthPaddingTop,
195 |                 parentWidth  - mZDepthPaddingRight,
196 |                 parentHeight - mZDepthPaddingBottom);
197 |     }
198 | 
199 |     @Override
200 |     protected void onDraw(Canvas canvas) {
201 |         super.onDraw(canvas);
202 |         mShadow.onDraw(canvas);
203 |     }
204 | 
205 |     protected void changeZDepth(ZDepth zDepth) {
206 | 
207 |         int   newAlphaTopShadow      = zDepth.getAlphaTopShadow();
208 |         int   newAlphaBottomShadow   = zDepth.getAlphaBottomShadow();
209 |         float newOffsetYTopShadow    = zDepth.getOffsetYTopShadowPx(getContext());
210 |         float newOffsetYBottomShadow = zDepth.getOffsetYBottomShadowPx(getContext());
211 |         float newBlurTopShadow       = zDepth.getBlurTopShadowPx(getContext());
212 |         float newBlurBottomShadow    = zDepth.getBlurBottomShadowPx(getContext());
213 | 
214 |         if (!mZDepthDoAnimation) {
215 |             mZDepthParam.mAlphaTopShadow        = newAlphaTopShadow;
216 |             mZDepthParam.mAlphaBottomShadow     = newAlphaBottomShadow;
217 |             mZDepthParam.mOffsetYTopShadowPx    = newOffsetYTopShadow;
218 |             mZDepthParam.mOffsetYBottomShadowPx = newOffsetYBottomShadow;
219 |             mZDepthParam.mBlurTopShadowPx       = newBlurTopShadow;
220 |             mZDepthParam.mBlurBottomShadowPx    = newBlurBottomShadow;
221 | 
222 |             mShadow.setParameter(mZDepthParam,
223 |                     mZDepthPaddingLeft,
224 |                     mZDepthPaddingTop,
225 |                     getWidth() - mZDepthPaddingRight,
226 |                     getHeight() - mZDepthPaddingBottom);
227 |             invalidate();
228 |             return;
229 |         }
230 | 
231 |         int   nowAlphaTopShadow      = mZDepthParam.mAlphaTopShadow;
232 |         int   nowAlphaBottomShadow   = mZDepthParam.mAlphaBottomShadow;
233 |         float nowOffsetYTopShadow    = mZDepthParam.mOffsetYTopShadowPx;
234 |         float nowOffsetYBottomShadow = mZDepthParam.mOffsetYBottomShadowPx;
235 |         float nowBlurTopShadow       = mZDepthParam.mBlurTopShadowPx;
236 |         float nowBlurBottomShadow    = mZDepthParam.mBlurBottomShadowPx;
237 | 
238 |         PropertyValuesHolder alphaTopShadowHolder     = PropertyValuesHolder.ofInt(ANIM_PROPERTY_ALPHA_TOP_SHADOW,
239 |                 nowAlphaTopShadow,
240 |                 newAlphaTopShadow);
241 |         PropertyValuesHolder alphaBottomShadowHolder  = PropertyValuesHolder.ofInt(ANIM_PROPERTY_ALPHA_BOTTOM_SHADOW,
242 |                 nowAlphaBottomShadow,
243 |                 newAlphaBottomShadow);
244 |         PropertyValuesHolder offsetTopShadowHolder    = PropertyValuesHolder.ofFloat(ANIM_PROPERTY_OFFSET_TOP_SHADOW,
245 |                 nowOffsetYTopShadow,
246 |                 newOffsetYTopShadow);
247 |         PropertyValuesHolder offsetBottomShadowHolder = PropertyValuesHolder.ofFloat(ANIM_PROPERTY_OFFSET_BOTTOM_SHADOW,
248 |                 nowOffsetYBottomShadow,
249 |                 newOffsetYBottomShadow);
250 |         PropertyValuesHolder blurTopShadowHolder      = PropertyValuesHolder.ofFloat(ANIM_PROPERTY_BLUR_TOP_SHADOW,
251 |                 nowBlurTopShadow,
252 |                 newBlurTopShadow);
253 |         PropertyValuesHolder blurBottomShadowHolder   = PropertyValuesHolder.ofFloat(ANIM_PROPERTY_BLUR_BOTTOM_SHADOW,
254 |                 nowBlurBottomShadow,
255 |                 newBlurBottomShadow);
256 | 
257 |         ValueAnimator anim = ValueAnimator
258 |                 .ofPropertyValuesHolder(
259 |                         alphaTopShadowHolder,
260 |                         alphaBottomShadowHolder,
261 |                         offsetTopShadowHolder,
262 |                         offsetBottomShadowHolder,
263 |                         blurTopShadowHolder,
264 |                         blurBottomShadowHolder);
265 |         anim.setDuration(mZDepthAnimDuration);
266 |         anim.setInterpolator(new LinearInterpolator());
267 |         anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
268 |             @Override
269 |             public void onAnimationUpdate(ValueAnimator animation) {
270 |                 int   alphaTopShadow     = (Integer) animation.getAnimatedValue(ANIM_PROPERTY_ALPHA_TOP_SHADOW);
271 |                 int   alphaBottomShadow  = (Integer) animation.getAnimatedValue(ANIM_PROPERTY_ALPHA_BOTTOM_SHADOW);
272 |                 float offsetTopShadow    = (Float) animation.getAnimatedValue(ANIM_PROPERTY_OFFSET_TOP_SHADOW);
273 |                 float offsetBottomShadow = (Float) animation.getAnimatedValue(ANIM_PROPERTY_OFFSET_BOTTOM_SHADOW);
274 |                 float blurTopShadow      = (Float) animation.getAnimatedValue(ANIM_PROPERTY_BLUR_TOP_SHADOW);
275 |                 float blurBottomShadow   = (Float) animation.getAnimatedValue(ANIM_PROPERTY_BLUR_BOTTOM_SHADOW);
276 | 
277 |                 mZDepthParam.mAlphaTopShadow = alphaTopShadow;
278 |                 mZDepthParam.mAlphaBottomShadow = alphaBottomShadow;
279 |                 mZDepthParam.mOffsetYTopShadowPx = offsetTopShadow;
280 |                 mZDepthParam.mOffsetYBottomShadowPx = offsetBottomShadow;
281 |                 mZDepthParam.mBlurTopShadowPx = blurTopShadow;
282 |                 mZDepthParam.mBlurBottomShadowPx = blurBottomShadow;
283 | 
284 |                 mShadow.setParameter(mZDepthParam,
285 |                         mZDepthPaddingLeft,
286 |                         mZDepthPaddingTop,
287 |                         getWidth() - mZDepthPaddingRight,
288 |                         getHeight() - mZDepthPaddingBottom);
289 | 
290 |                 invalidate();
291 |              }
292 |          });
293 |         anim.start();
294 |     }
295 | }
296 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/java/app/mosn/zdepthshadowlayout/ZDepth.java:
--------------------------------------------------------------------------------
  1 | package app.mosn.zdepthshadowlayout;
  2 | 
  3 | import android.content.Context;
  4 | 
  5 | import app.mosn.zdepthshadowlayout.utils.DisplayUtils;
  6 | 
  7 | public enum ZDepth {
  8 | 
  9 |     Depth0( // TODO
 10 |             0,
 11 |             0,
 12 |             0,
 13 |             0,
 14 |             0,
 15 |             0
 16 |     ),
 17 | 
 18 |     Depth1(
 19 |             30, // alpha to black
 20 |             61, // alpha to black
 21 |             1.0f, // dp
 22 |             1.0f, // dp
 23 |             1.5f, // dp
 24 |             1.0f  // dp
 25 |     ),
 26 |     Depth2(
 27 |             40,
 28 |             58,
 29 |             3.0f,
 30 |             3.0f,
 31 |             3.0f,
 32 |             3.0f
 33 |     ),
 34 |     Depth3(
 35 |             48,
 36 |             58,
 37 |             10.0f,
 38 |             6.0f,
 39 |             10.0f,
 40 |             3.0f
 41 |     ),
 42 |     Depth4(
 43 |             64,
 44 |             56,
 45 |             14.0f,
 46 |             10.0f,
 47 |             14.0f,
 48 |             5.0f
 49 |     ),
 50 |     Depth5(
 51 |             76,
 52 |             56,
 53 |             19.0f,
 54 |             15.0f,
 55 |             19.0f,
 56 |             6.0f
 57 |     );
 58 | 
 59 |     public final int mAlphaTopShadow; // alpha to black
 60 |     public final int mAlphaBottomShadow; // alpha to black
 61 | 
 62 |     public final float mOffsetYTopShadow; // dp
 63 |     public final float mOffsetYBottomShadow; // dp
 64 | 
 65 |     public final float mBlurTopShadow; // dp
 66 |     public final float mBlurBottomShadow; // dp
 67 | 
 68 |     private ZDepth(int alphaTopShadow, int alphaBottomShadow, float offsetYTopShadow, float offsetYBottomShadow, float blurTopShadow, float blurBottomShadow) {
 69 |         mAlphaTopShadow = alphaTopShadow;
 70 |         mAlphaBottomShadow = alphaBottomShadow;
 71 |         mOffsetYTopShadow = offsetYTopShadow;
 72 |         mOffsetYBottomShadow = offsetYBottomShadow;
 73 |         mBlurTopShadow = blurTopShadow;
 74 |         mBlurBottomShadow = blurBottomShadow;
 75 |     }
 76 | 
 77 |     public int getAlphaTopShadow() {
 78 |         return mAlphaTopShadow;
 79 |     }
 80 | 
 81 |     public int getAlphaBottomShadow() {
 82 |         return mAlphaBottomShadow;
 83 |     }
 84 | 
 85 |     public float getOffsetYTopShadowPx(Context context) {
 86 |         return DisplayUtils.convertDpToPx(context, mOffsetYTopShadow);
 87 |     }
 88 | 
 89 |     public float getOffsetYBottomShadowPx(Context context) {
 90 |         return DisplayUtils.convertDpToPx(context, mOffsetYBottomShadow);
 91 |     }
 92 | 
 93 |     public float getBlurTopShadowPx(Context context) {
 94 |         return DisplayUtils.convertDpToPx(context, mBlurTopShadow);
 95 |     }
 96 | 
 97 |     public float getBlurBottomShadowPx(Context context) {
 98 |         return DisplayUtils.convertDpToPx(context, mBlurBottomShadow);
 99 |     }
100 | }
101 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/java/app/mosn/zdepthshadowlayout/ZDepthParam.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowlayout;
 2 | 
 3 | import android.content.Context;
 4 | import android.graphics.Color;
 5 | 
 6 | 
 7 | public class ZDepthParam {
 8 | 
 9 |     public int mAlphaTopShadow; // alpha to black
10 |     public int mAlphaBottomShadow; // alpha to black
11 | 
12 |     public float mOffsetYTopShadowPx; // px
13 |     public float mOffsetYBottomShadowPx; // px
14 | 
15 |     public float mBlurTopShadowPx; // px
16 |     public float mBlurBottomShadowPx; // px
17 | 
18 |     public void initZDepth(Context context, ZDepth zDepth) {
19 |         mAlphaTopShadow = zDepth.getAlphaTopShadow();
20 |         mAlphaBottomShadow = zDepth.getAlphaBottomShadow();
21 |         mOffsetYTopShadowPx = zDepth.getOffsetYTopShadowPx(context);
22 |         mOffsetYBottomShadowPx = zDepth.getOffsetYBottomShadowPx(context);
23 |         mBlurTopShadowPx = zDepth.getBlurTopShadowPx(context);
24 |         mBlurBottomShadowPx = zDepth.getBlurBottomShadowPx(context);
25 |     }
26 | 
27 |     public int getColorTopShadow() {
28 |         return Color.argb(mAlphaTopShadow, 0, 0, 0);
29 |     }
30 | 
31 |     public int getColorBottomShadow() {
32 |         return Color.argb(mAlphaBottomShadow, 0, 0, 0);
33 |     }
34 | }
35 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/java/app/mosn/zdepthshadowlayout/ZDepthShadowLayout.java:
--------------------------------------------------------------------------------
  1 | package app.mosn.zdepthshadowlayout;
  2 | 
  3 | import android.content.Context;
  4 | import android.content.res.TypedArray;
  5 | import android.util.AttributeSet;
  6 | import android.util.Log;
  7 | import android.view.View;
  8 | import android.widget.FrameLayout;
  9 | 
 10 | 
 11 | public class ZDepthShadowLayout extends FrameLayout {
 12 |     public static final String TAG = "ZDepthShadowLayout";
 13 | 
 14 |     protected static final int DEFAULT_ATTR_SHAPE = 0;
 15 |     protected static final int DEFAULT_ATTR_ZDEPTH = 1;
 16 |     protected static final int DEFAULT_ATTR_ZDEPTH_PADDING = 5;
 17 |     protected static final int DEFAULT_ATTR_ZDEPTH_ANIM_DURATION = 150;
 18 |     protected static final boolean DEFAULT_ATTR_ZDEPTH_DO_ANIMATION = true;
 19 | 
 20 |     protected static final int SHAPE_RECT = 0;
 21 |     protected static final int SHAPE_OVAL = 1;
 22 | 
 23 |     protected ShadowView mShadowView;
 24 | 
 25 |     protected int mAttrShape;
 26 |     protected int mAttrZDepth;
 27 |     protected int mAttrZDepthPaddingLeft;
 28 |     protected int mAttrZDepthPaddingTop;
 29 |     protected int mAttrZDepthPaddingRight;
 30 |     protected int mAttrZDepthPaddingBottom;
 31 |     protected long mAttrZDepthAnimDuration;
 32 |     protected boolean mAttrZDepthDoAnimation;
 33 | 
 34 |     public ZDepthShadowLayout(Context context) {
 35 |         this(context, null);
 36 |     }
 37 | 
 38 |     public ZDepthShadowLayout(Context context, AttributeSet attrs) {
 39 |         this(context, attrs, 0);
 40 |     }
 41 | 
 42 |     public ZDepthShadowLayout(Context context, AttributeSet attrs, int defStyle) {
 43 |         super(context, attrs, defStyle);
 44 |         init(attrs, defStyle);
 45 |     }
 46 | 
 47 |     protected void init(AttributeSet attrs, int defStyle) {
 48 |         setClipToPadding(false);
 49 | 
 50 |         final TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ZDepthShadowLayout, defStyle, 0);
 51 |         mAttrShape = typedArray.getInt(R.styleable.ZDepthShadowLayout_z_depth_shape, DEFAULT_ATTR_SHAPE);
 52 |         mAttrZDepth = typedArray.getInt(R.styleable.ZDepthShadowLayout_z_depth, DEFAULT_ATTR_ZDEPTH);
 53 |         mAttrZDepthAnimDuration = typedArray.getInt(R.styleable.ZDepthShadowLayout_z_depth_animDuration, DEFAULT_ATTR_ZDEPTH_ANIM_DURATION);
 54 |         mAttrZDepthDoAnimation = typedArray.getBoolean(R.styleable.ZDepthShadowLayout_z_depth_doAnim, DEFAULT_ATTR_ZDEPTH_DO_ANIMATION);
 55 | 
 56 |         int attrZDepthPadding = typedArray.getInt(R.styleable.ZDepthShadowLayout_z_depth_padding, -1);
 57 |         int attrZDepthPaddingLeft = typedArray.getInt(R.styleable.ZDepthShadowLayout_z_depth_paddingLeft, -1);
 58 |         int attrZDepthPaddingTop = typedArray.getInt(R.styleable.ZDepthShadowLayout_z_depth_paddingTop, -1);
 59 |         int attrZDepthPaddingRight = typedArray.getInt(R.styleable.ZDepthShadowLayout_z_depth_paddingRight, -1);
 60 |         int attrZDepthPaddingBottom = typedArray.getInt(R.styleable.ZDepthShadowLayout_z_depth_paddingBottom, -1);
 61 | 
 62 |         if (attrZDepthPadding > -1) {
 63 |             mAttrZDepthPaddingLeft   = attrZDepthPadding;
 64 |             mAttrZDepthPaddingTop    = attrZDepthPadding;
 65 |             mAttrZDepthPaddingRight  = attrZDepthPadding;
 66 |             mAttrZDepthPaddingBottom = attrZDepthPadding;
 67 |         } else {
 68 |             mAttrZDepthPaddingLeft   = attrZDepthPaddingLeft   > -1 ? attrZDepthPaddingLeft   : DEFAULT_ATTR_ZDEPTH_PADDING;
 69 |             mAttrZDepthPaddingTop    = attrZDepthPaddingTop    > -1 ? attrZDepthPaddingTop    : DEFAULT_ATTR_ZDEPTH_PADDING;
 70 |             mAttrZDepthPaddingRight  = attrZDepthPaddingRight  > -1 ? attrZDepthPaddingRight  : DEFAULT_ATTR_ZDEPTH_PADDING;
 71 |             mAttrZDepthPaddingBottom = attrZDepthPaddingBottom > -1 ? attrZDepthPaddingBottom : DEFAULT_ATTR_ZDEPTH_PADDING;
 72 |         }
 73 | 
 74 |         typedArray.recycle();
 75 |     }
 76 | 
 77 |     @Override
 78 |     protected void onAttachedToWindow() {
 79 |         super.onAttachedToWindow();
 80 | 
 81 |         mShadowView = new ShadowView(getContext());
 82 |         mShadowView.setShape(mAttrShape);
 83 |         mShadowView.setZDepth(mAttrZDepth);
 84 |         mShadowView.setZDepthPaddingLeft(mAttrZDepthPaddingLeft);
 85 |         mShadowView.setZDepthPaddingTop(mAttrZDepthPaddingTop);
 86 |         mShadowView.setZDepthPaddingRight(mAttrZDepthPaddingRight);
 87 |         mShadowView.setZDepthPaddingBottom(mAttrZDepthPaddingBottom);
 88 |         mShadowView.setZDepthAnimDuration(mAttrZDepthAnimDuration);
 89 |         mShadowView.setZDepthDoAnimation(mAttrZDepthDoAnimation);
 90 |         addView(mShadowView, 0);
 91 | 
 92 |         int paddingLeft = mShadowView.getZDepthPaddingLeft();
 93 |         int paddingTop = mShadowView.getZDepthPaddingTop();
 94 |         int paddingRight = mShadowView.getZDepthPaddingRight();
 95 |         int paddingBottom = mShadowView.getZDepthPaddingBottom();
 96 |         setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
 97 |     }
 98 | 
 99 |     @Override
100 |     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
101 |         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
102 | 
103 |         final int childCount = getChildCount();
104 | 
105 |         int maxChildViewWidth = 0;
106 |         int maxChildViewHeight = 0;
107 | 
108 |         for (int i = 0; i < childCount; i++) {
109 |             View child = getChildAt(i);
110 |             if (maxChildViewWidth  < child.getMeasuredWidth())  maxChildViewWidth  = child.getMeasuredWidth();
111 |             if (maxChildViewHeight < child.getMeasuredHeight()) maxChildViewHeight = child.getMeasuredHeight();
112 |         }
113 | 
114 |         // その他の View のうち最も大きいサイズに padding を足して measure を呼び出す
115 |         int paddingLeft = mShadowView.getZDepthPaddingLeft();
116 |         int paddingTop = mShadowView.getZDepthPaddingTop();
117 |         int paddingRight = mShadowView.getZDepthPaddingRight();
118 |         int paddingBottom = mShadowView.getZDepthPaddingBottom();
119 |         maxChildViewWidth  += paddingLeft + paddingRight; // 左右の padding を加算する
120 |         maxChildViewHeight += paddingTop + paddingBottom; // 上下の padding を加算する
121 |         mShadowView.measure(
122 |                 MeasureSpec.makeMeasureSpec(maxChildViewWidth,  MeasureSpec.EXACTLY),
123 |                 MeasureSpec.makeMeasureSpec(maxChildViewHeight, MeasureSpec.EXACTLY)
124 |         );
125 |     }
126 | 
127 |     @Override
128 |     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
129 |         super.onLayout(changed, left, top, right, bottom);
130 | 
131 |         int width  = right - left;
132 |         int height = bottom - top;
133 |         mShadowView.layout(0, 0, width, height);
134 |     }
135 | 
136 |     public int getWidthExceptShadow() {
137 |         return getWidth() - getPaddingLeft() - getPaddingRight();
138 |     }
139 | 
140 |     public int getHeightExceptShadow() {
141 |         return getHeight() - getPaddingTop() - getPaddingBottom();
142 |     }
143 | 
144 |     public void changeZDepth(ZDepth zDepth) {
145 |         mShadowView.changeZDepth(zDepth);
146 |     }
147 | }
148 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/java/app/mosn/zdepthshadowlayout/shadow/Shadow.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowlayout.shadow;
 2 | 
 3 | import android.graphics.Canvas;
 4 | 
 5 | import app.mosn.zdepthshadowlayout.ZDepthParam;
 6 | 
 7 | 
 8 | public interface Shadow {
 9 |     public void setParameter(ZDepthParam parameter, int left, int top, int right, int bottom);
10 |     public void onDraw(Canvas canvas);
11 | }
12 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/java/app/mosn/zdepthshadowlayout/shadow/ShadowOval.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowlayout.shadow;
 2 | 
 3 | import android.graphics.BlurMaskFilter;
 4 | import android.graphics.Canvas;
 5 | import android.graphics.Color;
 6 | import android.graphics.RectF;
 7 | import android.graphics.drawable.ShapeDrawable;
 8 | import android.graphics.drawable.shapes.OvalShape;
 9 | 
10 | import app.mosn.zdepthshadowlayout.ZDepthParam;
11 | 
12 | public class ShadowOval implements Shadow {
13 | 
14 |     private ShapeDrawable mTopShadow;
15 |     private ShapeDrawable mBottomShadow;
16 | 
17 |     private RectF mRectTopShadow;
18 |     private RectF mRectBottomShadow;
19 | 
20 |     public ShadowOval() {
21 |         mRectTopShadow = new RectF();
22 |         mRectBottomShadow = new RectF();
23 |         mTopShadow = new ShapeDrawable(new OvalShape());
24 |         mBottomShadow = new ShapeDrawable(new OvalShape());
25 |     }
26 | 
27 |     @Override
28 |     public void setParameter(ZDepthParam param, int left, int top, int right, int bottom) {
29 |         mRectTopShadow.left   = left;
30 |         mRectTopShadow.top    = top    + param.mOffsetYTopShadowPx;
31 |         mRectTopShadow.right  = right;
32 |         mRectTopShadow.bottom = bottom + param.mOffsetYTopShadowPx;
33 | 
34 |         mRectBottomShadow.left   = left;
35 |         mRectBottomShadow.top    = top    + param.mOffsetYBottomShadowPx;
36 |         mRectBottomShadow.right  = right;
37 |         mRectBottomShadow.bottom = bottom + param.mOffsetYBottomShadowPx;
38 | 
39 |         mTopShadow.getPaint().setColor(Color.argb(param.mAlphaTopShadow, 0, 0, 0));
40 |         if (0 < param.mBlurTopShadowPx) {
41 |             mTopShadow.getPaint().setMaskFilter(new BlurMaskFilter(param.mBlurTopShadowPx, BlurMaskFilter.Blur.NORMAL));
42 |         } else {
43 |             mTopShadow.getPaint().setMaskFilter(null);
44 |         }
45 | 
46 |         mBottomShadow.getPaint().setColor(Color.argb(param.mAlphaBottomShadow, 0, 0, 0));
47 |         if (0 < param.mBlurBottomShadowPx) {
48 |             mBottomShadow.getPaint().setMaskFilter(new BlurMaskFilter(param.mBlurBottomShadowPx, BlurMaskFilter.Blur.NORMAL));
49 |         } else {
50 |             mBottomShadow.getPaint().setMaskFilter(null);
51 |         }
52 |     }
53 | 
54 |     @Override
55 |     public void onDraw(Canvas canvas) {
56 |         canvas.drawOval(mRectBottomShadow, mBottomShadow.getPaint());
57 |         canvas.drawOval(mRectTopShadow, mTopShadow.getPaint());
58 |     }
59 | }
60 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/java/app/mosn/zdepthshadowlayout/shadow/ShadowRect.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowlayout.shadow;
 2 | 
 3 | import android.graphics.BlurMaskFilter;
 4 | import android.graphics.Canvas;
 5 | import android.graphics.Color;
 6 | import android.graphics.Rect;
 7 | import android.graphics.drawable.ShapeDrawable;
 8 | import android.graphics.drawable.shapes.RectShape;
 9 | 
10 | import app.mosn.zdepthshadowlayout.ZDepthParam;
11 | 
12 | public class ShadowRect implements Shadow {
13 | 
14 |     private ShapeDrawable mTopShadow;
15 |     private ShapeDrawable mBottomShadow;
16 | 
17 |     private Rect mRectTopShadow;
18 |     private Rect mRectBottomShadow;
19 | 
20 |     public ShadowRect() {
21 |         mRectTopShadow = new Rect();
22 |         mRectBottomShadow = new Rect();
23 |         mTopShadow = new ShapeDrawable(new RectShape());
24 |         mBottomShadow = new ShapeDrawable(new RectShape());
25 |     }
26 | 
27 |     @Override
28 |     public void setParameter(ZDepthParam param, int left, int top, int right, int bottom) {
29 |         mRectTopShadow.left   = left;
30 |         mRectTopShadow.top    = (int) (top    + param.mOffsetYTopShadowPx);
31 |         mRectTopShadow.right  = right;
32 |         mRectTopShadow.bottom = (int) (bottom + param.mOffsetYTopShadowPx);
33 | 
34 |         mRectBottomShadow.left   = left;
35 |         mRectBottomShadow.top    = (int) (top    + param.mOffsetYBottomShadowPx);
36 |         mRectBottomShadow.right  = right;
37 |         mRectBottomShadow.bottom = (int) (bottom + param.mOffsetYBottomShadowPx);
38 | 
39 |         mTopShadow.getPaint().setColor(Color.argb(param.mAlphaTopShadow, 0, 0, 0));
40 |         if (0 < param.mBlurTopShadowPx) {
41 |             mTopShadow.getPaint().setMaskFilter(new BlurMaskFilter(param.mBlurTopShadowPx, BlurMaskFilter.Blur.NORMAL));
42 |         } else {
43 |             mTopShadow.getPaint().setMaskFilter(null);
44 |         }
45 | 
46 |         mBottomShadow.getPaint().setColor(Color.argb(param.mAlphaBottomShadow, 0, 0, 0));
47 |         if (0 < param.mBlurBottomShadowPx) {
48 |             mBottomShadow.getPaint().setMaskFilter(new BlurMaskFilter(param.mBlurBottomShadowPx, BlurMaskFilter.Blur.NORMAL));
49 |         } else {
50 |             mBottomShadow.getPaint().setMaskFilter(null);
51 |         }
52 |     }
53 | 
54 |     @Override
55 |     public void onDraw(Canvas canvas) {
56 |         canvas.drawRect(mRectBottomShadow, mBottomShadow.getPaint());
57 |         canvas.drawRect(mRectTopShadow, mTopShadow.getPaint());
58 |     }
59 | }
60 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/java/app/mosn/zdepthshadowlayout/utils/DisplayUtils.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowlayout.utils;
 2 | 
 3 | import android.content.Context;
 4 | 
 5 | public class DisplayUtils {
 6 | 
 7 |     public static int convertDpToPx(Context context, float dp) {
 8 |         float scale = context.getResources().getDisplayMetrics().density;
 9 |         return (int) (dp * scale + 0.5f);
10 |     }
11 | }
12 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |     
 4 |         
 5 |             
 6 |             
 7 |             
 8 |             
 9 |             
10 |             
11 |         
12 |         
13 |             
14 |             
15 |         
16 |         
17 |             
18 |             
19 |             
20 |             
21 |             
22 |             
23 |         
24 |         
25 |             
26 |             
27 |             
28 |             
29 |             
30 |             
31 |         
32 |         
33 |             
34 |             
35 |             
36 |             
37 |             
38 |             
39 |         
40 |         
41 |             
42 |             
43 |             
44 |             
45 |             
46 |             
47 |         
48 |         
49 |             
50 |             
51 |             
52 |             
53 |             
54 |             
55 |         
56 |         
57 |         
58 |     
59 | 
--------------------------------------------------------------------------------
/ZDepthShadowLayout/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | 
2 |     ZDepthShadow
3 | 
4 | 
--------------------------------------------------------------------------------
/blobs/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/blobs/demo.gif
--------------------------------------------------------------------------------
/blobs/screen_capture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/blobs/screen_capture.png
--------------------------------------------------------------------------------
/blobs/shadow_zdepth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/blobs/shadow_zdepth.png
--------------------------------------------------------------------------------
/blobs/zdepthshadow_layout_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/blobs/zdepthshadow_layout_1.png
--------------------------------------------------------------------------------
/blobs/zdepthshadow_layout_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/blobs/zdepthshadow_layout_2.png
--------------------------------------------------------------------------------
/blobs/zdepthshadow_zdepth_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/blobs/zdepthshadow_zdepth_5.png
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
 2 | 
 3 | buildscript {
 4 |     repositories {
 5 |         jcenter()
 6 |     }
 7 |     dependencies {
 8 |         classpath 'com.android.tools.build:gradle:1.1.0'
 9 |         classpath 'com.github.dcendents:android-maven-plugin:1.2'
10 | 
11 |         // NOTE: Do not place your application dependencies here; they belong
12 |         // in the individual module build.gradle files
13 |     }
14 | }
15 | 
16 | allprojects {
17 |     repositories {
18 |         jcenter()
19 |     }
20 | }
21 | 
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
 1 | # Project-wide Gradle settings.
 2 | 
 3 | # IDE (e.g. Android Studio) users:
 4 | # Gradle settings configured through the IDE *will override*
 5 | # any settings specified in this file.
 6 | 
 7 | # For more details on how to configure your build environment visit
 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
 9 | 
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 | 
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Nov 27 20:25:34 JST 2014
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
7 | 
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
  1 | #!/usr/bin/env bash
  2 | 
  3 | ##############################################################################
  4 | ##
  5 | ##  Gradle start up script for UN*X
  6 | ##
  7 | ##############################################################################
  8 | 
  9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 10 | DEFAULT_JVM_OPTS=""
 11 | 
 12 | APP_NAME="Gradle"
 13 | APP_BASE_NAME=`basename "$0"`
 14 | 
 15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
 16 | MAX_FD="maximum"
 17 | 
 18 | warn ( ) {
 19 |     echo "$*"
 20 | }
 21 | 
 22 | die ( ) {
 23 |     echo
 24 |     echo "$*"
 25 |     echo
 26 |     exit 1
 27 | }
 28 | 
 29 | # OS specific support (must be 'true' or 'false').
 30 | cygwin=false
 31 | msys=false
 32 | darwin=false
 33 | case "`uname`" in
 34 |   CYGWIN* )
 35 |     cygwin=true
 36 |     ;;
 37 |   Darwin* )
 38 |     darwin=true
 39 |     ;;
 40 |   MINGW* )
 41 |     msys=true
 42 |     ;;
 43 | esac
 44 | 
 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
 46 | if $cygwin ; then
 47 |     [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
 48 | fi
 49 | 
 50 | # Attempt to set APP_HOME
 51 | # Resolve links: $0 may be a link
 52 | PRG="$0"
 53 | # Need this for relative symlinks.
 54 | while [ -h "$PRG" ] ; do
 55 |     ls=`ls -ld "$PRG"`
 56 |     link=`expr "$ls" : '.*-> \(.*\)$'`
 57 |     if expr "$link" : '/.*' > /dev/null; then
 58 |         PRG="$link"
 59 |     else
 60 |         PRG=`dirname "$PRG"`"/$link"
 61 |     fi
 62 | done
 63 | SAVED="`pwd`"
 64 | cd "`dirname \"$PRG\"`/" >&-
 65 | APP_HOME="`pwd -P`"
 66 | cd "$SAVED" >&-
 67 | 
 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 69 | 
 70 | # Determine the Java command to use to start the JVM.
 71 | if [ -n "$JAVA_HOME" ] ; then
 72 |     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
 73 |         # IBM's JDK on AIX uses strange locations for the executables
 74 |         JAVACMD="$JAVA_HOME/jre/sh/java"
 75 |     else
 76 |         JAVACMD="$JAVA_HOME/bin/java"
 77 |     fi
 78 |     if [ ! -x "$JAVACMD" ] ; then
 79 |         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
 80 | 
 81 | Please set the JAVA_HOME variable in your environment to match the
 82 | location of your Java installation."
 83 |     fi
 84 | else
 85 |     JAVACMD="java"
 86 |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 87 | 
 88 | Please set the JAVA_HOME variable in your environment to match the
 89 | location of your Java installation."
 90 | fi
 91 | 
 92 | # Increase the maximum file descriptors if we can.
 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
 94 |     MAX_FD_LIMIT=`ulimit -H -n`
 95 |     if [ $? -eq 0 ] ; then
 96 |         if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
 97 |             MAX_FD="$MAX_FD_LIMIT"
 98 |         fi
 99 |         ulimit -n $MAX_FD
100 |         if [ $? -ne 0 ] ; then
101 |             warn "Could not set maximum file descriptor limit: $MAX_FD"
102 |         fi
103 |     else
104 |         warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 |     fi
106 | fi
107 | 
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 |     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 | 
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 |     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 |     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 | 
118 |     # We build the pattern for arguments to be converted via cygpath
119 |     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 |     SEP=""
121 |     for dir in $ROOTDIRSRAW ; do
122 |         ROOTDIRS="$ROOTDIRS$SEP$dir"
123 |         SEP="|"
124 |     done
125 |     OURCYGPATTERN="(^($ROOTDIRS))"
126 |     # Add a user-defined pattern to the cygpath arguments
127 |     if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 |         OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 |     fi
130 |     # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 |     i=0
132 |     for arg in "$@" ; do
133 |         CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 |         CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
135 | 
136 |         if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
137 |             eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 |         else
139 |             eval `echo args$i`="\"$arg\""
140 |         fi
141 |         i=$((i+1))
142 |     done
143 |     case $i in
144 |         (0) set -- ;;
145 |         (1) set -- "$args0" ;;
146 |         (2) set -- "$args0" "$args1" ;;
147 |         (3) set -- "$args0" "$args1" "$args2" ;;
148 |         (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 |         (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 |         (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 |         (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 |         (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 |         (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 |     esac
155 | fi
156 | 
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 |     JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 | 
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 | 
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
 1 | @if "%DEBUG%" == "" @echo off
 2 | @rem ##########################################################################
 3 | @rem
 4 | @rem  Gradle startup script for Windows
 5 | @rem
 6 | @rem ##########################################################################
 7 | 
 8 | @rem Set local scope for the variables with windows NT shell
 9 | if "%OS%"=="Windows_NT" setlocal
10 | 
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 | 
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 | 
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 | 
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 | 
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 | 
32 | goto fail
33 | 
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 | 
38 | if exist "%JAVA_EXE%" goto init
39 | 
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 | 
46 | goto fail
47 | 
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 | 
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 | 
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 | 
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 | 
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 | 
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 | 
69 | :execute
70 | @rem Setup the command line
71 | 
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 | 
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 | 
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 | 
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 | 
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 | 
90 | :omega
91 | 
--------------------------------------------------------------------------------
/rippleeffect/.gitignore:
--------------------------------------------------------------------------------
 1 | #Android generated
 2 | bin
 3 | gen
 4 | 
 5 | #Eclipse
 6 | .project
 7 | .classpath
 8 | .settings
 9 | 
10 | #IntelliJ IDEA
11 | .idea
12 | *.iml
13 | *.ipr
14 | *.iws
15 | out
16 | 
17 | #Gradle
18 | .gradle
19 | build
20 | 
21 | #Maven
22 | target
23 | release.properties
24 | pom.xml.*
25 | project.properties
26 | 
27 | #Ant
28 | build.xml
29 | local.properties
30 | gradle.properties
31 | proguard.cfg
32 | 
33 | #OSX
34 | .DS_Store/
35 | 
36 | # Crashlytics
37 | com_crashlytics_export_strings.xml
38 | crashlytics-build.properties
39 | crashlytics.properties
--------------------------------------------------------------------------------
/rippleeffect/build.gradle:
--------------------------------------------------------------------------------
 1 | apply plugin: 'com.android.library'
 2 | 
 3 | android {
 4 |     compileSdkVersion 20
 5 |     buildToolsVersion "20.0.0"
 6 | 
 7 |     defaultConfig {
 8 | //        applicationId "com.andexert.library"
 9 |         minSdkVersion 9
10 |         targetSdkVersion 20
11 |         versionCode 6
12 |         versionName "1.2.2"
13 |     }
14 |     buildTypes {
15 |         release {
16 |             minifyEnabled false
17 |             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 |         }
19 |     }
20 | }
21 | 
22 | dependencies {
23 |     compile fileTree(dir: 'libs', include: ['*.jar'])
24 | }
25 | 
26 | //apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle'
27 | 
--------------------------------------------------------------------------------
/rippleeffect/proguard-rules.pro:
--------------------------------------------------------------------------------
 1 | # Add project specific ProGuard rules here.
 2 | # By default, the flags in this file are appended to flags specified
 3 | # in C:/Users/robin.chutaux/Documents/adt/sdk/tools/proguard/proguard-android.txt
 4 | # You can edit the include path and order by changing the proguardFiles
 5 | # directive in build.gradle.
 6 | #
 7 | # For more details, see
 8 | #   http://developer.android.com/guide/developing/tools/proguard.html
 9 | 
10 | # Add any project specific keep options here:
11 | 
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | #   public *;
17 | #}
18 | 
--------------------------------------------------------------------------------
/rippleeffect/src/androidTest/java/com/andexert/library/ApplicationTest.java:
--------------------------------------------------------------------------------
 1 | package com.andexert.library;
 2 | 
 3 | import android.app.Application;
 4 | import android.test.ApplicationTestCase;
 5 | 
 6 | /**
 7 |  * Testing Fundamentals
 8 |  */
 9 | public class ApplicationTest extends ApplicationTestCase {
10 |     public ApplicationTest() {
11 |         super(Application.class);
12 |     }
13 | }
--------------------------------------------------------------------------------
/rippleeffect/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 | 
3 | 
4 |      
5 | 
6 | 
7 | 
--------------------------------------------------------------------------------
/rippleeffect/src/main/java/com/andexert/library/RippleView.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * The MIT License (MIT)
  3 |  *
  4 |  * Copyright (c) 2014 Robin Chutaux
  5 |  *
  6 |  * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 |  * of this software and associated documentation files (the "Software"), to deal
  8 |  * in the Software without restriction, including without limitation the rights
  9 |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10 |  * copies of the Software, and to permit persons to whom the Software is
 11 |  * furnished to do so, subject to the following conditions:
 12 |  *
 13 |  * The above copyright notice and this permission notice shall be included in
 14 |  * all copies or substantial portions of the Software.
 15 |  *
 16 |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17 |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18 |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19 |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20 |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21 |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22 |  * THE SOFTWARE.
 23 |  */
 24 | 
 25 | package com.andexert.library;
 26 | 
 27 | import android.content.Context;
 28 | import android.content.res.TypedArray;
 29 | import android.graphics.Bitmap;
 30 | import android.graphics.Canvas;
 31 | import android.graphics.Paint;
 32 | import android.graphics.PorterDuff;
 33 | import android.graphics.PorterDuffXfermode;
 34 | import android.graphics.Rect;
 35 | import android.os.Handler;
 36 | import android.util.AttributeSet;
 37 | import android.view.GestureDetector;
 38 | import android.view.MotionEvent;
 39 | import android.view.View;
 40 | import android.view.ViewGroup;
 41 | import android.view.animation.Animation;
 42 | import android.view.animation.ScaleAnimation;
 43 | import android.widget.RelativeLayout;
 44 | 
 45 | /**
 46 |  * Author :    Chutaux Robin
 47 |  * Date :      10/8/2014
 48 |  */
 49 | public class RippleView extends RelativeLayout
 50 | {
 51 |     private int WIDTH;
 52 |     private int HEIGHT;
 53 |     private int FRAME_RATE = 10;
 54 |     private int DURATION = 400;
 55 |     private int PAINT_ALPHA = 90;
 56 |     private Handler canvasHandler;
 57 |     private float radiusMax = 0;
 58 |     private boolean animationRunning = false;
 59 |     private int timer = 0;
 60 |     private int timerEmpty = 0;
 61 |     private int durationEmpty = -1;
 62 |     private float x = -1;
 63 |     private float y = -1;
 64 |     private int zoomDuration;
 65 |     private float zoomScale;
 66 |     private ScaleAnimation scaleAnimation;
 67 |     private Boolean hasToZoom;
 68 |     private Boolean isCentered;
 69 |     private Integer rippleType;
 70 |     private Paint paint;
 71 |     private Bitmap originBitmap;
 72 |     private int rippleColor;
 73 |     private View childView;
 74 |     private int ripplePadding;
 75 |     private GestureDetector gestureDetector;
 76 |     private Runnable runnable = new Runnable()
 77 |     {
 78 |         @Override
 79 |         public void run()
 80 |         {
 81 |             invalidate();
 82 |         }
 83 |     };
 84 | 
 85 |     public RippleView(Context context)
 86 |     {
 87 |         super(context);
 88 |     }
 89 | 
 90 |     public RippleView(Context context, AttributeSet attrs)
 91 |     {
 92 |         super(context, attrs);
 93 |         init(context, attrs);
 94 |     }
 95 | 
 96 |     public RippleView(Context context, AttributeSet attrs, int defStyle)
 97 |     {
 98 |         super(context, attrs, defStyle);
 99 |         init(context, attrs);
100 |     }
101 | 
102 |     private void init(final Context context, final AttributeSet attrs)
103 |     {
104 |         if (isInEditMode())
105 |             return;
106 | 
107 |         final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RippleView);
108 |         rippleColor = typedArray.getColor(R.styleable.RippleView_rv_color, getResources().getColor(R.color.rippelColor));
109 |         rippleType = typedArray.getInt(R.styleable.RippleView_rv_type, 0);
110 |         hasToZoom = typedArray.getBoolean(R.styleable.RippleView_rv_zoom, false);
111 |         isCentered = typedArray.getBoolean(R.styleable.RippleView_rv_centered, false);
112 |         DURATION = typedArray.getInteger(R.styleable.RippleView_rv_rippleDuration, DURATION);
113 |         FRAME_RATE = typedArray.getInteger(R.styleable.RippleView_rv_framerate, FRAME_RATE);
114 |         PAINT_ALPHA = typedArray.getInteger(R.styleable.RippleView_rv_alpha, PAINT_ALPHA);
115 |         ripplePadding = typedArray.getDimensionPixelSize(R.styleable.RippleView_rv_ripplePadding, 0);
116 |         canvasHandler = new Handler();
117 |         zoomScale = typedArray.getFloat(R.styleable.RippleView_rv_zoomScale, 1.03f);
118 |         zoomDuration = typedArray.getInt(R.styleable.RippleView_rv_zoomDuration, 200);
119 |         paint = new Paint();
120 |         paint.setAntiAlias(true);
121 |         paint.setStyle(Paint.Style.FILL);
122 |         paint.setColor(rippleColor);
123 |         paint.setAlpha(PAINT_ALPHA);
124 |         this.setWillNotDraw(false);
125 | 
126 |         gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener()
127 |         {
128 |             @Override
129 |             public boolean onSingleTapConfirmed(MotionEvent e)
130 |             {
131 |                 return true;
132 |             }
133 | 
134 |             @Override
135 |             public boolean onSingleTapUp(MotionEvent e)
136 |             {
137 |                 return true;
138 |             }
139 |         });
140 | 
141 |         this.setDrawingCacheEnabled(true);
142 |     }
143 | 
144 |     @Override
145 |     public void addView(View child, int index, ViewGroup.LayoutParams params)
146 |     {
147 |         childView = child;
148 |         super.addView(child, index, params);
149 |     }
150 | 
151 |     @Override
152 |     public void draw(Canvas canvas)
153 |     {
154 |         super.draw(canvas);
155 |         if (animationRunning)
156 |         {
157 |             if (DURATION <= timer * FRAME_RATE)
158 |             {
159 |                 animationRunning = false;
160 |                 timer = 0;
161 |                 durationEmpty = -1;
162 |                 timerEmpty = 0;
163 |                 canvas.restore();
164 |                 invalidate();
165 |                 return;
166 |             }
167 |             else
168 |                 canvasHandler.postDelayed(runnable, FRAME_RATE);
169 | 
170 |             if (timer == 0)
171 |                 canvas.save();
172 | 
173 | 
174 |             canvas.drawCircle(x, y, (radiusMax * (((float) timer * FRAME_RATE) / DURATION)), paint);
175 | 
176 |             paint.setColor(getResources().getColor(android.R.color.holo_red_light));
177 | 
178 |             if (rippleType == 1 && originBitmap != null && (((float) timer * FRAME_RATE) / DURATION) > 0.4f)
179 |             {
180 |                 if (durationEmpty == -1)
181 |                     durationEmpty = DURATION - timer * FRAME_RATE;
182 | 
183 |                 timerEmpty++;
184 |                 final Bitmap tmpBitmap = getCircleBitmap((int) ((radiusMax) * (((float) timerEmpty * FRAME_RATE) / (durationEmpty))));
185 |                 canvas.drawBitmap(tmpBitmap, 0, 0, paint);
186 |                 tmpBitmap.recycle();
187 |             }
188 | 
189 |             paint.setColor(rippleColor);
190 | 
191 |             if (rippleType == 1)
192 |             {
193 |                 if ((((float) timer * FRAME_RATE) / DURATION) > 0.6f)
194 |                     paint.setAlpha((int) (PAINT_ALPHA - ((PAINT_ALPHA) * (((float) timerEmpty * FRAME_RATE) / (durationEmpty)))));
195 |                 else
196 |                     paint.setAlpha(PAINT_ALPHA);
197 |             }
198 |             else
199 |                 paint.setAlpha((int) (PAINT_ALPHA - ((PAINT_ALPHA) * (((float) timer * FRAME_RATE) / DURATION))));
200 | 
201 |             timer++;
202 |         }
203 |     }
204 | 
205 |     @Override
206 |     protected void onSizeChanged(int w, int h, int oldw, int oldh)
207 |     {
208 |         super.onSizeChanged(w, h, oldw, oldh);
209 |         WIDTH = w;
210 |         HEIGHT = h;
211 | 
212 |         scaleAnimation = new ScaleAnimation(1.0f, zoomScale, 1.0f, zoomScale, w / 2, h / 2);
213 |         scaleAnimation.setDuration(zoomDuration);
214 |         scaleAnimation.setRepeatMode(Animation.REVERSE);
215 |         scaleAnimation.setRepeatCount(1);
216 |     }
217 | 
218 |     @Override
219 |     public boolean onTouchEvent(MotionEvent event)
220 |     {
221 |         if (gestureDetector.onTouchEvent(event) && !animationRunning)
222 |         {
223 |             if (hasToZoom)
224 |                 this.startAnimation(scaleAnimation);
225 | 
226 |             radiusMax = Math.max(WIDTH, HEIGHT);
227 | 
228 |             if (rippleType != 2)
229 |                 radiusMax /= 2;
230 | 
231 |             radiusMax -= ripplePadding;
232 | 
233 |             if (isCentered || rippleType == 1)
234 |             {
235 |                 this.x = getMeasuredWidth() / 2;
236 |                 this.y = getMeasuredHeight() / 2;
237 |             }
238 |             else
239 |             {
240 |                 this.x = event.getX();
241 |                 this.y = event.getY();
242 |             }
243 | 
244 |             animationRunning = true;
245 | 
246 |             if (rippleType == 1 && originBitmap == null)
247 |                 originBitmap = getDrawingCache(true);
248 | 
249 |             invalidate();
250 |             this.performClick();
251 |         }
252 | 
253 |         childView.onTouchEvent(event);
254 |         return true;
255 |     }
256 | 
257 |     @Override
258 |     public boolean onInterceptTouchEvent(MotionEvent event)
259 |     {
260 |        return true;
261 |     }
262 | 
263 |     private Bitmap getCircleBitmap(final int radius) {
264 |         final Bitmap output = Bitmap.createBitmap(originBitmap.getWidth(), originBitmap.getHeight(), Bitmap.Config.ARGB_8888);
265 |         final Canvas canvas = new Canvas(output);
266 |         final Paint paint = new Paint();
267 |         final Rect rect = new Rect((int)(x - radius), (int)(y - radius), (int)(x + radius), (int)(y + radius));
268 | 
269 |         paint.setAntiAlias(true);
270 |         canvas.drawARGB(0, 0, 0, 0);
271 |         canvas.drawCircle(x, y, radius, paint);
272 | 
273 |         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
274 |         canvas.drawBitmap(originBitmap, rect, rect, paint);
275 | 
276 |         return output;
277 |     }
278 | }
279 | 
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/rippleeffect/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/rippleeffect/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/rippleeffect/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/rippleeffect/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/drawable/shape_rounded.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
25 | 
26 | 
28 |     
29 |     
30 | 
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
25 | 
26 | 
27 |     
28 |         
29 |         
30 |         
31 |         
32 |         
33 |         
34 |         
35 |             
36 |             
37 |             
38 |         
39 |         
40 |         
41 |         
42 | 
43 |     
44 | 
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
25 | 
26 | 
27 |     #FFFFFF
28 | 
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | 
2 |     library
3 | 
4 | 
--------------------------------------------------------------------------------
/rippleeffect/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
7 | 
8 | 
9 | 
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | 
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
 1 | apply plugin: 'com.android.application'
 2 | 
 3 | android {
 4 |     compileSdkVersion 21
 5 |     buildToolsVersion "21.1.2"
 6 | 
 7 |     defaultConfig {
 8 |         applicationId "app.mosn.library.zdepthshadowsample"
 9 |         minSdkVersion 15
10 |         targetSdkVersion 21
11 |         versionCode 1
12 |         versionName "1.0"
13 |     }
14 |     buildTypes {
15 |         release {
16 |             minifyEnabled false
17 |             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 |         }
19 |     }
20 | }
21 | 
22 | dependencies {
23 |     compile fileTree(dir: 'libs', include: ['*.jar'])
24 |     compile 'com.android.support:appcompat-v7:21.0.3'
25 |     compile 'com.jakewharton:butterknife:5.1.1'
26 |     compile project(':ZDepthShadowLayout')
27 |     compile project(':rippleeffect')
28 | }
29 | 
--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
 1 | # Add project specific ProGuard rules here.
 2 | # By default, the flags in this file are appended to flags specified
 3 | # in /Users/Shogo/Development/Android/SDK/SDK/tools/proguard/proguard-android.txt
 4 | # You can edit the include path and order by changing the proguardFiles
 5 | # directive in build.gradle.
 6 | #
 7 | # For more details, see
 8 | #   http://developer.android.com/guide/developing/tools/proguard.html
 9 | 
10 | # Add any project specific keep options here:
11 | 
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | #   public *;
17 | #}
18 | 
--------------------------------------------------------------------------------
/sample/sample.iml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |   
 4 |     
 5 |       
 6 |         
 7 |       
 8 |     
 9 |     
10 |       
11 |         
12 |         
13 |         
14 |         
15 |         
16 |         
17 |         
18 |         
19 |         
20 |         
21 |         
22 |         
23 |       
24 |     
25 |   
26 |   
27 |     
28 |     
29 |     
30 |     
31 |       
32 |       
33 |       
34 |       
35 |       
36 |       
37 |       
38 |       
39 |       
40 |       
41 |       
42 |       
43 |       
44 |       
45 |       
46 |       
47 |       
48 |       
49 |       
50 |       
51 |       
52 |       
53 |       
54 |       
55 |       
56 |       
57 |       
58 |       
59 |       
60 |       
61 |       
62 |       
63 |       
64 |       
65 |       
66 |       
67 |       
68 |       
69 |       
70 |       
71 |       
72 |       
73 |       
74 |       
75 |       
76 |       
77 |       
78 |       
79 |       
80 |       
81 |       
82 |       
83 |       
84 |       
85 |     
86 |     
87 |     
88 |     
89 |     
90 |     
91 |     
92 |     
93 |     
94 |   
95 | 
96 | 
97 | 
--------------------------------------------------------------------------------
/sample/src/androidTest/java/app/mosn/zdepthshadowsample/ApplicationTest.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.myapplication;
 2 | 
 3 | import android.app.Application;
 4 | import android.test.ApplicationTestCase;
 5 | 
 6 | /**
 7 |  * Testing Fundamentals
 8 |  */
 9 | public class ApplicationTest extends ApplicationTestCase {
10 |     public ApplicationTest() {
11 |         super(Application.class);
12 |     }
13 | }
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 4 | 
 5 |     
10 |         
13 |             
14 |                 
15 | 
16 |                 
17 |             
18 |         
19 |         
22 |         
23 |         
27 |         
28 |         
31 |         
32 |         
35 |         
36 |     
37 | 
38 | 
39 | 
--------------------------------------------------------------------------------
/sample/src/main/java/app/mosn/zdepthshadowsample/ChangeZDepthActivity.java:
--------------------------------------------------------------------------------
  1 | package app.mosn.zdepthshadowsample;
  2 | 
  3 | import android.os.Bundle;
  4 | import android.support.v7.app.ActionBarActivity;
  5 | import android.support.v7.widget.Toolbar;
  6 | import android.view.Menu;
  7 | import android.view.MenuItem;
  8 | 
  9 | import app.mosn.zdepthshadowlayout.ZDepth;
 10 | import app.mosn.zdepthshadowlayout.ZDepthShadowLayout;
 11 | import butterknife.ButterKnife;
 12 | import butterknife.InjectView;
 13 | import butterknife.OnClick;
 14 | 
 15 | public class ChangeZDepthActivity extends ActionBarActivity {
 16 | 
 17 |     @InjectView(R.id.toolBar)
 18 |     Toolbar mToolbar;
 19 | 
 20 |     @InjectView(R.id.zDepthShadowLayout_toolBar)
 21 |     ZDepthShadowLayout mZDepthShadowLayoutToolbar;
 22 | 
 23 |     @InjectView(R.id.zDepthShadowLayout_rect)
 24 |     ZDepthShadowLayout mZDepthShadowLayoutRect;
 25 | 
 26 |     @InjectView(R.id.zDepthShadowLayout_oval)
 27 |     ZDepthShadowLayout mZDepthShadowLayoutOval;
 28 | 
 29 |     @Override
 30 |     protected void onCreate(Bundle savedInstanceState) {
 31 |         super.onCreate(savedInstanceState);
 32 |         setContentView(R.layout.activity_change_zdepth);
 33 |         ButterKnife.inject(this);
 34 | 
 35 |         setSupportActionBar(mToolbar);
 36 |     }
 37 | 
 38 |     @OnClick(R.id.button_zDepth_0)
 39 |     protected void onClickZDepth0() {
 40 |         mZDepthShadowLayoutRect.changeZDepth(ZDepth.Depth0);
 41 |         mZDepthShadowLayoutOval.changeZDepth(ZDepth.Depth0);
 42 |         mZDepthShadowLayoutToolbar.changeZDepth(ZDepth.Depth0);
 43 |     }
 44 | 
 45 |     @OnClick(R.id.button_zDepth_1)
 46 |     protected void onClickZDepth1() {
 47 |         mZDepthShadowLayoutRect.changeZDepth(ZDepth.Depth1);
 48 |         mZDepthShadowLayoutOval.changeZDepth(ZDepth.Depth1);
 49 |         mZDepthShadowLayoutToolbar.changeZDepth(ZDepth.Depth1);
 50 |     }
 51 | 
 52 |     @OnClick(R.id.button_zDepth_2)
 53 |     protected void onClickZDepth2() {
 54 |         mZDepthShadowLayoutRect.changeZDepth(ZDepth.Depth2);
 55 |         mZDepthShadowLayoutOval.changeZDepth(ZDepth.Depth2);
 56 |         mZDepthShadowLayoutToolbar.changeZDepth(ZDepth.Depth2);
 57 |     }
 58 | 
 59 |     @OnClick(R.id.button_zDepth_3)
 60 |     protected void onClickZDepth3() {
 61 |         mZDepthShadowLayoutRect.changeZDepth(ZDepth.Depth3);
 62 |         mZDepthShadowLayoutOval.changeZDepth(ZDepth.Depth3);
 63 |         mZDepthShadowLayoutToolbar.changeZDepth(ZDepth.Depth3);
 64 |     }
 65 | 
 66 |     @OnClick(R.id.button_zDepth_4)
 67 |     protected void onClickZDepth4() {
 68 |         mZDepthShadowLayoutRect.changeZDepth(ZDepth.Depth4);
 69 |         mZDepthShadowLayoutOval.changeZDepth(ZDepth.Depth4);
 70 |         mZDepthShadowLayoutToolbar.changeZDepth(ZDepth.Depth4);
 71 |     }
 72 | 
 73 |     @OnClick(R.id.button_zDepth_5)
 74 |     protected void onClickZDepth5() {
 75 |         mZDepthShadowLayoutRect.changeZDepth(ZDepth.Depth5);
 76 |         mZDepthShadowLayoutOval.changeZDepth(ZDepth.Depth5);
 77 |         mZDepthShadowLayoutToolbar.changeZDepth(ZDepth.Depth5);
 78 |     }
 79 | 
 80 |     @Override
 81 |     public boolean onCreateOptionsMenu(Menu menu) {
 82 |         // Inflate the menu; this adds items to the action bar if it is present.
 83 |         getMenuInflater().inflate(R.menu.menu_main, menu);
 84 |         return true;
 85 |     }
 86 | 
 87 |     @Override
 88 |     public boolean onOptionsItemSelected(MenuItem item) {
 89 |         // Handle action bar item clicks here. The action bar will
 90 |         // automatically handle clicks on the Home/Up button, so long
 91 |         // as you specify a parent activity in AndroidManifest.xml.
 92 |         int id = item.getItemId();
 93 | 
 94 |         //noinspection SimplifiableIfStatement
 95 |         if (id == R.id.action_settings) {
 96 |             return true;
 97 |         }
 98 | 
 99 |         return super.onOptionsItemSelected(item);
100 |     }
101 | }
102 | 
--------------------------------------------------------------------------------
/sample/src/main/java/app/mosn/zdepthshadowsample/MainActivity.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowsample;
 2 | 
 3 | import android.content.Intent;
 4 | import android.support.v7.app.ActionBarActivity;
 5 | import android.os.Bundle;
 6 | import android.widget.ArrayAdapter;
 7 | import android.widget.ListView;
 8 | 
 9 | import butterknife.ButterKnife;
10 | import butterknife.InjectView;
11 | import butterknife.OnItemClick;
12 | 
13 | 
14 | public class MainActivity extends ActionBarActivity {
15 | 
16 |     @InjectView(R.id.listView)
17 |     ListView mListView;
18 | 
19 |     @Override
20 |     protected void onCreate(Bundle savedInstanceState) {
21 |         super.onCreate(savedInstanceState);
22 |         setContentView(R.layout.activity_main);
23 |         ButterKnife.inject(this);
24 | 
25 |         mListView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1,
26 |                 new String[]{
27 |                         "Simple ZDepthShadowLayout",
28 |                         "Change ZDepth",
29 |                         "with RippleEffect Library",
30 |                         "Sample FloatingActionMenu"
31 |                 }));
32 |     }
33 | 
34 |     @OnItemClick(R.id.listView)
35 |     protected void onItemClick(int position) {
36 |         Intent intent = null;
37 | 
38 |         switch (position) {
39 |             case 0:
40 |                 intent = new Intent(this, SimpleZDepthActivity.class);
41 |                 break;
42 | 
43 |             case 1:
44 |                 intent = new Intent(this, ChangeZDepthActivity.class);
45 |                 break;
46 | 
47 |             case 2:
48 |                 intent = new Intent(this, WithRippleEffectActivity.class);
49 |                 break;
50 | 
51 |             case 3:
52 |                 intent = new Intent(this, SampleFloatingActionMenuActivity.class);
53 |                 break;
54 | 
55 |             default:
56 |                 return;
57 |         }
58 | 
59 |         startActivity(intent);
60 |     }
61 | }
62 | 
--------------------------------------------------------------------------------
/sample/src/main/java/app/mosn/zdepthshadowsample/SampleFloatingActionMenuActivity.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowsample;
 2 | 
 3 | import android.os.Bundle;
 4 | import android.support.v7.app.ActionBarActivity;
 5 | 
 6 | public class SampleFloatingActionMenuActivity extends ActionBarActivity {
 7 | 
 8 |     @Override
 9 |     protected void onCreate(Bundle savedInstanceState) {
10 |         super.onCreate(savedInstanceState);
11 |         setContentView(R.layout.activity_floating_action_menu);
12 |     }
13 | }
14 | 
--------------------------------------------------------------------------------
/sample/src/main/java/app/mosn/zdepthshadowsample/SimpleZDepthActivity.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowsample;
 2 | 
 3 | import android.os.Bundle;
 4 | import android.support.v7.app.ActionBarActivity;
 5 | 
 6 | public class SimpleZDepthActivity extends ActionBarActivity {
 7 | 
 8 |     @Override
 9 |     protected void onCreate(Bundle savedInstanceState) {
10 |         super.onCreate(savedInstanceState);
11 |         setContentView(R.layout.activity_simple_zdepth);
12 |     }
13 | }
14 | 
--------------------------------------------------------------------------------
/sample/src/main/java/app/mosn/zdepthshadowsample/WithRippleEffectActivity.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowsample;
 2 | 
 3 | import android.os.Bundle;
 4 | import android.support.v7.app.ActionBarActivity;
 5 | 
 6 | public class WithRippleEffectActivity extends ActionBarActivity {
 7 | 
 8 |     @Override
 9 |     protected void onCreate(Bundle savedInstanceState) {
10 |         super.onCreate(savedInstanceState);
11 |         setContentView(R.layout.activity_with_ripple_effect);
12 |     }
13 | }
14 | 
--------------------------------------------------------------------------------
/sample/src/main/java/app/mosn/zdepthshadowsample/fam/FloatingActionMenu.java:
--------------------------------------------------------------------------------
  1 | package app.mosn.zdepthshadowsample.fam;
  2 | 
  3 | import android.content.Context;
  4 | import android.graphics.PointF;
  5 | import android.util.AttributeSet;
  6 | import android.view.View;
  7 | import android.view.ViewTreeObserver;
  8 | import android.view.animation.AccelerateDecelerateInterpolator;
  9 | import android.widget.FrameLayout;
 10 | 
 11 | import app.mosn.zdepthshadowlayout.ZDepth;
 12 | import app.mosn.zdepthshadowsample.R;
 13 | 
 14 | public class FloatingActionMenu extends FrameLayout {
 15 | 
 16 |     protected FloatingActionMenuToggle mToggleButton;
 17 |     protected boolean mToggle;
 18 | 
 19 |     protected FloatingActionMenuButton[] mMenuButtons;
 20 |     protected PointF[] mMenuButtonShowPoints;
 21 |     protected PointF[] mMenuButtonHidePoints;
 22 |     protected int[] mIconIds = {
 23 |             R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher
 24 |     };
 25 | 
 26 |     public FloatingActionMenu(Context context) {
 27 |         super(context);
 28 |     }
 29 | 
 30 |     public FloatingActionMenu(Context context, AttributeSet attrs) {
 31 |         super(context, attrs);
 32 |     }
 33 | 
 34 |     public FloatingActionMenu(Context context, AttributeSet attrs, int defStyleAttr) {
 35 |         super(context, attrs, defStyleAttr);
 36 |     }
 37 | 
 38 |     @Override
 39 |     protected void onAttachedToWindow() {
 40 |         super.onAttachedToWindow();
 41 | 
 42 |         // set floating action menu toggle
 43 |         mToggleButton = new FloatingActionMenuToggle(getContext());
 44 |         mToggleButton.setIconId(R.drawable.ic_launcher);
 45 |         mToggleButton.setOnClickListener(new OnClickListener() {
 46 |             @Override
 47 |             public void onClick(View v) {
 48 |                 toggle();
 49 |             }
 50 |         });
 51 |         addView(mToggleButton);
 52 | 
 53 |         // set floating action menu buttons
 54 |         mMenuButtons = new FloatingActionMenuButton[mIconIds.length];
 55 |         mMenuButtonShowPoints = new PointF[mIconIds.length];
 56 |         mMenuButtonHidePoints = new PointF[mIconIds.length];
 57 |         for (int i = 0; i < mIconIds.length; i++) {
 58 |             FloatingActionMenuButton btn = new FloatingActionMenuButton(getContext());
 59 |             btn.setIconId(mIconIds[i]);
 60 |             mMenuButtons[i] = btn;
 61 |             addView(btn, 0);
 62 |         }
 63 | 
 64 |         getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
 65 |             @Override
 66 |             public void onGlobalLayout() {
 67 |                 hidden(false);
 68 |             }
 69 |         });
 70 |     }
 71 | 
 72 |     @Override
 73 |     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
 74 |         super.onLayout(changed, left, top, right, bottom);
 75 | 
 76 |         layoutToggleButton(left, top, right, bottom);
 77 |         layoutMenuButton();
 78 |     }
 79 | 
 80 |     protected void layoutToggleButton(int left, int top, int right, int bottom) {
 81 |         int width = mToggleButton.getMeasuredWidth();
 82 |         int height = mToggleButton.getMeasuredHeight();
 83 | 
 84 |         int newLeft = right - width;
 85 |         int newRight = right;
 86 |         int newTop = bottom - height;
 87 |         int newBottom = bottom;
 88 | 
 89 |         mToggleButton.layout(newLeft, newTop, newRight, newBottom);
 90 |     }
 91 | 
 92 |     protected void layoutMenuButton() {
 93 |         final int count = mMenuButtons.length;
 94 |         final int baseMenuButtonX = (int) mToggleButton.getX();
 95 |         final int baseMenuButtonY = (int) mToggleButton.getY();
 96 | 
 97 |         final int toggleWidth = mToggleButton.getMeasuredWidth();
 98 |         final int toggleHeight = mToggleButton.getMeasuredHeight();
 99 | 
100 |         for (int i = 0; i < count; i++) {
101 |             FloatingActionMenuButton btn = mMenuButtons[i];
102 | 
103 |             final int btnWidth = btn.getMeasuredWidth();
104 |             final int btnHeight = btn.getMeasuredHeight();
105 | 
106 |             int beforeButtonsHeight = 0;
107 |             for (int j = 0; j < i; j++) {
108 |                 FloatingActionMenuButton beforeBtn = mMenuButtons[j];
109 |                 beforeButtonsHeight += beforeBtn.getMeasuredHeight();
110 |             }
111 | 
112 |             int hidePointLeft = baseMenuButtonX + Math.abs(toggleWidth - btnWidth) / 2;
113 |             int hidePointRight = hidePointLeft + btnWidth;
114 |             int hidePointTop = baseMenuButtonY + Math.abs(toggleHeight - btnHeight) / 2;
115 |             int hidePointBottom =hidePointTop + btnHeight;
116 | 
117 |             int showPointLeft = hidePointLeft;
118 |             int showPointTop = baseMenuButtonY - beforeButtonsHeight - btnHeight;
119 | 
120 |             mMenuButtonShowPoints[i] = new PointF(showPointLeft, showPointTop);
121 |             mMenuButtonHidePoints[i] = new PointF(hidePointLeft, hidePointTop);
122 | 
123 |             btn.layout(hidePointLeft, hidePointTop, hidePointRight, hidePointBottom);
124 |         }
125 |     }
126 | 
127 |     public void toggle() {
128 |         if (mToggle) {
129 |             hidden(true);
130 |         } else {
131 |             show(true);
132 |         }
133 |         mToggle = !mToggle;
134 |     }
135 | 
136 |     protected void show(boolean isAnimation) {
137 |         final int count = mMenuButtons.length;
138 |         mToggleButton.changeZDepth(ZDepth.Depth4);
139 | 
140 |         if (!isAnimation) {
141 |             for (int i = 0; i < count; i++) {
142 |                 FloatingActionMenuButton btn = mMenuButtons[i];
143 |                 btn.setAlpha(1.0f);
144 |                 btn.setX(mMenuButtonShowPoints[i].x);
145 |                 btn.setY(mMenuButtonShowPoints[i].y);
146 |             }
147 |             return;
148 |         }
149 | 
150 |         for (int i = 0; i < count; i++) {
151 |             FloatingActionMenuButton btn = mMenuButtons[i];
152 |             btn
153 |                     .animate()
154 |                     .alpha(1.0f)
155 |                     .x(mMenuButtonShowPoints[i].x)
156 |                     .y(mMenuButtonShowPoints[i].y)
157 |                     .setDuration(160 + 20 * i)
158 |                     .setInterpolator(new AccelerateDecelerateInterpolator())
159 |                     .start();
160 |         }
161 |     }
162 | 
163 |     protected void hidden(boolean isAnimation) {
164 |         final int count = mMenuButtons.length;
165 |         mToggleButton.changeZDepth(ZDepth.Depth2);
166 | 
167 |         if (!isAnimation) {
168 |             for (int i = 0; i < count; i++) {
169 |                 FloatingActionMenuButton btn = mMenuButtons[i];
170 |                 btn.setAlpha(0.0f);
171 |                 btn.setX(mMenuButtonHidePoints[i].x);
172 |                 btn.setY(mMenuButtonHidePoints[i].y);
173 |             }
174 |             return;
175 |         }
176 | 
177 |         for (int i = 0; i < count; i++) {
178 |             FloatingActionMenuButton btn = mMenuButtons[i];
179 |             btn
180 |                     .animate()
181 |                     .alpha(0.0f)
182 |                     .x(mMenuButtonHidePoints[i].x)
183 |                     .y(mMenuButtonHidePoints[i].y)
184 |                     .setDuration(160 + 20 * i)
185 |                     .setInterpolator(new AccelerateDecelerateInterpolator())
186 |                     .start();
187 |         }
188 |     }
189 | }
190 | 
--------------------------------------------------------------------------------
/sample/src/main/java/app/mosn/zdepthshadowsample/fam/FloatingActionMenuButton.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowsample.fam;
 2 | 
 3 | import android.content.Context;
 4 | 
 5 | import android.graphics.drawable.Drawable;
 6 | import android.util.AttributeSet;
 7 | import android.view.Gravity;
 8 | import android.widget.ImageView;
 9 | 
10 | import app.mosn.zdepthshadowlayout.ZDepthShadowLayout;
11 | import app.mosn.zdepthshadowlayout.utils.DisplayUtils;
12 | import app.mosn.zdepthshadowsample.R;
13 | 
14 | public class FloatingActionMenuButton extends ZDepthShadowLayout {
15 | 
16 |     protected int mIconId;
17 |     protected int mButtonSizeDp = 40;
18 |     protected int mIconSizeDp = 24;
19 | 
20 |     public FloatingActionMenuButton(Context context) {
21 |         super(context);
22 |         init(null, 0);
23 |     }
24 | 
25 |     @Override
26 |     protected void init(AttributeSet attrs, int defStyle) {
27 |         super.init(attrs, defStyle);
28 | 
29 |         mAttrShape = SHAPE_OVAL;
30 |         mAttrZDepth = 2;
31 |         mAttrZDepthPaddingLeft = 3;
32 |         mAttrZDepthPaddingTop = 3;
33 |         mAttrZDepthPaddingRight = 3;
34 |         mAttrZDepthPaddingBottom = 3;
35 |         mAttrZDepthDoAnimation = true;
36 |         mAttrZDepthAnimDuration = 150;
37 |     }
38 | 
39 |     @Override
40 |     protected void onAttachedToWindow() {
41 |         super.onAttachedToWindow();
42 | 
43 |         // set Button LayoutParams
44 |         int buttonSize = DisplayUtils.convertDpToPx(getContext(), mButtonSizeDp);
45 |         int iconSize = DisplayUtils.convertDpToPx(getContext(), mIconSizeDp);
46 | 
47 |         setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
48 | 
49 |         // set Background Circle
50 |         ImageView bgImage = new ImageView(getContext());
51 |         bgImage.setLayoutParams(new LayoutParams(buttonSize, buttonSize));
52 |         bgImage.setImageResource(R.drawable.drawable_circle);
53 |         addView(bgImage);
54 | 
55 |         // set Icon
56 |         Drawable icon = getResources().getDrawable(mIconId);
57 |         LayoutParams iconLP = new LayoutParams(iconSize, iconSize);
58 |         iconLP.gravity = Gravity.CENTER;
59 | 
60 |         ImageView imageView = new ImageView(getContext());
61 |         imageView.setLayoutParams(iconLP);
62 |         imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
63 |         imageView.setImageDrawable(icon);
64 |         addView(imageView);
65 |     }
66 | 
67 |     protected void setIconId(int iconId) {
68 |         mIconId = iconId;
69 |     }
70 | }
71 | 
--------------------------------------------------------------------------------
/sample/src/main/java/app/mosn/zdepthshadowsample/fam/FloatingActionMenuToggle.java:
--------------------------------------------------------------------------------
 1 | package app.mosn.zdepthshadowsample.fam;
 2 | 
 3 | import android.content.Context;
 4 | import android.util.AttributeSet;
 5 | 
 6 | public class FloatingActionMenuToggle extends FloatingActionMenuButton {
 7 | 
 8 |     public FloatingActionMenuToggle(Context context) {
 9 |         super(context);
10 |     }
11 | 
12 |     @Override
13 |     protected void init(AttributeSet attrs, int defStyle) {
14 |         super.init(attrs, defStyle);
15 | 
16 |         mButtonSizeDp = 56;
17 |         mAttrShape = SHAPE_OVAL;
18 |         mAttrZDepth = 2;
19 |         mAttrZDepthPaddingLeft = 4;
20 |         mAttrZDepthPaddingTop = 4;
21 |         mAttrZDepthPaddingRight = 4;
22 |         mAttrZDepthPaddingBottom = 4;
23 |         mAttrZDepthDoAnimation = true;
24 |         mAttrZDepthAnimDuration = 150;
25 |     }
26 | }
27 | 
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/sample/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/sample/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/sample/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sho5nn/ZDepthShadow/975f2cd4f405e81d17685290e32fb1aa313d6b21/sample/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable/drawable_circle.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
5 |     
6 | 
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_change_zdepth.xml:
--------------------------------------------------------------------------------
  1 | 
  2 | 
  7 | 
  8 |     
 17 | 
 18 |         
 24 | 
 25 |     
 26 | 
 27 |     
 32 | 
 33 |     
 42 | 
 43 |         
 50 | 
 51 |     
 52 | 
 53 |     
 60 | 
 61 |         
 67 | 
 68 |         
 74 | 
 75 |         
 81 | 
 82 |     
 83 |     
 84 |     
 91 | 
 92 |         
 98 | 
 99 |         
105 | 
106 |         
112 |     
113 | 
114 |     
125 | 
126 |         
132 | 
133 |     
134 | 
135 | 
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_floating_action_menu.xml:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 6 | 
 7 |     
10 |     
11 | 
12 | 
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
 1 | 
 8 | 
 9 |     
13 | 
14 | 
15 | 
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_simple_zdepth.xml:
--------------------------------------------------------------------------------
  1 | 
  2 | 
  7 | 
  8 |     
 13 | 
 14 |         
 19 | 
 20 |             
 26 | 
 27 |         
 28 | 
 29 |         
 36 | 
 37 |             
 43 | 
 44 |         
 45 | 
 46 |         
 51 | 
 52 |             
 58 | 
 59 |         
 60 | 
 61 |         
 66 | 
 67 |             
 73 | 
 74 |         
 75 | 
 76 |         
 81 | 
 82 |             
 88 | 
 89 |         
 90 | 
 91 |         
 96 | 
 97 |             
103 | 
104 |         
105 | 
106 |         
111 | 
112 |             
119 | 
120 |         
121 | 
122 |         
127 | 
128 |             
135 | 
136 |         
137 | 
138 |         
143 | 
144 |             
151 | 
152 |         
153 | 
154 |         
159 | 
160 |             
167 | 
168 |         
169 | 
170 |         
175 | 
176 |             
183 | 
184 |         
185 | 
186 |         
191 | 
192 |             
199 | 
200 |         
201 | 
202 |     
203 | 
204 | 
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_with_ripple_effect.xml:
--------------------------------------------------------------------------------
  1 | 
  2 | 
  8 | 
  9 |     
 15 | 
 16 |         
 21 | 
 22 |             
 26 | 
 27 |                 
 33 | 
 34 |             
 35 | 
 36 |         
 37 | 
 38 |         
 43 | 
 44 |             
 48 | 
 49 |                 
 55 | 
 56 |             
 57 | 
 58 |         
 59 | 
 60 |         
 65 | 
 66 |             
 70 | 
 71 |                 
 77 | 
 78 |             
 79 | 
 80 |         
 81 | 
 82 |         
 87 | 
 88 |             
 92 | 
 93 |                 
 99 | 
100 |             
101 | 
102 |         
103 | 
104 |         
109 | 
110 |             
114 | 
115 |                 
121 | 
122 |             
123 | 
124 |         
125 | 
126 |         
131 | 
132 |             
136 | 
137 |                 
143 | 
144 |             
145 | 
146 |         
147 | 
148 |         
153 | 
154 |             
159 | 
160 |                 
167 | 
168 |             
169 | 
170 |         
171 | 
172 |         
177 | 
178 |             
183 | 
184 |                 
191 | 
192 |             
193 | 
194 |         
195 | 
196 |         
201 | 
202 |             
207 | 
208 |                 
215 | 
216 |             
217 | 
218 |         
219 | 
220 |         
225 | 
226 |             
231 | 
232 |                 
239 | 
240 |             
241 | 
242 |         
243 | 
244 |         
249 | 
250 |             
255 | 
256 |                 
263 | 
264 |             
265 | 
266 |         
267 | 
268 |         
273 | 
274 |             
279 | 
280 |                 
287 | 
288 |             
289 | 
290 |         
291 | 
292 |     
293 | 
294 | 
--------------------------------------------------------------------------------
/sample/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 | 
7 | 
--------------------------------------------------------------------------------
/sample/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 | 
2 |     
5 |     64dp
6 | 
7 | 
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 | 
2 |     
3 |     16dp
4 |     16dp
5 | 
6 | 
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 |     ZDepthShadowSample
5 |     Hello world!
6 |     Settings
7 | 
8 | 
9 | 
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 | 
2 | 
3 |     
4 |     
7 | 
8 | 
9 | 
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':ZDepthShadowLayout', ':sample', ':rippleeffect'
2 | 
--------------------------------------------------------------------------------