├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── gradle.xml
├── jarRepositories.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── android_neumorphic
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── github
│ │ ├── florent37
│ │ ├── ShapeOfView.java
│ │ └── manager
│ │ │ ├── ClipManager.java
│ │ │ └── ClipPathManager.java
│ │ └── sshadkany
│ │ ├── CircleButton.java
│ │ ├── PolygonButton.java
│ │ ├── RectButton.java
│ │ ├── neo.java
│ │ ├── neoText.java
│ │ └── shapes
│ │ ├── CircleView.java
│ │ ├── PolygonView.java
│ │ └── RoundRectView.java
│ └── res
│ └── values
│ └── attrs.xml
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── github
│ │ └── sshadkany
│ │ └── android_neumorphic_test_app
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── sshadkany
│ │ │ └── android_neumorphic_test_app
│ │ │ ├── Activity3.java
│ │ │ ├── Activity5.java
│ │ │ ├── ActivityButton.java
│ │ │ ├── ActivityStyle.java
│ │ │ ├── CircleImageButtonActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── NeoTextActivity.java
│ │ │ ├── NestedButtonActivity.java
│ │ │ ├── PolygonButtonActivity.java
│ │ │ ├── RectButtonActivity.java
│ │ │ └── SecendActivity.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ ├── activity_3.xml
│ │ ├── activity_5.xml
│ │ ├── activity_button.xml
│ │ ├── activity_circle_image_button.xml
│ │ ├── activity_main.xml
│ │ ├── activity_neo_text.xml
│ │ ├── activity_nested_button.xml
│ │ ├── activity_polygon_button.xml
│ │ ├── activity_rect_button.xml
│ │ ├── activity_secend.xml
│ │ └── activity_style.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── github
│ └── sshadkany
│ └── android_neumorphic_test_app
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── screenshots
├── 1.jpg
├── 1.png
├── 2.png
├── 3.gif
├── 5.png
├── button.gif
├── button2.gif
├── canvas.png
├── circleImageButton.gif
├── neoText.png
├── nested.png
├── polygonButton.gif
├── polygon_basin.gif
├── recbutton.gif
└── shadow style.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.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 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 |
6 |
7 | # Android_neumorphic
8 | ## neumorphic (sof-ui) library for android
9 | #### based on https://github.com/florent37/ShapeOfView
10 | ---
11 | **NOTE**
12 | This is not a free library. But it has been published based on your trust. If you use this library in your software, be sure to pay the price.
13 | - If this library was very useful ... $ 99
14 | - If it only saves your time ... $ 29
15 | - My Public Address to Receive USDT (TRC20) TM23smMPwAGH3HdFnQZ1AGWKna9Cm7s32e
16 | - Pay me via Trust Wallet: https://link.trustwallet.com/send?coin=195&address=TM23smMPwAGH3HdFnQZ1AGWKna9Cm7s32e&token_id=TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
17 | ---
18 | 🔧 Easy Installation 🔧 click here ->
19 | [](https://jitpack.io/#sshadkany/Android_neumorphic)
20 | --
21 | ## ✔️some exmaples !!
22 | ### with 3 basic shape + Dark Mode
23 | |
|
|
24 | |------------|-------------|--------------|
25 | |code in [activity_secend.xml](app/src/main/res/layout/activity_secend.xml) | code in [activity_secend.xml](app/src/main/res/layout/activity_secend.xml) | code in [activity_circle_image_button.xml](app/src/main/res/layout/activity_circle_image_button.xml)
26 |
27 | ### can works nested and make amazing views !!
28 | |
|
|
29 | |-----------------|----------------|
30 | |code in [activity_main.xml](app/src/main/res/layout/activity_main.xml) |code in [activity_3.xml](app/src/main/res/layout/activity_3.xml)
31 |
32 | ### can create multiLine neomorphic text !!
33 | |
|
34 | |-----------------|
35 | |code in [activity_neo_text.xml](app/src/main/res/layout/activity_neo_text.xml) |
36 |
37 | ## how to use ?? 👞 by 👞
38 | ### 1.first install library
39 | ### 2.use this code for circle neumorphic view
40 | ```xml
41 |
50 | ```
51 | ### 3.a better example
52 | |
|
53 | |-------------|
54 | |code in [activity_style.xml](app/src/main/res/layout/activity_style.xml)|
55 |
56 | ### you can play with every paramter!!
57 | |
|
58 | |-------------|
59 | |code in [activity_5.xml](app/src/main/res/layout/aactivity_5.xml)|
60 | ```xml
61 | app:shape_circle_shadow_position_y="-30dp"
62 | app:shape_circle_shadow_position_x="40dp"
63 | app:shape_circle_dark_color="@color/colorPrimary"
64 | app:shape_circle_light_color="@color/colorAccent"
65 |
66 | app:shape_circle_borderColor="@color/colorPrimaryDark"
67 | app:shape_circle_borderWidth="4dp"
68 | ```
69 |
70 | ### how make a button ?? (easy way)
71 | |
|
72 | |----------|
73 | |code in [activity_circle_image_button.xml](app/src/main/res/layout/activity_circle_image_button.xml)|
74 | ```xml
75 |
79 |
80 |
88 |
89 |
90 | ```
91 | and in java class
92 | ```java
93 | CircleButton circle_button = findViewById(R.id.circle_image_button);
94 | circle_button.setOnClickListener(new View.OnClickListener() {
95 | @Override
96 | public void onClick(View v) {
97 | Log.i("neo", "onClick: i am clicked");
98 | }
99 | });
100 | ```
101 | ### more examples
102 | |
|
|
|
103 | |-----------------|----------------|-------------------|
104 | |code in [activity_rect_button.xml](app/src/main/res/layout/activity_rect_button.xml)|code in [activity_polygon_button.xml](app/src/main/res/layout/activity_polygon_button.xml)|code in [activity_polygon_button.xml](app/src/main/res/layout/activity_polygon_button.xml)
105 | ### how make Darkmode
106 | change this three color
107 | ```xml
108 | app:shape_roundRect_backgroundColor="#303234"
109 | app:shape_roundRect_light_color="#66494949"
110 | app:shape_roundRect_dark_color="#66000000"
111 | ```
112 |
113 | ### how make a button ?? (Advanced way)
114 | |
|
115 | |----------|
116 | |code in [activity_button.xml](app/src/main/res/layout/activity_button.xml)|
117 |
118 | ```java
119 | final neo mybtn = findViewById(R.id.my_button);
120 | ViewGroup viewGroup = findViewById(R.id.my_button);
121 | final ImageView imageview = (ImageView) viewGroup.getChildAt(0);
122 | mybtn.setOnTouchListener(new View.OnTouchListener() {
123 | @Override
124 | public boolean onTouch(View v, MotionEvent event) {
125 | // is shape Contains Point ----> for detect place of Touch is in the shape or not
126 | if (mybtn.isShapeContainsPoint(event.getX(), event.getY())) {
127 | switch (event.getAction()) {
128 | case MotionEvent.ACTION_DOWN:
129 | // PRESSED
130 | mybtn.setStyle(neo.small_inner_shadow);
131 | imageview.setScaleX(imageview.getScaleX() * 0.9f);
132 | imageview.setScaleY(imageview.getScaleY() * 0.9f);
133 | return true;
134 | case MotionEvent.ACTION_UP:
135 | case MotionEvent.ACTION_CANCEL:
136 | // RELEASED
137 | mybtn.setStyle(neo.drop_shadow);
138 | imageview.setScaleX(1);
139 | imageview.setScaleY(1);
140 | return true;
141 | }
142 | }
143 | return false;
144 | }
145 | });
146 | }
147 | ```
148 |
--------------------------------------------------------------------------------
/android_neumorphic/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/android_neumorphic/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 29
5 | buildToolsVersion "29.0.3"
6 |
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 29
10 | versionCode 1
11 | versionName "1.0"
12 |
13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
14 | consumerProguardFiles "consumer-rules.pro"
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(dir: "libs", include: ["*.jar"])
27 | implementation 'androidx.appcompat:appcompat:1.1.0'
28 |
29 | }
--------------------------------------------------------------------------------
/android_neumorphic/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/android_neumorphic/consumer-rules.pro
--------------------------------------------------------------------------------
/android_neumorphic/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/android_neumorphic/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/florent37/ShapeOfView.java:
--------------------------------------------------------------------------------
1 | package com.github.florent37;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Bitmap;
7 | import android.graphics.Canvas;
8 | import android.graphics.Color;
9 | import android.graphics.Outline;
10 | import android.graphics.Paint;
11 | import android.graphics.Path;
12 | import android.graphics.PorterDuff;
13 | import android.graphics.PorterDuffXfermode;
14 | import android.graphics.drawable.Drawable;
15 | import android.os.Build;
16 | import android.util.AttributeSet;
17 | import android.view.View;
18 | import android.view.ViewOutlineProvider;
19 | import android.widget.FrameLayout;
20 |
21 | import androidx.annotation.NonNull;
22 | import androidx.annotation.Nullable;
23 | import androidx.appcompat.content.res.AppCompatResources;
24 | import androidx.core.view.ViewCompat;
25 |
26 | import com.github.florent37.manager.ClipManager;
27 | import com.github.florent37.manager.ClipPathManager;
28 |
29 | import com.github.sshadkany.android_neumorphic.R;
30 |
31 | /**
32 | *
33 | * created by com.github.florent37
34 | *
35 | *
36 | */
37 | public class ShapeOfView extends FrameLayout {
38 |
39 | private final Paint clipPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
40 | final public Path clipPath = new Path();
41 |
42 | protected PorterDuffXfermode pdMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
43 |
44 | @Nullable
45 | protected Drawable drawable = null;
46 | private ClipManager clipManager = new ClipPathManager();
47 | private boolean requiersShapeUpdate = true;
48 | private Bitmap clipBitmap;
49 |
50 | public int background_color = Color.parseColor("#E0E5Ec"); // moved from neo
51 |
52 |
53 | final public Path rectView = new Path();
54 |
55 | public ShapeOfView(@NonNull Context context) {
56 | super(context);
57 | init(context, null);
58 | }
59 |
60 | public ShapeOfView(@NonNull Context context, @Nullable AttributeSet attrs) {
61 | super(context, attrs);
62 | init(context, attrs);
63 | }
64 |
65 | public ShapeOfView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
66 | super(context, attrs, defStyleAttr);
67 | init(context, attrs);
68 | }
69 |
70 | @Override
71 | public void setBackground(Drawable background) {
72 | //disabled here, please set a background to to this view child or use background_color instead
73 | }
74 |
75 | @Override
76 | public void setBackgroundResource(int resid) {
77 | //disabled here, please set a background to to this view child
78 | }
79 |
80 | @Override
81 | public void setBackgroundColor(int color) {
82 | background_color = color;
83 | }
84 |
85 | private void init(Context context, AttributeSet attrs) {
86 | clipPaint.setAntiAlias(true);
87 |
88 | setDrawingCacheEnabled(true);
89 |
90 | setWillNotDraw(false);
91 |
92 | clipPaint.setColor(Color.BLUE);
93 | clipPaint.setStyle(Paint.Style.FILL);
94 | clipPaint.setStrokeWidth(1);
95 | setBackgroundColor(background_color);
96 |
97 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
98 | clipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
99 | setLayerType(LAYER_TYPE_SOFTWARE, clipPaint); //Only works for software layers
100 | } else {
101 | clipPaint.setXfermode(pdMode);
102 | setLayerType(LAYER_TYPE_SOFTWARE, null); //Only works for software layers
103 | }
104 |
105 | if (attrs != null) {
106 | final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.ShapeOfView);
107 |
108 | if (attributes.hasValue(R.styleable.ShapeOfView_shape_clip_drawable)) {
109 | final int resourceId = attributes.getResourceId(R.styleable.ShapeOfView_shape_clip_drawable, -1);
110 | if (-1 != resourceId) {
111 | setDrawable(resourceId);
112 | }
113 | }
114 |
115 | attributes.recycle();
116 | }
117 | }
118 |
119 | protected float dpToPx(float dp) {
120 | return dp * this.getContext().getResources().getDisplayMetrics().density;
121 | }
122 |
123 | protected float pxToDp(float px) {
124 | return px / this.getContext().getResources().getDisplayMetrics().density;
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 | if (changed) {
131 | requiresShapeUpdate();
132 | }
133 | }
134 |
135 | private boolean requiresBitmap() {
136 | return isInEditMode() || (clipManager != null && clipManager.requiresBitmap()) || drawable != null;
137 | }
138 |
139 | public void setDrawable(Drawable drawable) {
140 | this.drawable = drawable;
141 | requiresShapeUpdate();
142 | }
143 |
144 | public void setDrawable(int redId) {
145 | setDrawable(AppCompatResources.getDrawable(getContext(), redId));
146 | }
147 |
148 | @Override
149 | protected void dispatchDraw(Canvas canvas) {
150 | super.dispatchDraw(canvas);
151 |
152 | if (requiersShapeUpdate) {
153 | calculateLayout(canvas.getWidth(), canvas.getHeight());
154 | requiersShapeUpdate = false;
155 | }
156 | if (requiresBitmap()) {
157 | clipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
158 | canvas.drawBitmap(clipBitmap, 0, 0, clipPaint);
159 | } else {
160 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
161 | Bitmap bitmap = Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
162 | Canvas mc = new Canvas(bitmap);
163 | Paint p = new Paint();
164 | p.setColor(Color.YELLOW);
165 | mc.drawPath(clipPath,p);
166 | canvas.drawBitmap(bitmap,0,0,clipPaint);
167 | // canvas.drawPath(clipPath, clipPaint);
168 | } else {
169 | canvas.drawPath(rectView, clipPaint);
170 | }
171 | }
172 |
173 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
174 | setLayerType(LAYER_TYPE_HARDWARE, null);
175 | }
176 | }
177 |
178 | private void calculateLayout(final int width, final int height) {
179 | rectView.reset();
180 | rectView.addRect(-1 * getWidth(), -1 * getHeight(), 2f * getWidth(), 2f * getHeight(), Path.Direction.CW);
181 |
182 | if (clipManager != null) {
183 | if (width > 0 && height > 0) {
184 | clipManager.setupClipLayout(width, height);
185 | clipPath.reset();
186 | clipPath.set(clipManager.createMask(width, height));
187 |
188 | if (requiresBitmap()) {
189 | if (clipBitmap != null) {
190 | clipBitmap.recycle();
191 | }
192 | clipBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
193 | final Canvas canvas = new Canvas(clipBitmap);
194 |
195 | if (drawable != null) {
196 | drawable.setBounds(0, 0, width, height);
197 | drawable.draw(canvas);
198 | } else {
199 | canvas.drawPath(clipPath, clipManager.getPaint());
200 | }
201 | }
202 |
203 | // invert the path for android P
204 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) {
205 | final boolean success = rectView.op(clipPath, Path.Op.DIFFERENCE);
206 | }else {
207 |
208 | }
209 |
210 | //this needs to be fixed for 25.4.0
211 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && ViewCompat.getElevation(this) > 0f) {
212 | try {
213 | setOutlineProvider(getOutlineProvider());
214 | } catch (Exception e) {
215 | e.printStackTrace();
216 | }
217 | }
218 | }
219 | }
220 |
221 | postInvalidate();
222 | }
223 |
224 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
225 | @Override
226 | public ViewOutlineProvider getOutlineProvider() {
227 | return new ViewOutlineProvider() {
228 | @Override
229 | public void getOutline(View view, Outline outline) {
230 | if (clipManager != null && !isInEditMode()) {
231 | final Path shadowConvexPath = clipManager.getShadowConvexPath();
232 | if (shadowConvexPath != null) {
233 | try {
234 | outline.setConvexPath(shadowConvexPath);
235 | } catch (Exception e) {
236 | e.printStackTrace();
237 | }
238 | }
239 | }
240 |
241 | }
242 | };
243 | }
244 |
245 | public void setClipPathCreator(ClipPathManager.ClipPathCreator createClipPath) {
246 | ((ClipPathManager) clipManager).setClipPathCreator(createClipPath);
247 | requiresShapeUpdate();
248 | }
249 |
250 | public void requiresShapeUpdate() {
251 | this.requiersShapeUpdate = true;
252 | postInvalidate();
253 | }
254 |
255 | }
256 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/florent37/manager/ClipManager.java:
--------------------------------------------------------------------------------
1 | package com.github.florent37.manager;
2 |
3 | import android.graphics.Paint;
4 | import android.graphics.Path;
5 |
6 | import androidx.annotation.NonNull;
7 | import androidx.annotation.Nullable;
8 |
9 | public interface ClipManager {
10 |
11 | @NonNull
12 | Path createMask(int width, int height);
13 |
14 | @Nullable
15 | Path getShadowConvexPath();
16 |
17 | void setupClipLayout(int width, int height);
18 |
19 | Paint getPaint();
20 |
21 | boolean requiresBitmap();
22 | }
23 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/florent37/manager/ClipPathManager.java:
--------------------------------------------------------------------------------
1 | package com.github.florent37.manager;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.Paint;
5 | import android.graphics.Path;
6 |
7 | import androidx.annotation.Nullable;
8 |
9 | public class ClipPathManager implements ClipManager {
10 |
11 | protected final Path path = new Path();
12 | private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
13 |
14 | private ClipPathCreator createClipPath = null;
15 |
16 | public ClipPathManager() {
17 | paint.setColor(Color.BLACK);
18 | paint.setStyle(Paint.Style.FILL);
19 | paint.setAntiAlias(true);
20 | paint.setStrokeWidth(1);
21 |
22 | }
23 |
24 | public Paint getPaint() {
25 | return paint;
26 | }
27 |
28 | @Override
29 | public boolean requiresBitmap() {
30 | return createClipPath != null && createClipPath.requiresBitmap();
31 | }
32 |
33 | @Nullable
34 | protected final Path createClipPath(int width, int height) {
35 | if (createClipPath != null) {
36 | return createClipPath.createClipPath(width, height);
37 | }
38 | return null;
39 | }
40 |
41 | public void setClipPathCreator(ClipPathCreator createClipPath) {
42 | this.createClipPath = createClipPath;
43 | }
44 |
45 | @Override
46 | public Path createMask(int width, int height) {
47 | return path;
48 | }
49 |
50 | @Nullable
51 | @Override
52 | public Path getShadowConvexPath() {
53 | return path;
54 | }
55 |
56 | @Override
57 | public void setupClipLayout(int width, int height) {
58 | path.reset();
59 | final Path clipPath = createClipPath(width, height);
60 | if (clipPath != null) {
61 | path.set(clipPath);
62 | }
63 | }
64 |
65 | public interface ClipPathCreator {
66 | Path createClipPath(int width, int height);
67 | boolean requiresBitmap();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/sshadkany/CircleButton.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import androidx.annotation.Nullable;
12 |
13 | import com.github.sshadkany.shapes.CircleView;
14 |
15 |
16 | public class CircleButton extends CircleView {
17 |
18 | private ImageView imageView;
19 | private TextView textView;
20 |
21 | public CircleButton(Context context) {
22 | super(context);
23 | }
24 |
25 | public CircleButton(Context context, @Nullable AttributeSet attrs) {
26 | super(context, attrs);
27 | }
28 |
29 | public CircleButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
30 | super(context, attrs, defStyleAttr);
31 | }
32 |
33 | private void myAddView(View child) {
34 |
35 | if (child instanceof ImageView) {
36 | imageView = (ImageView) child;
37 | } else if (child instanceof TextView) {
38 | textView = (TextView) child;
39 | }
40 | }
41 |
42 | @Override
43 | public void addView(View child, int index, ViewGroup.LayoutParams params) {
44 | super.addView(child, index, params);
45 | myAddView(child);
46 | }
47 |
48 | @Override
49 | public void addView(View child, int width, int height) {
50 | super.addView(child, width, height);
51 | myAddView(child);
52 | }
53 |
54 | @Override
55 | public void addView(View child, int index) {
56 | super.addView(child, index);
57 | myAddView(child);
58 | }
59 |
60 | @Override
61 | public void addView(View child) {
62 | super.addView(child);
63 | myAddView(child);
64 | }
65 |
66 |
67 | @Override
68 | public boolean onTouchEvent(MotionEvent event) {
69 | if (isShapeContainsPoint(event.getX(), event.getY())) {
70 | switch (event.getAction()) {
71 | case MotionEvent.ACTION_DOWN:
72 | // PRESSED
73 | setStyle(neo.small_inner_shadow);
74 | if (imageView != null) {
75 | imageView.setScaleX(imageView.getScaleX() * 0.9f);
76 | imageView.setScaleY(imageView.getScaleY() * 0.9f);
77 | }
78 | if (textView != null) {
79 | textView.setScaleX(textView.getScaleX() * 0.9f);
80 | textView.setScaleY(textView.getScaleY() * 0.9f);
81 | }
82 | performClick();
83 | requiresShapeUpdate();
84 | return true;
85 | case MotionEvent.ACTION_UP:
86 | case MotionEvent.ACTION_CANCEL:
87 | // RELEASED
88 | setStyle(neo.drop_shadow);
89 | if (imageView != null) {
90 | imageView.setScaleX(1);
91 | imageView.setScaleY(1);
92 | }
93 | if (textView != null) {
94 | textView.setScaleX(1);
95 | textView.setScaleY(1);
96 | }
97 | requiresShapeUpdate();
98 | return true;
99 | }
100 | } else {
101 | // RELEASED
102 | // handle release
103 | setStyle(neo.drop_shadow);
104 | if (imageView != null) {
105 | imageView.setScaleX(1);
106 | imageView.setScaleY(1);
107 | }
108 | if (textView != null) {
109 | textView.setScaleX(1);
110 | textView.setScaleY(1);
111 | }
112 | requiresShapeUpdate();
113 | return true;
114 | }
115 | return false;
116 | }
117 |
118 | @Override
119 | public boolean performClick() {
120 | return super.performClick();
121 |
122 | }
123 |
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/sshadkany/PolygonButton.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import androidx.annotation.NonNull;
12 | import androidx.annotation.Nullable;
13 |
14 | import com.github.sshadkany.shapes.PolygonView;
15 |
16 | public class PolygonButton extends PolygonView {
17 |
18 | private ImageView imageView;
19 | private TextView textView;
20 |
21 | public PolygonButton(@NonNull Context context) {
22 | super(context);
23 | }
24 |
25 | public PolygonButton(@NonNull Context context, @Nullable AttributeSet attrs) {
26 | super(context, attrs);
27 | }
28 |
29 | public PolygonButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
30 | super(context, attrs, defStyleAttr);
31 | }
32 |
33 |
34 | private void myAddView(View child) {
35 |
36 | if (child instanceof ImageView) {
37 | imageView = (ImageView) child;
38 | } else if (child instanceof TextView) {
39 | textView = (TextView) child;
40 | }
41 | }
42 |
43 | @Override
44 | public void addView(View child, int index, ViewGroup.LayoutParams params) {
45 | super.addView(child, index, params);
46 | myAddView(child);
47 | }
48 |
49 | @Override
50 | public void addView(View child, int width, int height) {
51 | super.addView(child, width, height);
52 | myAddView(child);
53 | }
54 |
55 | @Override
56 | public void addView(View child, int index) {
57 | super.addView(child, index);
58 | myAddView(child);
59 | }
60 |
61 | @Override
62 | public void addView(View child) {
63 | super.addView(child);
64 | myAddView(child);
65 | }
66 |
67 |
68 | @Override
69 | public boolean onTouchEvent(MotionEvent event) {
70 | if (isShapeContainsPoint(event.getX(), event.getY())) {
71 | switch (event.getAction()) {
72 | case MotionEvent.ACTION_DOWN:
73 | // PRESSED
74 | setStyle(neo.small_inner_shadow);
75 | if (imageView != null) {
76 | imageView.setScaleX(imageView.getScaleX() * 0.9f);
77 | imageView.setScaleY(imageView.getScaleY() * 0.9f);
78 | }
79 | if (textView != null) {
80 | textView.setScaleX(textView.getScaleX() * 0.9f);
81 | textView.setScaleY(textView.getScaleY() * 0.9f);
82 | }
83 | performClick();
84 | requiresShapeUpdate();
85 | return true;
86 | case MotionEvent.ACTION_UP:
87 | case MotionEvent.ACTION_CANCEL:
88 | // RELEASED
89 | setStyle(neo.drop_shadow);
90 | if (imageView != null) {
91 | imageView.setScaleX(1);
92 | imageView.setScaleY(1);
93 | }
94 | if (textView != null) {
95 | textView.setScaleX(1);
96 | textView.setScaleY(1);
97 | }
98 | requiresShapeUpdate();
99 | return true;
100 | }
101 | } else {
102 | // RELEASED
103 | // handle release
104 | setStyle(neo.drop_shadow);
105 | if (imageView != null) {
106 | imageView.setScaleX(1);
107 | imageView.setScaleY(1);
108 | }
109 | if (textView != null) {
110 | textView.setScaleX(1);
111 | textView.setScaleY(1);
112 | }
113 | requiresShapeUpdate();
114 | return true;
115 | }
116 | return false;
117 | }
118 |
119 | @Override
120 | public boolean performClick() {
121 | return super.performClick();
122 |
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/sshadkany/RectButton.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import androidx.annotation.NonNull;
12 | import androidx.annotation.Nullable;
13 |
14 | import com.github.sshadkany.shapes.RoundRectView;
15 |
16 | public class RectButton extends RoundRectView {
17 |
18 | private ImageView imageView;
19 | private TextView textView;
20 | private boolean isPressed = false;
21 |
22 | public RectButton(@NonNull Context context) {
23 | super(context);
24 | }
25 |
26 | public RectButton(@NonNull Context context, @Nullable AttributeSet attrs) {
27 | super(context, attrs);
28 | }
29 |
30 | public RectButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
31 | super(context, attrs, defStyleAttr);
32 | }
33 |
34 | private void myAddView(View child) {
35 |
36 | if (child instanceof ImageView) {
37 | imageView = (ImageView) child;
38 | } else if (child instanceof TextView) {
39 | textView = (TextView) child;
40 | }
41 | }
42 |
43 | @Override
44 | public void addView(View child, int index, ViewGroup.LayoutParams params) {
45 | super.addView(child, index, params);
46 | myAddView(child);
47 | }
48 |
49 | @Override
50 | public void addView(View child, int width, int height) {
51 | super.addView(child, width, height);
52 | myAddView(child);
53 | }
54 |
55 | @Override
56 | public void addView(View child, int index) {
57 | super.addView(child, index);
58 | myAddView(child);
59 | }
60 |
61 | @Override
62 | public void addView(View child) {
63 | super.addView(child);
64 | myAddView(child);
65 | }
66 |
67 |
68 | @Override
69 | public boolean onTouchEvent(MotionEvent event) {
70 | if (isShapeContainsPoint(event.getX(), event.getY())) {
71 | switch (event.getAction()) {
72 | case MotionEvent.ACTION_DOWN:
73 | // PRESSED
74 | setStyle(neo.small_inner_shadow);
75 | if (imageView != null) {
76 | imageView.setScaleX(imageView.getScaleX() * 0.9f);
77 | imageView.setScaleY(imageView.getScaleY() * 0.9f);
78 | }
79 | if (textView != null) {
80 | textView.setScaleX(textView.getScaleX() * 0.9f);
81 | textView.setScaleY(textView.getScaleY() * 0.9f);
82 | }
83 | isPressed = true;
84 | performClick();
85 | requiresShapeUpdate();
86 | return true;
87 | case MotionEvent.ACTION_UP:
88 | case MotionEvent.ACTION_CANCEL:
89 | // RELEASED
90 | setStyle(neo.drop_shadow);
91 | if (imageView != null) {
92 | imageView.setScaleX(1);
93 | imageView.setScaleY(1);
94 | }
95 | if (textView != null) {
96 | textView.setScaleX(1);
97 | textView.setScaleY(1);
98 | }
99 | isPressed = false;
100 | requiresShapeUpdate();
101 | return true;
102 | }
103 | } else {
104 | // RELEASED
105 | // handle release
106 | setStyle(neo.drop_shadow);
107 | if (imageView != null) {
108 | imageView.setScaleX(1);
109 | imageView.setScaleY(1);
110 | }
111 | if (textView != null) {
112 | textView.setScaleX(1);
113 | textView.setScaleY(1);
114 | }
115 | isPressed = false;
116 | requiresShapeUpdate();
117 | return true;
118 | }
119 | return false;
120 | }
121 |
122 | @Override
123 | public boolean performClick() {
124 | return super.performClick();
125 |
126 | }
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/sshadkany/neo.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Path;
9 | import android.graphics.PorterDuff;
10 | import android.graphics.PorterDuffXfermode;
11 | import android.graphics.RectF;
12 | import android.graphics.Region;
13 | import android.hardware.Sensor;
14 | import android.hardware.SensorEvent;
15 | import android.hardware.SensorEventListener;
16 | import android.hardware.SensorManager;
17 | import android.os.Build;
18 | import android.util.AttributeSet;
19 | import android.util.Log;
20 |
21 | import androidx.annotation.IntDef;
22 | import androidx.annotation.NonNull;
23 | import androidx.annotation.Nullable;
24 |
25 | import com.github.florent37.ShapeOfView;
26 |
27 | import static android.content.Context.SENSOR_SERVICE;
28 | /**
29 | * created by sshadkany
30 | */
31 | public class neo extends ShapeOfView {
32 |
33 | @IntDef({drop_shadow,big_inner_shadow,small_inner_shadow})
34 | public @interface mystyle{}
35 | public static final int drop_shadow = 1;
36 | public static final int big_inner_shadow = 2;
37 | public static final int small_inner_shadow = 3;
38 | @mystyle
39 | public int style = drop_shadow;
40 | public float shadow_position_x = 25;
41 | public float shadow_position_y = 25;
42 | public float shadow_radius = 41;
43 |
44 | public int light_color = Color.WHITE;
45 | public int dark_color = Color.parseColor("#A3B1C6");
46 | // public int background_color = Color.parseColor("#E0E5Ec"); // move upper place
47 |
48 | private Paint mPaint;
49 | private Paint mPaint2;
50 | private Context mcontext;
51 | private Paint fillPaint;
52 | private Paint shadowPaint;
53 | private Paint lightPaint;
54 | private PorterDuffXfermode mode;
55 | private Path bigPath;
56 |
57 |
58 |
59 |
60 |
61 | public neo(@NonNull Context context) {
62 | super(context);
63 | init(context);
64 | }
65 |
66 | public neo(@NonNull Context context, @Nullable AttributeSet attrs) {
67 | super(context, attrs);
68 | init(context);
69 | }
70 |
71 | public neo(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
72 | super(context, attrs, defStyleAttr);
73 | init(context);
74 | }
75 |
76 | public void init(Context context){
77 | mcontext = context;
78 | setDrawingCacheEnabled(true);
79 | setWillNotDraw(false);
80 | mPaint = new Paint();
81 | mPaint.setAntiAlias(true);
82 |
83 | mPaint2 = new Paint();
84 | mPaint2.setAntiAlias(true);
85 |
86 | fillPaint = new Paint();
87 | fillPaint.setAntiAlias(true);
88 | fillPaint.setStyle(Paint.Style.FILL);
89 | fillPaint.setColor(background_color);
90 | // gyroscopeSensor();
91 |
92 | bigPath = new Path();
93 |
94 |
95 | }
96 |
97 | @Override
98 | protected void dispatchDraw(Canvas canvas) {
99 | super.dispatchDraw(canvas);
100 | bigPath.addRect(-1*getWidth(),-1*getHeight(),getWidth(),getHeight(), Path.Direction.CW);
101 |
102 | Bitmap bitmap = Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
103 | Canvas mc = new Canvas(bitmap);
104 |
105 | Log.i("sajjad", "dispatchDraw: sajjad"+style);
106 | if (style == drop_shadow) {
107 | dropShadowOptions(shadow_position_x,shadow_position_y, shadow_radius);
108 | mc.drawPath(clipPath,shadowPaint);
109 | mc.drawPath(clipPath,lightPaint);
110 | canvas.drawBitmap(bitmap,0,0,mPaint);
111 | }else if (style == big_inner_shadow || style == small_inner_shadow) {
112 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
113 | innerShadowOptions(shadow_position_x, shadow_position_y, shadow_radius);
114 | Bitmap bitmap2 = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
115 | Canvas mc2 = new Canvas(bitmap2);
116 |
117 | Bitmap rectviewbitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
118 | Canvas rectcanvas = new Canvas(rectviewbitmap);
119 | Paint p = new Paint();
120 | p.setColor(Color.BLUE);
121 | rectcanvas.drawPath(bigPath,p);
122 | p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
123 | rectcanvas.drawPath(clipPath,p);
124 |
125 | // mc2.drawPath(rectView, shadowPaint);
126 | // mc2.drawPath(rectView, lightPaint);
127 | mc2.drawBitmap(rectviewbitmap.extractAlpha(),0,0,shadowPaint);
128 | mc2.drawBitmap(rectviewbitmap.extractAlpha(),0,0,lightPaint);
129 |
130 | mc.drawPath(clipPath, fillPaint);
131 |
132 | mPaint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
133 | mc.drawBitmap(bitmap2, 0, 0, mPaint2);
134 | mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
135 | mPaint.setXfermode(mode);
136 | canvas.drawBitmap(bitmap, 0, 0, mPaint);
137 |
138 | mode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
139 | fillPaint.setXfermode(mode);
140 | fillPaint.setColor(background_color);
141 | canvas.drawPath(clipPath, fillPaint);
142 | }else{
143 | innerShadowOptions(shadow_position_x, shadow_position_y, shadow_radius);
144 | Bitmap bitmap2 = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
145 | Canvas mc2 = new Canvas(bitmap2);
146 |
147 | mc2.drawPath(rectView, shadowPaint);
148 | mc2.drawPath(rectView, lightPaint);
149 |
150 | mc.drawPath(clipPath, fillPaint);
151 |
152 | mPaint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
153 | mc.drawBitmap(bitmap2, 0, 0, mPaint2);
154 | mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
155 | mPaint.setXfermode(mode);
156 | canvas.drawBitmap(bitmap, 0, 0, mPaint);
157 |
158 | mode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
159 | fillPaint.setXfermode(mode);
160 | fillPaint.setColor(background_color);
161 | canvas.drawPath(clipPath, fillPaint);
162 | }
163 | }
164 |
165 |
166 |
167 |
168 | }
169 |
170 |
171 | @Override
172 | protected void onDraw(Canvas canvas) {
173 | super.onDraw(canvas);
174 |
175 | }
176 | public static float pxFromDp(final Context context, final float dp) {
177 | return dp * context.getResources().getDisplayMetrics().density;
178 | }
179 | private void dropShadowOptions(float dx,float dy,float radius){
180 | shadowPaint = new Paint();
181 | shadowPaint.setAntiAlias(true);
182 | shadowPaint.setColor(background_color);
183 | shadowPaint.setShadowLayer(radius,dx,dy,dark_color);
184 |
185 | lightPaint = new Paint();
186 | lightPaint.setAntiAlias(true);
187 | lightPaint.setColor(background_color);
188 | lightPaint.setShadowLayer(radius,-1*dx,-1*dy,light_color);
189 |
190 | mode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
191 | mPaint.setXfermode(mode);
192 | }
193 |
194 |
195 | private void innerShadowOptions(float dx,float dy,float radius){
196 | shadowPaint = new Paint();
197 | shadowPaint.setAntiAlias(true);
198 | shadowPaint.setStyle(Paint.Style.FILL);
199 | shadowPaint.setColor(background_color);
200 | shadowPaint.setShadowLayer(radius,dx,dy,dark_color);
201 |
202 | lightPaint = new Paint();
203 | lightPaint.setAntiAlias(true);
204 | lightPaint.setColor(background_color);
205 | lightPaint.setShadowLayer(radius,-1*dx,-1*dy,light_color);
206 |
207 |
208 | mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP);
209 | mPaint.setXfermode(mode);
210 | }
211 | private void gyroscopeSensor(){
212 | SensorManager sensorManager =
213 | (SensorManager) mcontext.getSystemService(SENSOR_SERVICE);
214 | Sensor gyroscopeSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
215 |
216 | SensorEventListener gyroscopeSensorListener = new SensorEventListener() {
217 | @Override
218 | public void onSensorChanged(SensorEvent sensorEvent) {
219 | float[] rotationMatrix = new float[16];
220 | SensorManager.getRotationMatrixFromVector(
221 | rotationMatrix, sensorEvent.values);
222 | // Remap coordinate system
223 | float[] remappedRotationMatrix = new float[16];
224 | SensorManager.remapCoordinateSystem(rotationMatrix,
225 | SensorManager.AXIS_X,
226 | SensorManager.AXIS_Z,
227 | remappedRotationMatrix);
228 |
229 | // Convert to orientations
230 | float[] orientations = new float[3];
231 | SensorManager.getOrientation(remappedRotationMatrix, orientations);
232 |
233 | // /*orientations[2] in radian*/
234 | shadow_position_y = (float) (Math.cos(orientations[2])* shadow_radius) + 5;
235 | shadow_position_x = (float) (Math.sin(orientations[2])* shadow_radius) + 5;
236 | // radius = (float) (Math.sin(orientations[1])*50)+10;
237 |
238 | postInvalidate();
239 | }
240 |
241 | @Override
242 | public void onAccuracyChanged(Sensor sensor, int i) {
243 | }
244 | };
245 |
246 | sensorManager.registerListener(gyroscopeSensorListener,
247 | gyroscopeSensor, SensorManager.SENSOR_DELAY_UI);
248 | }
249 |
250 | //**************** Getter and setter *******************
251 |
252 |
253 | public int getStyle() {
254 | return style;
255 | }
256 |
257 | /***
258 | * for set shadow style "small inner shadow" or "big inner shadow" or "drop shadow"
259 | * "small inner shadow" is same as big inner shadow but smaller and is same size of drop shadow
260 | * when you want make a button you should use "small inner shadow" for pressing style
261 | *
262 | *
263 | * @param style
264 | *
265 | */
266 | public void setStyle(@mystyle int style) {
267 | this.style = style;
268 | requiresShapeUpdate();
269 | }
270 |
271 | /***
272 | *
273 | * same as set style but with a better name !
274 | *
275 | */
276 | public int getShadowStyle() {
277 | return style;
278 | }
279 |
280 | /***
281 | * for set shadow style "small inner shadow" or "big inner shadow" or "drop shadow"
282 | * "small inner shadow" is same as big inner shadow but smaller and is same size of drop shadow
283 | * when you want make a button you should use "small inner shadow" for pressing style
284 | *
285 | * same as set style but with a better name !
286 | * @param shadowStyle
287 | */
288 | public void setShadowStyle(@mystyle int shadowStyle) {
289 | this.style = shadowStyle;
290 | requiresShapeUpdate();
291 | }
292 |
293 | public float getShadow_position_x() {
294 | return shadow_position_x;
295 | }
296 |
297 | public void setShadow_position_x(float shadow_position_x) {
298 | this.shadow_position_x = shadow_position_x;
299 | requiresShapeUpdate();
300 | }
301 |
302 | public float getShadow_position_y() {
303 | return shadow_position_y;
304 | }
305 |
306 | public void setShadow_position_y(float shadow_position_y) {
307 | this.shadow_position_y = shadow_position_y;
308 | requiresShapeUpdate();
309 | }
310 |
311 | public float getShadow_radius() {
312 | return shadow_radius;
313 | }
314 |
315 | public void setShadow_radius(float shadow_radius) {
316 | this.shadow_radius = shadow_radius;
317 | requiresShapeUpdate();
318 | }
319 |
320 | public int getLight_color() {
321 | return light_color;
322 | }
323 |
324 | public void setLight_color(int light_color) {
325 | this.light_color = light_color;
326 | requiresShapeUpdate();
327 | }
328 |
329 | public int getDark_color() {
330 | return dark_color;
331 | }
332 |
333 | public void setDark_color(int dark_color) {
334 | this.dark_color = dark_color;
335 | requiresShapeUpdate();
336 | }
337 |
338 |
339 | public int getBackground_color(){
340 | return background_color;
341 | }
342 |
343 | public void setBackground_color(int background_color) {
344 | this.background_color = background_color;
345 | requiresShapeUpdate();
346 | }
347 |
348 | /**
349 | *
350 | *
351 | * @param x
352 | * @param y
353 | * @return true if the point are inside of shape
354 | */
355 | public boolean isShapeContainsPoint(float x, float y){
356 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
357 | Path tempPath = new Path(); // Create temp Path
358 | tempPath.moveTo(x, y); // Move cursor to point
359 | RectF rectangle = new RectF(x - 1, y - 1, x + 1, y + 1); // create rectangle with size 2xp
360 | tempPath.addRect(rectangle, Path.Direction.CW); // add rect to temp path
361 | tempPath.op(clipPath, Path.Op.DIFFERENCE); // get difference with our PathToCheck
362 | if (tempPath.isEmpty()) // if out path cover temp path we get empty path in result
363 | {
364 | Log.d("saj", "Path contains this point");
365 | return true;
366 | } else {
367 | return false;
368 | }
369 | }else{
370 | RectF rectF = new RectF();
371 | clipPath.computeBounds(rectF, false);
372 | Region r = new Region();
373 | r.setPath(clipPath, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));
374 | if (r.contains((int)x,(int)y)){
375 | return true;
376 | }else {
377 | return false;
378 | }
379 |
380 | }
381 | }
382 |
383 | //*****************************************************
384 |
385 | }
386 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/sshadkany/neoText.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.graphics.Path;
10 | import android.graphics.Rect;
11 | import android.os.Build;
12 | import android.provider.CalendarContract;
13 | import android.text.Layout;
14 | import android.text.LoginFilter;
15 | import android.text.StaticLayout;
16 | import android.text.TextPaint;
17 | import android.util.AttributeSet;
18 | import android.util.Log;
19 | import android.view.View;
20 | import android.view.ViewGroup;
21 | import android.widget.ImageView;
22 | import android.widget.TextView;
23 |
24 | import androidx.annotation.ColorInt;
25 | import androidx.annotation.NonNull;
26 | import androidx.annotation.Nullable;
27 | import androidx.annotation.RequiresApi;
28 |
29 | import com.github.florent37.manager.ClipPathManager;
30 |
31 | import com.github.sshadkany.android_neumorphic.R;
32 | import com.github.sshadkany.neo;
33 |
34 | /**
35 | * created by sshadkany
36 | */
37 | public class neoText extends neo {
38 | private float borderWidthPx = 0f;
39 | private TextView textView;
40 |
41 | String mText = "";
42 | TextPaint mTextPaint;
43 |
44 | @ColorInt
45 | private int borderColor = Color.WHITE;
46 |
47 | private final Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
48 |
49 |
50 | public neoText(@NonNull Context context) {
51 | super(context);
52 | init(context, null);
53 | }
54 |
55 | public neoText(@NonNull Context context, @Nullable AttributeSet attrs) {
56 | super(context, attrs);
57 | init(context, attrs);
58 | }
59 |
60 | public neoText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
61 | super(context, attrs, defStyleAttr);
62 | init(context, attrs);
63 | }
64 |
65 | private void myAddView(View child) {
66 | if (child instanceof TextView) {
67 | textView = (TextView) child;
68 | textView.setTextColor(Color.TRANSPARENT);
69 | }
70 | }
71 |
72 | @Override
73 | public void addView(View child, int index, ViewGroup.LayoutParams params) {
74 | super.addView(child, index, params);
75 | myAddView(child);
76 | }
77 |
78 | @Override
79 | public void addView(View child, int width, int height) {
80 | super.addView(child, width, height);
81 | myAddView(child);
82 | }
83 |
84 | @Override
85 | public void addView(View child, int index) {
86 | super.addView(child, index);
87 | myAddView(child);
88 | }
89 |
90 | @Override
91 | public void addView(View child) {
92 | super.addView(child);
93 | myAddView(child);
94 | }
95 |
96 |
97 | private void init(Context context, AttributeSet attrs) {
98 | if (attrs != null) {
99 | final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.neoText);
100 | borderWidthPx = attributes.getDimensionPixelSize(R.styleable.neoText_neo_borderWidth, (int) borderWidthPx);
101 | borderColor = attributes.getColor(R.styleable.neoText_neo_borderColor, borderColor);
102 | //****** neo text default styles ************
103 | shadow_position_x = 4;
104 | shadow_position_y = 4;
105 | shadow_radius = 4;
106 | //******************************
107 | style = attributes.getInteger(R.styleable.neoText_neo_shadow_type, drop_shadow);
108 | shadow_position_x = attributes.getDimensionPixelSize(R.styleable.neoText_neo_shadow_position_x, (int) shadow_position_x);
109 | shadow_position_y = attributes.getDimensionPixelSize(R.styleable.neoText_neo_shadow_position_y, (int) shadow_position_y);
110 | shadow_radius = attributes.getDimensionPixelSize(R.styleable.neoText_neo_radius, (int) shadow_radius);
111 | light_color = attributes.getColor(R.styleable.neoText_neo_light_color, light_color);
112 | dark_color = attributes.getColor(R.styleable.neoText_neo_dark_color, dark_color);
113 | background_color = attributes.getColor(R.styleable.neoText_neo_backgroundColor, background_color);
114 | //******************************
115 |
116 | //*****************************
117 | attributes.recycle();
118 | }
119 | borderPaint.setAntiAlias(true);
120 | borderPaint.setStyle(Paint.Style.STROKE);
121 |
122 | super.setClipPathCreator(new ClipPathManager.ClipPathCreator() {
123 | @Override
124 | public Path createClipPath(int width, int height) {
125 | final Path path = new Path();
126 | if (textView != null) {
127 | mText = textView.getText().toString();
128 | mTextPaint = textView.getPaint();
129 | // initLabelView(mText,mTextPaint);
130 | // TextPaint textViewPaint = mStaticLayout.getPaint();
131 | float text_position_x = 0;
132 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
133 | text_position_x = findTextBounds(textView).left;
134 |
135 | }
136 | // String s = textView.getText().toString();
137 | boolean flag = true;
138 | int line = 0;
139 | int startPointer = 0;
140 | int endPointer = mText.length();
141 |
142 | while (flag) {
143 | Path p = new Path();
144 | int breakText = mTextPaint.breakText(mText.substring(startPointer), true, width, null);
145 | mTextPaint.getTextPath(mText, startPointer, startPointer + breakText, text_position_x,
146 | textView.getBaseline() + mTextPaint.getFontSpacing() * line, p);
147 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
148 | path.op(p, Path.Op.UNION);
149 | }
150 | endPointer -= breakText;
151 | startPointer += breakText;
152 | line++;
153 | if (endPointer == 0) {
154 | flag = false;
155 | }
156 | }
157 |
158 | }
159 | return path;
160 | }
161 |
162 | @Override
163 | public boolean requiresBitmap() {
164 | return false;
165 | }
166 | });
167 | }
168 |
169 |
170 | public void setBorderWidth(float borderWidth) {
171 | this.borderWidthPx = borderWidth;
172 | requiresShapeUpdate();
173 | }
174 |
175 | public void setBorderColor(@ColorInt int borderColor) {
176 | this.borderColor = borderColor;
177 | requiresShapeUpdate();
178 | }
179 |
180 | public void setBorderWidthDp(float borderWidth) {
181 | setBorderWidth(dpToPx(borderWidth));
182 | }
183 |
184 | public float getBorderWidth() {
185 | return borderWidthPx;
186 | }
187 |
188 | public float getBorderWidthDp() {
189 | return pxToDp(getBorderWidth());
190 | }
191 |
192 | public int getBorderColor() {
193 | return borderColor;
194 | }
195 |
196 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
197 | private Rect findTextBounds(TextView textView) {
198 | // Force measure of text pre-layout.
199 | textView.measure(0, 0);
200 | String s = (String) textView.getText();
201 |
202 | // bounds will store the rectangle that will circumscribe the text.
203 | Rect bounds = new Rect();
204 | Paint textPaint = textView.getPaint();
205 |
206 | // Get the bounds for the text. Top and bottom are measured from the baseline. Left
207 | // and right are measured from 0.
208 | textPaint.getTextBounds(s, 0, s.length(), bounds);
209 | int baseline = textView.getBaseline();
210 | bounds.top = baseline + bounds.top;
211 | bounds.bottom = baseline + bounds.bottom;
212 | int startPadding = textView.getPaddingStart();
213 | bounds.left += startPadding;
214 |
215 | // textPaint.getTextBounds() has already computed a value for the width of the text,
216 | // however, Paint#measureText() gives a more accurate value.
217 | bounds.right = (int) textPaint.measureText(s, 0, s.length()) + startPadding;
218 | return bounds;
219 | }
220 |
221 |
222 | }
223 |
224 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/sshadkany/shapes/CircleView.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.shapes;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Path;
9 | import android.os.Build;
10 | import android.util.AttributeSet;
11 |
12 | import androidx.annotation.ColorInt;
13 | import androidx.annotation.NonNull;
14 | import androidx.annotation.Nullable;
15 | import androidx.annotation.RequiresApi;
16 |
17 | import com.github.florent37.manager.ClipPathManager;
18 |
19 | import com.github.sshadkany.android_neumorphic.R;
20 | import com.github.sshadkany.neo;
21 |
22 | /**
23 | * created by com.github.florent37
24 | * modified by sshadkany
25 | */
26 | public class CircleView extends neo {
27 | private float borderWidthPx = 0f;
28 |
29 |
30 | @ColorInt
31 | private int borderColor = Color.WHITE;
32 |
33 | private final Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
34 | private float adjust_factor = 2.2f;
35 | public CircleView(@NonNull Context context) {
36 | super(context);
37 | init(context, null);
38 | }
39 |
40 | public CircleView(@NonNull Context context, @Nullable AttributeSet attrs) {
41 | super(context, attrs);
42 | init(context, attrs);
43 | }
44 |
45 | public CircleView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
46 | super(context, attrs, defStyleAttr);
47 | init(context, attrs);
48 | }
49 |
50 | private void init(Context context, AttributeSet attrs) {
51 | if (attrs != null) {
52 | final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircleView);
53 | borderWidthPx = attributes.getDimensionPixelSize(R.styleable.CircleView_shape_circle_borderWidth, (int) borderWidthPx);
54 | borderColor = attributes.getColor(R.styleable.CircleView_shape_circle_borderColor, borderColor);
55 | //****** neo styles ************
56 | style = attributes.getInteger(R.styleable.CircleView_shape_circle_shadow_type,drop_shadow);
57 | shadow_position_x = attributes.getDimensionPixelSize(R.styleable.CircleView_shape_circle_shadow_position_x, (int) shadow_position_x);
58 | shadow_position_y = attributes.getDimensionPixelSize(R.styleable.CircleView_shape_circle_shadow_position_y, (int) shadow_position_y);
59 | shadow_radius = attributes.getDimensionPixelSize(R.styleable.CircleView_shape_circle_radius, (int) shadow_radius);
60 | light_color = attributes.getColor(R.styleable.CircleView_shape_circle_light_color, light_color);
61 | dark_color = attributes.getColor(R.styleable.CircleView_shape_circle_dark_color, dark_color);
62 | background_color = attributes.getColor(R.styleable.CircleView_shape_circle_backgroundColor, background_color);
63 | //******************************
64 | attributes.recycle();
65 | }
66 | borderPaint.setAntiAlias(true);
67 | borderPaint.setStyle(Paint.Style.STROKE);
68 | final float abs_shadow_position_x = Math.abs(shadow_position_x);
69 | final float abs_shadow_position_y = Math.abs(shadow_position_y);
70 | final float abs_radius = Math.abs(shadow_radius)*adjust_factor;
71 |
72 | super.setClipPathCreator(new ClipPathManager.ClipPathCreator() {
73 | @Override
74 | public Path createClipPath(int width, int height) {
75 | final Path path = new Path();
76 | if (style == drop_shadow || style == small_inner_shadow) {
77 | path.addCircle(width / 2f, height / 2f, Math.min(width - (2 * abs_shadow_position_x) - abs_radius, height - (2 * abs_shadow_position_y) - abs_radius) / 2, Path.Direction.CW);
78 | }else{
79 | path.addCircle(width / 2f, height / 2f, Math.min(width , height) / 2f, Path.Direction.CW);
80 | }
81 | return path;
82 | }
83 |
84 | @Override
85 | public boolean requiresBitmap() {
86 | return false;
87 | }
88 | });
89 | }
90 |
91 | @RequiresApi(api = Build.VERSION_CODES.KITKAT)
92 | @Override
93 | protected void dispatchDraw(Canvas canvas) {
94 | super.dispatchDraw(canvas);
95 | final float abs_shadow_position_x = Math.abs(shadow_position_x);
96 | final float abs_shadow_position_y = Math.abs(shadow_position_y);
97 | final float abs_radius = Math.abs(shadow_radius)*adjust_factor;
98 | if(borderWidthPx > 0){
99 | borderPaint.setStrokeWidth(borderWidthPx);
100 | borderPaint.setColor(borderColor);
101 | if (style == drop_shadow || style == small_inner_shadow){
102 | canvas.drawCircle(getWidth()/2f, getHeight()/2f, Math.min(getWidth()-(2*abs_shadow_position_x)-abs_radius, getHeight()-(2*abs_shadow_position_y)-abs_radius)/2, borderPaint);
103 | }else{
104 | canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, (Math.min(getWidth() , getHeight()) / 2f)-(borderWidthPx / 2f),borderPaint);
105 | }
106 | }
107 | }
108 |
109 | public void setBorderWidth(float borderWidth) {
110 | this.borderWidthPx = borderWidth;
111 | requiresShapeUpdate();
112 | }
113 |
114 | public void setBorderColor(@ColorInt int borderColor) {
115 | this.borderColor = borderColor;
116 | requiresShapeUpdate();
117 | }
118 |
119 | public void setBorderWidthDp(float borderWidth) {
120 | setBorderWidth(dpToPx(borderWidth));
121 | }
122 |
123 | public float getBorderWidth() {
124 | return borderWidthPx;
125 | }
126 |
127 | public float getBorderWidthDp() {
128 | return pxToDp(getBorderWidth());
129 | }
130 |
131 | public int getBorderColor() {
132 | return borderColor;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/sshadkany/shapes/PolygonView.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.shapes;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Path;
9 | import android.util.AttributeSet;
10 | import android.util.Log;
11 |
12 | import androidx.annotation.ColorInt;
13 | import androidx.annotation.NonNull;
14 | import androidx.annotation.Nullable;
15 |
16 | import com.github.florent37.manager.ClipPathManager;
17 |
18 | import com.github.sshadkany.android_neumorphic.R;
19 | import com.github.sshadkany.neo;
20 |
21 | /**
22 | * created by sshadkany@gmail.com
23 | */
24 | public class PolygonView extends neo {
25 | private float borderWidthPx = 0f;
26 | private int side = 3;
27 | private float corner_radius = 55;
28 | private float adjust_factor = 2.2f;
29 | @ColorInt
30 | private int borderColor = Color.WHITE;
31 |
32 | private final Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
33 |
34 | public PolygonView(@NonNull Context context) {
35 | super(context);
36 | init(context, null);
37 | }
38 |
39 | public PolygonView(@NonNull Context context, @Nullable AttributeSet attrs) {
40 | super(context, attrs);
41 | init(context, attrs);
42 | }
43 |
44 | public PolygonView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
45 | super(context, attrs, defStyleAttr);
46 | init(context, attrs);
47 | }
48 |
49 | private void init(Context context, AttributeSet attrs) {
50 | if (attrs != null) {
51 | final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.PolygonView);
52 | borderWidthPx = attributes.getDimensionPixelSize(R.styleable.PolygonView_shape_polygon_borderWidth, (int) borderWidthPx);
53 | borderColor = attributes.getColor(R.styleable.PolygonView_shape_polygon_borderColor, borderColor);
54 | //****** neo styles ************
55 | style = attributes.getInteger(R.styleable.PolygonView_shape_polygon_shadow_type,drop_shadow);
56 | shadow_position_x = attributes.getDimensionPixelSize(R.styleable.PolygonView_shape_polygon_shadow_position_x, (int) shadow_position_x);
57 | shadow_position_y = attributes.getDimensionPixelSize(R.styleable.PolygonView_shape_polygon_shadow_position_y, (int) shadow_position_y);
58 | shadow_radius = attributes.getDimensionPixelSize(R.styleable.PolygonView_shape_polygon_radius, (int) shadow_radius);
59 | light_color = attributes.getColor(R.styleable.PolygonView_shape_polygon_light_color, light_color);
60 | dark_color = attributes.getColor(R.styleable.PolygonView_shape_polygon_dark_color, dark_color);
61 | background_color = attributes.getColor(R.styleable.PolygonView_shape_polygon_backgroundColor, background_color);
62 | side = attributes.getInteger(R.styleable.PolygonView_shape_polygon_side, (int) side);
63 | corner_radius = attributes.getDimensionPixelSize(R.styleable.PolygonView_shape_polygon_corner_radius, (int) corner_radius);
64 | //******************************
65 | attributes.recycle();
66 | }
67 | borderPaint.setAntiAlias(true);
68 | borderPaint.setStyle(Paint.Style.STROKE);
69 | final float abs_shadow_position_x = Math.abs(shadow_position_x);
70 | final float abs_shadow_position_y = Math.abs(shadow_position_y);
71 | final float abs_radius = Math.abs(shadow_radius)*adjust_factor;
72 |
73 | super.setClipPathCreator(new ClipPathManager.ClipPathCreator() {
74 | @Override
75 | public Path createClipPath(int width, int height) {
76 | final Path path;
77 | if (style == drop_shadow || style == small_inner_shadow) {
78 | path = createPath(side,Math.min(width - (2 * abs_shadow_position_x) - abs_radius, height - (2 * abs_shadow_position_y) - abs_radius) / 2,width / 2f, height / 2f);
79 | // path.addCircle(width / 2f, height / 2f, Math.min(width - (2 * abs_shadow_position_x) - abs_radius, height - (2 * abs_shadow_position_y) - abs_radius) / 2, Path.Direction.CW);
80 | }else{
81 | path=createPath(side,Math.min(width , height) / 2f,width / 2f, height / 2f);
82 | // path.addCircle(width / 2f, height / 2f, Math.min(width , height) / 2f, Path.Direction.CW);
83 | }
84 | return path;
85 | }
86 |
87 | @Override
88 | public boolean requiresBitmap() {
89 | return false;
90 | }
91 | });
92 | }
93 |
94 | @Override
95 | protected void dispatchDraw(Canvas canvas) {
96 | super.dispatchDraw(canvas);
97 | final float abs_shadow_position_x = Math.abs(shadow_position_x);
98 | final float abs_shadow_position_y = Math.abs(shadow_position_y);
99 | final float abs_radius = Math.abs(shadow_radius)*adjust_factor;
100 | if(borderWidthPx > 0){
101 | borderPaint.setStrokeWidth(borderWidthPx);
102 | borderPaint.setColor(borderColor);
103 |
104 | final Path path;
105 | float width = getWidth();
106 | float height = getHeight();
107 | if (style == drop_shadow || style == small_inner_shadow) {
108 | path = createPath(side,Math.min(width - (2 * abs_shadow_position_x) - abs_radius, height - (2 * abs_shadow_position_y) - abs_radius) / 2,width / 2f, height / 2f);
109 | }else{
110 | path=createPath(side,Math.min(width , height) / 2f,width / 2f, height / 2f);
111 | }
112 |
113 | canvas.drawPath(path,borderPaint);
114 | }
115 | }
116 |
117 | // public Path createPath(int sides,float radius,float cx,float cy){
118 | // Path path = new Path();
119 | // float angle = (float) (2.0 * Math.PI / sides);
120 | // path.moveTo(
121 | // (float)(cx + (radius * Math.cos(0.0))),
122 | // (float)(cy + (radius * Math.sin(0.0))));
123 | // for (int i = 1; i < sides; i++) {
124 | // path.lineTo(
125 | // ((float) (cx + (radius * Math.cos(angle * i)))),
126 | // ((float) (cy + (radius * Math.sin(angle * i)))));
127 | // }
128 | // path.close();
129 | // return path;
130 | // }
131 |
132 | public Path createPath(int sides,float radius,float cx,float cy){
133 | Log.i("sajjad", "createPath: corner"+corner_radius);
134 | Path path = new Path();
135 | float angle = (float) (2.0 * Math.PI / sides);
136 | float corner = Math.abs(corner_radius)/radius;
137 | corner = Math.min(0.5f,corner); //should be between 0 and 0.5
138 | float currentAngle = 0;
139 | float currentpointY=0,y1=0,x1=0,currentpointX=0,nextpointY=0,nextpointX=0;
140 | float lessX =0;
141 | float lessY =0;
142 | float moreX =0;
143 | float moreY =0;
144 | x1= (float) (cx + (radius * Math.cos(angle*(sides))));
145 | y1 = (float) (cy + (radius * Math.sin(angle*(sides))));
146 |
147 | currentpointX= (float) (cx + (radius * Math.cos(currentAngle)));
148 | currentpointY = (float) (cy + (radius * Math.sin(currentAngle)));
149 | nextpointX= (float) (cx + (radius * Math.cos(angle)));
150 | nextpointY = (float) (cy + (radius * Math.sin(angle)));
151 |
152 | moreX = lerp(currentpointX,nextpointX,corner);
153 | moreY = lerp(currentpointY,nextpointY, corner);
154 |
155 | path.moveTo(moreX,moreY);
156 |
157 | for (int i = 1; i <= sides; i++) {
158 | currentAngle = angle * i;
159 | currentpointX= (float) (cx + (radius * Math.cos(currentAngle)));
160 | currentpointY = (float) (cy + (radius * Math.sin(currentAngle)));
161 | nextpointX= (float) (cx + (radius * Math.cos(angle * (i+1))));
162 | nextpointY = (float) (cy + (radius * Math.sin(angle * (i+1))));
163 |
164 | lessX = lerp(x1,currentpointX,1-corner);
165 | lessY = lerp(y1, currentpointY, 1-corner);
166 | moreX = lerp(currentpointX,nextpointX,corner);
167 | moreY = lerp(currentpointY,nextpointY, corner);
168 |
169 | path.lineTo(lessX,lessY);
170 | path.quadTo(
171 | currentpointX,
172 | currentpointY,
173 | moreX,
174 | moreY);
175 |
176 | x1 = currentpointX;
177 | y1 = currentpointY;
178 | }
179 | path.close();
180 | return path;
181 | }
182 | float lerp(float a, float b, float f)
183 | {
184 | return a + f * (b - a);
185 | }
186 |
187 | public void setBorderWidth(float borderWidth) {
188 | this.borderWidthPx = borderWidth;
189 | requiresShapeUpdate();
190 | }
191 |
192 | public void setBorderColor(@ColorInt int borderColor) {
193 | this.borderColor = borderColor;
194 | requiresShapeUpdate();
195 | }
196 |
197 | public void setBorderWidthDp(float borderWidth) {
198 | setBorderWidth(dpToPx(borderWidth));
199 | }
200 |
201 | public float getBorderWidth() {
202 | return borderWidthPx;
203 | }
204 |
205 | public float getBorderWidthDp() {
206 | return pxToDp(getBorderWidth());
207 | }
208 |
209 | public int getBorderColor() {
210 | return borderColor;
211 | }
212 |
213 | public float getBorderWidthPx() {
214 | return borderWidthPx;
215 | }
216 |
217 | public void setBorderWidthPx(float borderWidthPx) {
218 | this.borderWidthPx = borderWidthPx;
219 | requiresShapeUpdate();
220 | }
221 |
222 | public int getSide() {
223 | return side;
224 | }
225 |
226 | public void setSide(int side) {
227 | this.side = side;
228 | requiresShapeUpdate();
229 | }
230 |
231 | public float getCorner_radius() {
232 | return corner_radius;
233 | }
234 |
235 | public void setCorner_radius(float corner_radius) {
236 | this.corner_radius = corner_radius;
237 | requiresShapeUpdate();
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/android_neumorphic/src/main/java/com/github/sshadkany/shapes/RoundRectView.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.shapes;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Path;
9 | import android.graphics.RectF;
10 | import android.util.AttributeSet;
11 | import android.util.Log;
12 |
13 | import androidx.annotation.ColorInt;
14 | import androidx.annotation.NonNull;
15 | import androidx.annotation.Nullable;
16 |
17 | import com.github.florent37.manager.ClipPathManager;
18 |
19 | import com.github.sshadkany.android_neumorphic.R;
20 | import com.github.sshadkany.neo;
21 |
22 | /**
23 | * created by com.github.florent37
24 | * modified by sshadkany
25 | */
26 | public class RoundRectView extends neo {
27 |
28 | private final RectF rectF = new RectF();
29 | //region border
30 | private final Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
31 | private final RectF borderRectF = new RectF();
32 | private final Path borderPath = new Path();
33 | private float topLeftRadius = 0f;
34 | private float topRightRadius = 0f;
35 | private float bottomRightRadius = 0f;
36 | private float bottomLeftRadius = 0f;
37 | @ColorInt
38 | private int borderColor = Color.WHITE;
39 |
40 | private float borderWidthPx = 0f;
41 | private float adjust_factor = 1.2f;
42 |
43 | public RoundRectView(@NonNull Context context) {
44 | super(context);
45 | init(context, null);
46 | }
47 |
48 | public RoundRectView(@NonNull Context context, @Nullable AttributeSet attrs) {
49 | super(context, attrs);
50 | init(context, attrs);
51 | }
52 |
53 | public RoundRectView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
54 | super(context, attrs, defStyleAttr);
55 | init(context, attrs);
56 | }
57 |
58 | private void init(Context context, AttributeSet attrs) {
59 | Log.i("saj", "init: ");
60 | if (attrs != null) {
61 | final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.RoundRectView);
62 | topLeftRadius = attributes.getDimensionPixelSize(R.styleable.RoundRectView_shape_roundRect_topLeftRadius, (int) topLeftRadius);
63 | topRightRadius = attributes.getDimensionPixelSize(R.styleable.RoundRectView_shape_roundRect_topRightRadius, (int) topRightRadius);
64 | bottomLeftRadius = attributes.getDimensionPixelSize(R.styleable.RoundRectView_shape_roundRect_bottomLeftRadius, (int) bottomLeftRadius);
65 | bottomRightRadius = attributes.getDimensionPixelSize(R.styleable.RoundRectView_shape_roundRect_bottomRightRadius, (int) bottomRightRadius);
66 | borderColor = attributes.getColor(R.styleable.RoundRectView_shape_roundRect_borderColor, borderColor);
67 | borderWidthPx = attributes.getDimensionPixelSize(R.styleable.RoundRectView_shape_roundRect_borderWidth, (int) borderWidthPx);
68 | //****** neo styles ************
69 | style = attributes.getInteger(R.styleable.RoundRectView_shape_roundRect_shadow_type,drop_shadow);
70 | shadow_position_x = attributes.getDimensionPixelSize(R.styleable.RoundRectView_shape_roundRect_shadow_position_x, (int) shadow_position_x);
71 | shadow_position_y = attributes.getDimensionPixelSize(R.styleable.RoundRectView_shape_roundRect_shadow_position_y, (int) shadow_position_y);
72 | shadow_radius = attributes.getDimensionPixelSize(R.styleable.RoundRectView_shape_roundRect_radius, (int) shadow_radius);
73 | light_color = attributes.getColor(R.styleable.RoundRectView_shape_roundRect_light_color, light_color);
74 | dark_color = attributes.getColor(R.styleable.RoundRectView_shape_roundRect_dark_color, dark_color);
75 | background_color = attributes.getColor(R.styleable.RoundRectView_shape_roundRect_backgroundColor, background_color);
76 |
77 | Log.i("sajjad", "init: radius:" + shadow_radius +"\n"+"shadow_position_x"+shadow_position_x );
78 | //******************************
79 | attributes.recycle();
80 | }
81 | borderPaint.setStyle(Paint.Style.STROKE);
82 | final float abs_shadow_position_x = Math.abs(shadow_position_x);
83 | final float abs_shadow_position_y = Math.abs(shadow_position_y);
84 | final float abs_radius = Math.abs(shadow_radius)*adjust_factor;
85 |
86 | super.setClipPathCreator(new ClipPathManager.ClipPathCreator() {
87 | @Override
88 | public Path createClipPath(int width, int height) {
89 | if (borderWidthPx <= 0) {
90 | if (style == drop_shadow || style == small_inner_shadow) {
91 | rectF.set((2 * abs_shadow_position_x) + abs_radius, (2 * abs_shadow_position_y) + abs_radius, width - ((2 * abs_shadow_position_x) + abs_radius), height - ((2 * abs_shadow_position_y) + abs_radius));
92 | } else {
93 | rectF.set(0, 0, width, height);
94 | }
95 | }else{
96 | if (style == drop_shadow || style == small_inner_shadow) {
97 | rectF.set((2 * abs_shadow_position_x) + abs_radius + borderWidthPx / 2f,
98 | (2 * abs_shadow_position_y) + abs_radius +borderWidthPx / 2f,
99 | width - ((2 * abs_shadow_position_x) + abs_radius + borderWidthPx / 2f),
100 | height - ((2 * abs_shadow_position_y) + abs_radius + borderWidthPx / 2f));
101 | } else {
102 | rectF.set(borderWidthPx / 2f, borderWidthPx / 2f, width - borderWidthPx / 2f, height - borderWidthPx / 2f);
103 | }
104 | }
105 | return generatePath(rectF,
106 | limitSize(topLeftRadius, width, height),
107 | limitSize(topRightRadius, width, height),
108 | limitSize(bottomRightRadius, width, height),
109 | limitSize(bottomLeftRadius, width, height)
110 | );
111 | }
112 |
113 | @Override
114 | public boolean requiresBitmap() {
115 | return false;
116 | }
117 | });
118 | }
119 |
120 | protected float limitSize(float from, final float width, final float height) {
121 | return Math.min(from, Math.min(width, height));
122 | }
123 |
124 | @Override
125 | public void requiresShapeUpdate() {
126 | //TODO
127 | final float abs_shadow_position_x = Math.abs(shadow_position_x);
128 | final float abs_shadow_position_y = Math.abs(shadow_position_y);
129 | final float abs_radius = Math.abs(shadow_radius)*adjust_factor;
130 | if (style == drop_shadow || style == small_inner_shadow) {
131 | borderRectF.set(
132 | borderWidthPx / 2f + (2 * abs_shadow_position_x) + abs_radius,
133 | borderWidthPx / 2f +(2 * abs_shadow_position_y) + abs_radius,
134 | getWidth() - ((2 * abs_shadow_position_x) + abs_radius) - borderWidthPx / 2f,
135 | getHeight() - ((2 * abs_shadow_position_y) + abs_radius)- borderWidthPx / 2f);
136 | }else{
137 | borderRectF.set(borderWidthPx / 2f, borderWidthPx / 2f, getWidth() - borderWidthPx / 2f, getHeight() - borderWidthPx / 2f);
138 | }
139 |
140 | borderPath.set(generatePath(borderRectF,
141 | topLeftRadius,
142 | topRightRadius,
143 | bottomRightRadius,
144 | bottomLeftRadius
145 | ));
146 | super.requiresShapeUpdate();
147 | }
148 |
149 | @Override
150 | protected void dispatchDraw(Canvas canvas) {
151 | super.dispatchDraw(canvas);
152 |
153 | if (borderWidthPx > 0) {
154 | borderPaint.setStrokeWidth(borderWidthPx);
155 | borderPaint.setColor(borderColor);
156 | canvas.drawPath(borderPath, borderPaint);
157 | }
158 | }
159 |
160 | private Path generatePath(RectF rect, float topLeftRadius, float topRightRadius, float bottomRightRadius, float bottomLeftRadius) {
161 | return generatePath(false, rect, topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius);
162 | }
163 |
164 | private Path generatePath(boolean useBezier, RectF rect, float topLeftRadius, float topRightRadius, float bottomRightRadius, float bottomLeftRadius) {
165 | final Path path = new Path();
166 |
167 | final float left = rect.left;
168 | final float top = rect.top;
169 | final float bottom = rect.bottom;
170 | final float right = rect.right;
171 |
172 | final float maxSize = Math.min(rect.width() / 2f, rect.height() / 2f);
173 |
174 | float topLeftRadiusAbs = Math.abs(topLeftRadius);
175 | float topRightRadiusAbs = Math.abs(topRightRadius);
176 | float bottomLeftRadiusAbs = Math.abs(bottomLeftRadius);
177 | float bottomRightRadiusAbs = Math.abs(bottomRightRadius);
178 |
179 | if (topLeftRadiusAbs > maxSize) {
180 | topLeftRadiusAbs = maxSize;
181 | }
182 | if (topRightRadiusAbs > maxSize) {
183 | topRightRadiusAbs = maxSize;
184 | }
185 | if (bottomLeftRadiusAbs > maxSize) {
186 | bottomLeftRadiusAbs = maxSize;
187 | }
188 | if (bottomRightRadiusAbs > maxSize) {
189 | bottomRightRadiusAbs = maxSize;
190 | }
191 |
192 | path.moveTo(left + topLeftRadiusAbs, top);
193 | path.lineTo(right - topRightRadiusAbs, top);
194 |
195 | //float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo
196 | if (useBezier) {
197 | path.quadTo(right, top, right, top + topRightRadiusAbs);
198 | } else {
199 | final float arc = topRightRadius > 0 ? 90 : -270;
200 | path.arcTo(new RectF(right - topRightRadiusAbs * 2f, top, right, top + topRightRadiusAbs * 2f), -90, arc);
201 | }
202 | path.lineTo(right, bottom - bottomRightRadiusAbs);
203 | if (useBezier) {
204 | path.quadTo(right, bottom, right - bottomRightRadiusAbs, bottom);
205 | } else {
206 | final float arc = bottomRightRadiusAbs > 0 ? 90 : -270;
207 | path.arcTo(new RectF(right - bottomRightRadiusAbs * 2f, bottom - bottomRightRadiusAbs * 2f, right, bottom), 0, arc);
208 | }
209 | path.lineTo(left + bottomLeftRadiusAbs, bottom);
210 | if (useBezier) {
211 | path.quadTo(left, bottom, left, bottom - bottomLeftRadiusAbs);
212 | } else {
213 | final float arc = bottomLeftRadiusAbs > 0 ? 90 : -270;
214 | path.arcTo(new RectF(left, bottom - bottomLeftRadiusAbs * 2f, left + bottomLeftRadiusAbs * 2f, bottom), 90, arc);
215 | }
216 | path.lineTo(left, top + topLeftRadiusAbs);
217 | if (useBezier) {
218 | path.quadTo(left, top, left + topLeftRadiusAbs, top);
219 | } else {
220 | final float arc = topLeftRadiusAbs > 0 ? 90 : -270;
221 | path.arcTo(new RectF(left, top, left + topLeftRadiusAbs * 2f, top + topLeftRadiusAbs * 2f), 180, arc);
222 | }
223 | path.close();
224 |
225 | return path;
226 | }
227 |
228 | public float getTopLeftRadius() {
229 | return topLeftRadius;
230 | }
231 |
232 | public void setTopLeftRadius(float topLeftRadius) {
233 | this.topLeftRadius = topLeftRadius;
234 | requiresShapeUpdate();
235 | }
236 |
237 | public float getTopLeftRadiusDp() {
238 | return pxToDp(getTopLeftRadius());
239 | }
240 |
241 | public void setTopLeftRadiusDp(float topLeftRadius) {
242 | setTopLeftRadius(dpToPx(topLeftRadius));
243 | }
244 |
245 | public float getTopRightRadius() {
246 | return topRightRadius;
247 | }
248 |
249 | public void setTopRightRadius(float topRightRadius) {
250 | this.topRightRadius = topRightRadius;
251 | requiresShapeUpdate();
252 | }
253 |
254 | public float getTopRightRadiusDp() {
255 | return pxToDp(getTopRightRadius());
256 | }
257 |
258 | public void setTopRightRadiusDp(float topRightRadius) {
259 | setTopRightRadius(dpToPx(topRightRadius));
260 | }
261 |
262 | public float getBottomRightRadius() {
263 | return bottomRightRadius;
264 | }
265 |
266 | public void setBottomRightRadius(float bottomRightRadius) {
267 | this.bottomRightRadius = bottomRightRadius;
268 | requiresShapeUpdate();
269 | }
270 |
271 | public float getBottomRightRadiusDp() {
272 | return pxToDp(getBottomRightRadius());
273 | }
274 |
275 | public void setBottomRightRadiusDp(float bottomRightRadius) {
276 | setBottomRightRadius(dpToPx(bottomRightRadius));
277 | }
278 |
279 | public float getBottomLeftRadius() {
280 | return bottomLeftRadius;
281 | }
282 |
283 | public void setBottomLeftRadius(float bottomLeftRadius) {
284 | this.bottomLeftRadius = bottomLeftRadius;
285 | requiresShapeUpdate();
286 | }
287 |
288 | public float getBottomLeftRadiusDp() {
289 | return pxToDp(getBottomLeftRadius());
290 | }
291 |
292 | public void setBottomLeftRadiusDp(float bottomLeftRadius) {
293 | setBottomLeftRadius(dpToPx(bottomLeftRadius));
294 | }
295 |
296 | public float getBorderColor() {
297 | return borderColor;
298 | }
299 |
300 | public void setBorderColor(int borderColor) {
301 | this.borderColor = borderColor;
302 | requiresShapeUpdate();
303 | }
304 |
305 | public float getBorderWidth() {
306 | return borderWidthPx;
307 | }
308 |
309 | public void setBorderWidth(float borderWidth) {
310 | this.borderWidthPx = borderWidth;
311 | requiresShapeUpdate();
312 | }
313 |
314 | public float getBorderWidthDp() {
315 | return pxToDp(getBorderWidth());
316 | }
317 |
318 | public void setBorderWidthDp(float borderWidth) {
319 | setBorderWidth(dpToPx(borderWidth));
320 | }
321 | }
--------------------------------------------------------------------------------
/android_neumorphic/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 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | buildToolsVersion "29.0.3"
6 |
7 | defaultConfig {
8 | applicationId "com.github.sshadkany.android_neumorphic"
9 | minSdkVersion 16
10 | targetSdkVersion 29
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(dir: "libs", include: ["*.jar"])
27 | implementation 'androidx.appcompat:appcompat:1.1.0'
28 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
29 | implementation 'com.github.sshadkany:Android_neumorphic:1.2.0'
30 | testImplementation 'junit:junit:4.12'
31 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
32 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
33 |
34 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/github/sshadkany/android_neumorphic_test_app/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.github.sshadkany.android_neumorphic", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/Activity3.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 |
7 | public class Activity3 extends AppCompatActivity {
8 |
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | setContentView(R.layout.activity_3);
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/Activity5.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 |
7 | public class Activity5 extends AppCompatActivity {
8 |
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | setContentView(R.layout.activity_5);
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/ActivityButton.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.graphics.Matrix;
6 | import android.os.Bundle;
7 | import android.view.MotionEvent;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 |
12 | import com.github.sshadkany.neo;
13 |
14 | public class ActivityButton extends AppCompatActivity {
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | setContentView(R.layout.activity_button);
20 |
21 | final neo mybtn = findViewById(R.id.my_button);
22 | ViewGroup viewGroup = findViewById(R.id.my_button);
23 | final ImageView imageview = (ImageView) viewGroup.getChildAt(0);
24 | mybtn.setOnTouchListener(new View.OnTouchListener() {
25 | @Override
26 | public boolean onTouch(View v, MotionEvent event) {
27 | // is shape Contains Point ----> for detect place of Touch is in the shape or not
28 | if (mybtn.isShapeContainsPoint(event.getX(), event.getY())) {
29 | switch (event.getAction()) {
30 | case MotionEvent.ACTION_DOWN:
31 | // PRESSED
32 | //use only "small inner shadow" because its same size with "drop shadow" style and "big inner shadow" is bigger
33 | // "small inner shadow" = "drop shadow"
34 | // "big inner shadow" > "drop shadow"
35 | mybtn.setStyle(neo.small_inner_shadow);
36 | imageview.setScaleX(imageview.getScaleX() * 0.9f);
37 | imageview.setScaleY(imageview.getScaleY() * 0.9f);
38 | return true; // if you want to handle the touch event
39 | case MotionEvent.ACTION_UP:
40 | case MotionEvent.ACTION_CANCEL:
41 | // RELEASED
42 | mybtn.setStyle(neo.drop_shadow);
43 | imageview.setScaleX(1);
44 | imageview.setScaleY(1);
45 | return true; // if you want to handle the touch event
46 | }
47 | }
48 | return false;
49 | }
50 | });
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/ActivityStyle.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import android.os.Bundle;
4 |
5 | import androidx.appcompat.app.AppCompatActivity;
6 |
7 | public class ActivityStyle extends AppCompatActivity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | setContentView(R.layout.activity_style);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/CircleImageButtonActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.view.View;
8 |
9 | import com.github.sshadkany.CircleButton;
10 |
11 | public class CircleImageButtonActivity extends AppCompatActivity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_circle_image_button);
17 |
18 | CircleButton circle_button = findViewById(R.id.circle_image_button);
19 | circle_button.setOnClickListener(new View.OnClickListener() {
20 | @Override
21 | public void onClick(View v) {
22 | Log.i("1111", "onClick: i am clicked");
23 | }
24 | });
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.github.sshadkany.shapes.PolygonView;
10 |
11 | public class MainActivity extends AppCompatActivity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_main);
17 |
18 | ViewGroup myview1 = findViewById(R.id.btn2);
19 | final PolygonView childAt = (PolygonView)myview1.getChildAt(0);
20 | final PolygonView myview = (PolygonView) myview1;
21 | myview.setOnClickListener(new View.OnClickListener() {
22 | @Override
23 | public void onClick(View v) {
24 | int side = myview.getSide();
25 | if (side > 10){
26 | myview.setSide(5);
27 | childAt.setSide(5);
28 | }else {
29 | myview.setSide(side+1);
30 | childAt.setSide(side+1);
31 | }
32 | }
33 | });
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/NeoTextActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.github.sshadkany.neoText;
9 |
10 | public class NeoTextActivity extends AppCompatActivity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_neo_text);
16 | neoText neotext = findViewById(R.id.neotext);
17 | findViewById(R.id.backgroundLayout).setBackgroundColor(neotext.background_color);
18 | }
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/NestedButtonActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.view.View;
8 |
9 | import com.github.sshadkany.PolygonButton;
10 |
11 | public class NestedButtonActivity extends AppCompatActivity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(com.github.sshadkany.android_neumorphic_test_app.R.layout.activity_nested_button);
17 |
18 | PolygonButton polygonButton = findViewById(com.github.sshadkany.android_neumorphic_test_app.R.id.polygon_button);
19 |
20 | findViewById(com.github.sshadkany.android_neumorphic_test_app.R.id.backgroundLayout).setBackgroundColor(polygonButton.background_color); // set layout background color from neo object.
21 |
22 | polygonButton.setOnClickListener(new View.OnClickListener() {
23 | @Override
24 | public void onClick(View v) {
25 | Log.i("neo", "onClick: I am poly button !!");
26 | }
27 | });
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/PolygonButtonActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.view.View;
8 |
9 | import com.github.sshadkany.PolygonButton;
10 |
11 | public class PolygonButtonActivity extends AppCompatActivity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(com.github.sshadkany.android_neumorphic_test_app.R.layout.activity_polygon_button);
17 |
18 | PolygonButton polygonButton = findViewById(com.github.sshadkany.android_neumorphic_test_app.R.id.polygon_button);
19 |
20 | findViewById(com.github.sshadkany.android_neumorphic_test_app.R.id.backgroundLayout).setBackgroundColor(polygonButton.background_color); // set layout background color from neo object.
21 |
22 | polygonButton.setOnClickListener(new View.OnClickListener() {
23 | @Override
24 | public void onClick(View v) {
25 | Log.i("neo", "onClick: I am poly button !!");
26 | }
27 | });
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/RectButtonActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.view.View;
8 |
9 | import com.github.sshadkany.RectButton;
10 |
11 | public class RectButtonActivity extends AppCompatActivity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_rect_button);
17 |
18 | RectButton recButton = findViewById(R.id.rec_image_button);
19 |
20 | findViewById(R.id.backgroundLayout).setBackgroundColor(recButton.background_color); // set layout background color from neo object.
21 |
22 | recButton.setOnClickListener(new View.OnClickListener() {
23 | @Override
24 | public void onClick(View v) {
25 | Log.i("neo", "onClick: I am rect button !!");
26 | }
27 | });
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/github/sshadkany/android_neumorphic_test_app/SecendActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.annotation.SuppressLint;
6 | import android.os.Bundle;
7 | import android.view.MotionEvent;
8 | import android.view.View;
9 |
10 | import com.github.sshadkany.PolygonButton;
11 | import com.github.sshadkany.RectButton;
12 | import com.github.sshadkany.neo;
13 | import com.github.sshadkany.shapes.CircleView;
14 | import com.github.sshadkany.shapes.PolygonView;
15 | import com.github.sshadkany.shapes.RoundRectView;
16 |
17 | public class SecendActivity extends AppCompatActivity {
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_secend);
23 | ////*************************below code changes sides of polygon when its clicked ***************************************
24 | // final PolygonView my_polygon = findViewById(R.id.my_polygon);
25 | // my_polygon.setOnTouchListener(new View.OnTouchListener() {
26 | // @Override
27 | // public boolean onTouch(View v, MotionEvent event) {
28 | // if (my_polygon.isShapeContainsPoint(event.getX(), event.getY())) {
29 | // switch (event.getAction()) {
30 | // case MotionEvent.ACTION_DOWN:
31 | // // PRESSED
32 | // int side = my_polygon.getSide();
33 | // if (side > 12){
34 | // my_polygon.setSide(3);
35 | // }else {
36 | // my_polygon.setSide(side+1);
37 | // }
38 | // return true;
39 | // case MotionEvent.ACTION_UP:
40 | // case MotionEvent.ACTION_CANCEL:
41 | // // RELEASED
42 | // return true;
43 | // }
44 | // } else {
45 | // // RELEASED
46 | // return true;
47 | // }
48 | // return false;
49 | // }
50 | // });
51 | //************************************************************************************
52 |
53 |
54 | RoundRectView rectView = findViewById(R.id.roundRectView);
55 | findViewById(R.id.backgroundLayout).setBackgroundColor(rectView.background_color); // set layout background color from neo object.
56 |
57 |
58 | }
59 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
25 |
26 |
36 |
37 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
21 |
22 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_circle_image_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
24 |
25 |
26 |
27 |
33 |
34 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
28 |
29 |
30 |
31 |
41 |
42 |
50 |
51 |
52 |
53 |
54 |
55 |
68 |
69 |
79 |
80 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_neo_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
21 |
29 |
30 |
31 |
39 |
40 |
41 |
42 |
50 |
51 |
52 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_nested_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
16 |
17 |
18 |
24 |
25 |
26 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_polygon_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
16 |
17 |
23 |
24 |
25 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_rect_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
25 |
26 |
33 |
34 |
35 |
36 |
49 |
50 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_secend.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_style.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
21 |
31 |
32 |
42 |
43 |
54 |
55 |
64 |
65 |
74 |
75 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Android_neumorphic
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/test/java/com/github/sshadkany/android_neumorphic_test_app/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.github.sshadkany.android_neumorphic_test_app;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:4.0.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | google()
18 | jcenter()
19 | maven { url 'https://jitpack.io' }
20 | }
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Jun 25 20:07:57 IRDT 2020
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-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
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 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/screenshots/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/1.jpg
--------------------------------------------------------------------------------
/screenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/1.png
--------------------------------------------------------------------------------
/screenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/2.png
--------------------------------------------------------------------------------
/screenshots/3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/3.gif
--------------------------------------------------------------------------------
/screenshots/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/5.png
--------------------------------------------------------------------------------
/screenshots/button.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/button.gif
--------------------------------------------------------------------------------
/screenshots/button2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/button2.gif
--------------------------------------------------------------------------------
/screenshots/canvas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/canvas.png
--------------------------------------------------------------------------------
/screenshots/circleImageButton.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/circleImageButton.gif
--------------------------------------------------------------------------------
/screenshots/neoText.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/neoText.png
--------------------------------------------------------------------------------
/screenshots/nested.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/nested.png
--------------------------------------------------------------------------------
/screenshots/polygonButton.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/polygonButton.gif
--------------------------------------------------------------------------------
/screenshots/polygon_basin.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/polygon_basin.gif
--------------------------------------------------------------------------------
/screenshots/recbutton.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/recbutton.gif
--------------------------------------------------------------------------------
/screenshots/shadow style.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sshadkany/Android_neumorphic/d11803a0722496e37b9db18f6ba51f6697cf3a87/screenshots/shadow style.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':android_neumorphic'
2 | include ':app'
3 | rootProject.name = "Android_neumorphic"
--------------------------------------------------------------------------------