├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── atman.jks
├── build.gradle.kts
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── leo
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── leo
│ │ │ ├── MainActivity.kt
│ │ │ ├── ShadowActivity.java
│ │ │ ├── ShapeActivity.java
│ │ │ ├── StarShowActivity.java
│ │ │ ├── WikiActivity.java
│ │ │ └── loadingview
│ │ │ ├── MainLoadingActivity.kt
│ │ │ └── SecondActivity.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── cb_select_new.xml
│ │ ├── ic_launcher_background.xml
│ │ └── shap_progressbar_web.xml
│ │ ├── layout
│ │ ├── activity_loading_main.xml
│ │ ├── activity_main.xml
│ │ ├── activity_second.xml
│ │ ├── activity_shadow.xml
│ │ ├── activity_shape.xml
│ │ ├── activity_starshow.xml
│ │ └── activity_wiki_web.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── shadowlayout_logo.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── shadowlayout_logo.png
│ │ ├── mipmap-xhdpi
│ │ ├── back_icon_black.png
│ │ ├── check_off.png
│ │ ├── check_on.png
│ │ ├── game_6_right.png
│ │ ├── game_6_wrong.png
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ ├── regist_gou_false.png
│ │ ├── regist_gou_true.png
│ │ ├── shadowlayout_logo.png
│ │ ├── test_background_false.png
│ │ └── test_background_true.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── shadowlayout_logo.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── shadowlayout_logo.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── leo
│ └── ExampleUnitTest.java
├── build.gradle.kts
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle.kts
├── shadowLibrary
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── lihang
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── lihang
│ │ │ ├── GlideRoundTransform.java
│ │ │ ├── GlideRoundUtils.java
│ │ │ ├── ShadowLayout.java
│ │ │ ├── SmartLoadingView.java
│ │ │ └── help
│ │ │ ├── CirclBigView.java
│ │ │ ├── OkView.java
│ │ │ └── UIUtil.java
│ └── res
│ │ ├── anim
│ │ ├── alpha_enter.xml
│ │ ├── alpha_exit.xml
│ │ └── alpha_hide.xml
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ids.xml
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── lihang
│ └── ExampleUnitTest.java
└── showImages
├── GLIDE.md
├── README218.md
├── ShadowLayout_.png
├── SmartLoadingViewGuide.md
├── bindTextView.gif
├── corners.gif
├── first_show.gif
├── friend.md
├── glide1.png
├── glide2.jpg
├── glide3.png
├── glide4.png
├── groupUse2.gif
├── isSym.jpg
├── isSym_half.jpg
├── main.jpg
├── other_show.gif
├── pay_ali.png
├── pay_wx.png
├── problem.md
├── ripple.gif
├── shapeSelector2.gif
├── shape_gif.gif
├── show_3.3.1_1.jpg
├── show_3.3.1_2.jpg
├── show_3.3.1_3.jpg
├── singleShadow_bug.png
├── singleShadow_ok.png
└── stroke2.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | /.idea/caches/build_file_checksums.ser
6 | /.idea/libraries
7 | /.idea/modules.xml
8 | /.idea/workspace.xml
9 | .DS_Store
10 | /build
11 | /captures
12 | .externalNativeBuild
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 leo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 万能阴影布局-ShadowLayout
2 | [](https://jitpack.io/#lihangleo2/ShadowLayout)
3 | [](https://github.com/lihangleo2/ShadowLayout/blob/master/LICENSE)
4 |
5 |
6 | ## 特点功能
7 | 任何view被包裹后即可享受阴影,以及系统shape,selector功能(清空项目drawable文件夹)。具体介绍如下:
8 | ```
9 | 支持定制化阴影:
10 | 1. 随意修改阴影颜色值
11 | 2. 阴影圆角:可统一设置圆角,也可对某几个角单独设置
12 | 3. 阴影x,y偏移量
13 | 4. 随意修改阴影扩散程度,即阴影大小
14 | 5. 隐藏阴影:隐藏某边或多边阴影,或完全隐藏
15 | 6. 可随意代码动态修改阴影
16 |
17 | 不止于阴影;系统shape功能:项目中shape、selector、ripple统统拥有。解放你的双手,清空项目drawable文件夹
18 | 1. shape样式:pressed(按钮点击)、selected(按钮选择)、ripple(点击水波纹)
19 | 2. 背景色设置
20 | 3. stroke边框设置
21 | 4. 渐变色背景色设置
22 | 5. 按钮是否可被点击及不可点击背景
23 | 6. 可绑定textView后,可伴随文案变化,可伴随文案颜色变化
24 | 7. 支持设置图片背景,支持图片selector
25 | 8. 可以剪裁子view,比如用到播放器之类的地方,想要各种不同的圆角时,ShadowLayout可以轻松解决
26 |
27 | ```
28 |
29 |
30 | ## ShadowLayout动态
31 | * [ShadowLayout成长史](https://github.com/lihangleo2/ShadowLayout/wiki)
32 | * 注意:3.0后修改大量api及规范命名,如果还在用2.0,不方便转移的可查看[ShadowLayout2.0文档](https://github.com/lihangleo2/ShadowLayout/blob/master/showImages/README218.md)
33 | * 注意:3.4.0后适配了AndroidX
34 | * 注意:3.4.1加入了SmartLoadingView的使用。[点击查看SmartLoadingView的使用](https://github.com/lihangleo2/ShadowLayout/blob/master/showImages/SmartLoadingViewGuide.md)
35 |
36 | ## Demo
37 | 为录制流畅,截图分辨率比较模糊。可在下方扫描二维码下载apk,查看真机效果。
38 |
39 | 
40 |
41 |
42 | ## 效果展示
43 | 为录制流畅,截图分辨率模糊。可下载apk查看真机效果
44 | * ### 1.0功能展示
45 | |基础功能展示|各属性展示|随意更改颜色|
46 | |:---:|:---:|:---:|
47 | |
|
|
48 |
49 |
50 | * ### 2.0功能更新
51 | |2.1.6新增shape,selector功能|2.1.7isSym属性对比|2.1.8单独更改某圆角大小|
52 | |:---:|:---:|:---:|
53 | |
|
|
54 |
55 |
56 | * ### 3.0.1版本来袭
57 | |stroke边框及点击|shape及图片selector|组合使用|
58 | |:---:|:---:|:---:|
59 | |
|
|
60 |
61 |
62 | * ### 3.1.0新增ripple及渐变色及3.1.1绑定textView
63 | |3.1.0渐变色及ripple|3.1.1绑定textView|
64 | |:---:|:---:|
65 | |
|
66 |
67 |
68 | * ### 3.3.1功能更新
69 | |增加虚线边框|单边虚线|边框和ripple共存|
70 | |:---:|:---:|:---:|
71 | |
|
|
72 |
73 |
74 |
75 | ## 添加依赖
76 |
77 | - 项目build.gradle添加如下
78 | ```java
79 | allprojects {
80 | repositories {
81 | maven { url 'https://jitpack.io' }
82 | }
83 | }
84 | ```
85 | - app build.gradle添加如下
86 | ```java
87 | dependencies {
88 |
89 | //使用AndroidX版本
90 | implementation 'com.github.lihangleo2:ShadowLayout:3.4.1'
91 |
92 | //不使用AndroidX
93 | //implementation 'com.github.lihangleo2:ShadowLayout:3.3.3'
94 | }
95 | ```
96 |
97 |
98 | ## 热门问题
99 |
100 | - [glide版本冲突终极解决方案](https://github.com/lihangleo2/ShadowLayout/blob/master/showImages/GLIDE.md)
101 |
102 | - [3.2.4依赖问题解决](https://github.com/lihangleo2/ShadowLayout/blob/master/showImages/problem.md)
103 |
104 |
105 |
106 | ## 基本使用
107 | * #### 一、阴影的简单使用
108 | ```xml
109 |
118 |
119 |
128 |
129 | ```
130 |
131 |
132 | * #### 二、stroke边框的简单使用
133 | ```xml
134 |
140 |
141 |
149 |
150 | ```
151 |
152 |
153 | * #### 三、shape selector的简单使用
154 | ```xml
155 |
165 |
166 |
174 |
175 | ```
176 |
177 |
178 | * #### 四、图片 selector的简单使用
179 | ```xml
180 |
190 |
191 |
192 |
200 |
201 |
202 | ```
203 | 如果你觉得麻烦,你还可以这样
204 | ```xml
205 |
214 | ```
215 |
216 |
217 |
218 | * #### 五、渐变色的简单使用
219 | ```xml
220 |
227 |
228 |
234 |
235 |
236 | ```
237 |
238 |
239 |
240 | * #### 六、水波纹ripple的使用
241 | ```xml
242 |
252 |
253 |
259 |
260 |
261 | ```
262 |
263 |
264 |
265 | * #### 七、绑定textView,伴随文案及颜色变化
266 | ```xml
267 |
281 |
282 |
291 |
292 |
293 | ```
294 |
295 |
296 |
297 | * #### 八、单条虚线、hl_shapeMode:dashLine的使用(以长边为宽度,短边为虚线width。由此可知,如下例子:为横向虚线)
298 | ```xml
299 |
308 | ```
309 |
310 |
311 |
312 | * #### 九、剪裁各种难以搞定的圆角(如特殊视频圆角剪裁,注意任何view被ShadowLayout包裹都能剪裁)
313 | ```
314 | 如下代码,剪裁视频播放器(注明2点)
315 | - app:hl_layoutBackground="@color/transparent" 取消shadowLayout默认背景白色改透明
316 | - app:clickable="false" 取消shadowLayout的点击焦点(用于解决recyclerView里的点击冲突)
317 | ```
318 |
319 | ```xml
320 |
329 |
334 |
335 | ```
336 |
337 |
338 |
339 | ## 属性表格(Attributes)
340 | ### 一、关于阴影
341 |
342 | |name|format|description|
343 | |:---:|:---:|:---:|
344 | |hl_shadowHidden|boolean|是否隐藏阴影(默认false)|
345 | |hl_shadowColor|color|阴影颜色值,如不带透明,默认透明16%|
346 | |hl_shadowLimit|dimension|阴影扩散程度(dp)|
347 | |hl_shadowOffsetX|dimension|x轴的偏移量(dp)|
348 | |hl_shadowOffsetY|dimension|y轴的偏移量(dp)|
349 | |hl_shadowHiddenLeft|boolean|左边的阴影不可见,其他3边同理|
350 | |hl_shadowSymmetry|boolean|控件区域是否对称(默认true)根据此图理解
|
351 |
352 |
353 |
354 | ### 二、关于圆角
355 | |name|format|description|
356 | |:---:|:---:|:---:|
357 | |hl_cornerRadius|dimension|包括阴影圆角、shape圆角(dp)|
358 | |hl_cornerRadius_leftTop|dimension|左上圆角,其他角还是hl_cornerRadius值;同理其他3角(dp)|
359 |
360 |
361 |
362 | ### 三、关于shape
363 | * #### 3.1、关于shape样式及背景色
364 | |name|format|description|
365 | |:---:|:---:|:---:|
366 | |hl_shapeMode|enum|有4种模式:pressed和selected。和系统shape一样,以及ripple点击水波纹。新增dashLine|
367 | |hl_layoutBackground|reference/color|背景色,为false时展示:可以是颜色值,图片以及系统shape样式|
368 | |hl_layoutBackground_true|reference/color|背景色,为true时展示:可以是颜色值,图片以及系统shape样式|
369 |
370 |
371 |
372 | * #### 3.2、关于stroke边框
373 | |name|format|description|
374 | |:---:|:---:|:---:|
375 | |hl_strokeWith|dimension|stroke边框线宽度|
376 | |hl_strokeColor|color|边框颜色值,为false展示|
377 | |hl_strokeColor_true|color|边框颜色值,为true展示|
378 | |hl_stroke_dashWidth|dimension|虚线边框的实线部分长度|
379 | |hl_stroke_dashGap|dimension|虚线边框的间隔宽度|
380 |
381 |
382 |
383 | * #### 3.3、关于渐变色
384 | |name|format|description|
385 | |:---:|:---:|:---:|
386 | |hl_startColor|color|渐变起始颜色(设置渐变色后,hl_layoutBackground属性将无效)|
387 | |hl_centerColor|color|渐变中间颜色(可不填)|
388 | |hl_endColor|color|渐变的终止颜色|
389 | |hl_angle|integer|渐变角度(默认0)|
390 |
391 |
392 |
393 | * #### 3.4、关于绑定textView
394 | |name|format|description|
395 | |:---:|:---:|:---:|
396 | |hl_bindTextView|reference|当前要绑定的textView的id|
397 | |hl_textColor|color|shape为false是展示的文案颜色|
398 | |hl_textColor_true|color|shape为true是展示的文案颜色|
399 | |hl_text|string|shape为false时展示的文案|
400 | |hl_text_true|string|shape为true时展示的文案|
401 |
402 |
403 |
404 |
405 | ### 四、关于clickable
406 | |name|format|description|
407 | |:---:|:---:|:---:|
408 | |clickable|boolean|设置ShadowLayout是否可以被点击;代码设置:mShadowLayout.setClickable(false);(默认true)|
409 | |hl_layoutBackground_clickFalse|reference/color|Clickable为false时,要展示的图片或颜色。(此属性应当在app:hl_shapeMode="pressed"时生效)|
410 |
411 |
412 |
413 | ## 方法表格(Method)
414 | |name|format|description|
415 | |:---:|:---:|:---:|
416 | |setShadowHidden()|boolean|是否隐藏阴影|
417 | |setShadowColor()|color|设置阴影颜色值|
418 | |setShadowLimit()|dimension|设置阴影扩散区域|
419 | |setOffsetX()|dimension|设置阴影的X轴偏移量|
420 | |setOffsetY()|dimension|设置阴影的Y轴偏移量|
421 | |setShadowHiddenTop()|boolean|隐藏上边阴影(同理其他三遍)|
422 | |setCornerRadius()|dimension|设置圆角|
423 | |setLayoutBackground()|color|设置false时的背景颜色值|
424 | |setLayoutBackgroundTrue()|color|设置true时的背景颜色值|
425 | |setStrokeColor()|color|设置false时的边框颜色|
426 | |setStrokeColorTrue()|color|设置true时的边框颜色|
427 | |setStrokeWidth()|dimension|设置边框的粗细|
428 | |setClickable()|boolean|设置ShadowLayout是否可以点击|
429 | |setSpecialCorner()|integer|设置ShadowLayout四个角的大小|
430 | |setGradientColor()|integer|设置渐变颜色|
431 |
432 |
433 | ## 赞赏
434 |
435 | 如果你喜欢 ShadowLayout 的功能,感觉 ShadowLayout 帮助到了你,可以点右上角 "Star" 支持一下 谢谢! ^_^
436 | 你也还可以扫描下面的二维码~ 请作者喝一杯咖啡。或者遇到工作中比较难实现的需求请作者帮忙。
437 |
438 |  
439 |
440 |
441 | 如果在捐赠留言中备注名称,将会被记录到列表中~ 如果你也是github开源作者,捐赠时可以留下github项目地址或者个人主页地址,链接将会被添加到列表中
442 | ### [捐赠列表](https://github.com/lihangleo2/ShadowLayout/blob/master/showImages/friend.md)
443 |
444 |
445 |
446 | ## 其他作品
447 | [万能ViewPager2适配器SmartViewPager2Adapter](https://github.com/lihangleo2/ViewPager2Demo)
448 | [RichEditTextCopyToutiao](https://github.com/lihangleo2/RichEditTextCopyToutiao)
449 | [mPro](https://github.com/lihangleo2/mPro)
450 | [SmartLoadingView](https://github.com/lihangleo2/SmartLoadingView)
451 |
452 |
453 |
454 |
455 | ## 关于作者。
456 | Android工作多年了。前进的道路上是孤独的。如果你在学习的路上也感觉孤独,请和我一起。让我们在学习道路上少些孤独
457 |
458 | * QQ群: 209010674
(点击图标,可以直接加入)
459 |
460 |
461 |
462 | ## Licenses
463 |
464 | ```
465 | MIT License
466 |
467 | Copyright (c) 2019 leo
468 |
469 | Permission is hereby granted, free of charge, to any person obtaining a copy
470 | of this software and associated documentation files (the "Software"), to deal
471 | in the Software without restriction, including without limitation the rights
472 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
473 | copies of the Software, and to permit persons to whom the Software is
474 | furnished to do so, subject to the following conditions:
475 |
476 | The above copyright notice and this permission notice shall be included in all
477 | copies or substantial portions of the Software.
478 | ```
479 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/atman.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/atman.jks
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import java.text.SimpleDateFormat
2 | import java.util.Date
3 | import java.util.Locale
4 |
5 | plugins {
6 | id("com.android.application")
7 | id("org.jetbrains.kotlin.android")
8 | }
9 |
10 | android {
11 | namespace = "com.leo"
12 | compileSdk = 31
13 |
14 | defaultConfig {
15 | applicationId = "com.leo"
16 | minSdk = 21
17 | targetSdk = 31
18 | versionCode = 341
19 | versionName = "3.4.1"
20 |
21 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
22 | //设置apk和aab的文件名
23 | val buildAppTime = SimpleDateFormat("MMddHHmm", Locale.getDefault()).format(Date())
24 | setProperty("archivesBaseName", "ShadowLayout_${buildAppTime}_v${versionName}")
25 | }
26 |
27 | //签名 (需要签名文件)
28 | signingConfigs {
29 |
30 | create("testKey") {
31 | storeFile = file("atman.jks")
32 | storePassword = "5888062"
33 | keyAlias = "fastMedical"
34 | keyPassword = "5888062"
35 | }
36 | }
37 |
38 | buildTypes {
39 | release {
40 | isMinifyEnabled = false
41 | signingConfig = signingConfigs.getByName("testKey")
42 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
43 | }
44 | }
45 |
46 |
47 | flavorDimensions += "default"
48 | productFlavors {
49 | create("google")
50 | }
51 |
52 | productFlavors.all {
53 | manifestPlaceholders["APP_CHANNEL_VALUE"] = name
54 | }
55 |
56 | compileOptions {
57 | sourceCompatibility = JavaVersion.VERSION_1_8
58 | targetCompatibility = JavaVersion.VERSION_1_8
59 | }
60 | kotlinOptions {
61 | jvmTarget = "1.8"
62 | }
63 |
64 | buildFeatures {
65 | dataBinding = true
66 | }
67 |
68 | }
69 |
70 | dependencies {
71 |
72 | implementation("androidx.core:core-ktx:1.8.0")
73 | implementation("androidx.appcompat:appcompat:1.4.1")
74 | implementation("com.google.android.material:material:1.5.0")
75 | implementation("androidx.constraintlayout:constraintlayout:2.1.4")
76 | implementation("com.google.firebase:firebase-crashlytics-buildtools:2.9.9")
77 | testImplementation("junit:junit:4.13.2")
78 | androidTestImplementation("androidx.test.ext:junit:1.1.5")
79 | androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
80 | implementation(project(mapOf("path" to ":shadowLibrary")))
81 | }
--------------------------------------------------------------------------------
/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
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/leo/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.leo
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.leo", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
31 |
32 |
37 |
38 |
43 |
44 |
49 |
50 |
51 |
57 |
58 |
59 |
64 |
65 |
66 |
67 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/app/src/main/java/com/leo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.leo
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.view.View
6 | import androidx.appcompat.app.AppCompatActivity
7 | import androidx.databinding.DataBindingUtil
8 | import com.leo.databinding.ActivityMainBinding
9 | import com.leo.loadingview.MainLoadingActivity
10 |
11 | /**
12 | * 首页展示
13 | */
14 | class MainActivity : AppCompatActivity() {
15 | var mBinding: ActivityMainBinding? = null
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 | mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
19 | mBinding?.run {
20 | //ShadowLayout的使用
21 | ShadowLayoutShadow.setOnClickListener {
22 | startActivity(Intent(this@MainActivity, ShadowActivity::class.java))
23 | }
24 |
25 | ShadowLayoutShape.setOnClickListener {
26 | startActivity(Intent(this@MainActivity, ShapeActivity::class.java))
27 | }
28 |
29 | ShadowLayoutWiki.setOnClickListener {
30 | startActivity(Intent(this@MainActivity, WikiActivity::class.java))
31 | }
32 |
33 | //3.4.1 SmartLoadingView的使用
34 | smartFullscreenAuto.setOnClickListener {
35 | smartFullscreenAuto.startLoading()
36 | smartFullscreenAuto.finishLoadingWithFullScreen(this@MainActivity, MainLoadingActivity::class.java)
37 | }
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/leo/ShadowActivity.java:
--------------------------------------------------------------------------------
1 | package com.leo;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 |
6 | import com.leo.databinding.ActivityShadowBinding;
7 |
8 | import androidx.annotation.Nullable;
9 | import androidx.appcompat.app.AppCompatActivity;
10 | import androidx.databinding.DataBindingUtil;
11 |
12 | /**
13 | * Created by leo
14 | * on 2020/10/27.
15 | * shadow阴影的各项使用
16 | */
17 | public class ShadowActivity extends AppCompatActivity {
18 | ActivityShadowBinding binding;
19 |
20 | @Override
21 | protected void onCreate(@Nullable Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | binding = DataBindingUtil.setContentView(this, R.layout.activity_shadow);
24 | binding.shadowLayoutBarLeft.setOnClickListener(v ->{
25 | finish();
26 | });
27 |
28 | binding.ShadowLayoutIntent.setOnClickListener(v ->{
29 | startActivity(new Intent(ShadowActivity.this, StarShowActivity.class));
30 | });
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/leo/ShapeActivity.java:
--------------------------------------------------------------------------------
1 | package com.leo;
2 |
3 | import android.os.Bundle;
4 | import com.leo.databinding.ActivityShapeBinding;
5 |
6 | import androidx.annotation.Nullable;
7 | import androidx.appcompat.app.AppCompatActivity;
8 | import androidx.databinding.DataBindingUtil;
9 |
10 | /**
11 | * shape功能的各项使用
12 | */
13 | public class ShapeActivity extends AppCompatActivity {
14 | ActivityShapeBinding binding;
15 |
16 | @Override
17 | protected void onCreate(@Nullable Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | binding = DataBindingUtil.setContentView(this, R.layout.activity_shape);
20 | binding.ShadowLayoutImage.setSelected(true);
21 | binding.ShadowLayoutImage.setOnClickListener(v -> {
22 | binding.ShadowLayoutImage.setSelected(!binding.ShadowLayoutImage.isSelected());
23 | });
24 | binding.shadowLayoutBarLeft.setOnClickListener(v -> {
25 | finish();
26 | });
27 |
28 | binding.shadowLayoutSelect.setOnClickListener(v -> {
29 | binding.shadowLayoutSelect.setSelected(!binding.shadowLayoutSelect.isSelected());
30 | });
31 |
32 | binding.shadowLayoutBindView.setOnClickListener(v -> {
33 | binding.shadowLayoutBindView.setSelected(!binding.shadowLayoutBindView.isSelected());
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/leo/StarShowActivity.java:
--------------------------------------------------------------------------------
1 | package com.leo;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.ImageView;
7 | import android.widget.SeekBar;
8 |
9 | import androidx.appcompat.app.AppCompatActivity;
10 |
11 | /**
12 | * 动态设置阴影页
13 | */
14 | public class StarShowActivity extends AppCompatActivity implements View.OnClickListener {
15 | private com.lihang.ShadowLayout ShadowLayout;
16 | private SeekBar skbar_x;
17 | private SeekBar skbar_y;
18 | private SeekBar skbar_limit;
19 | private SeekBar skbar_corner;
20 | private int alpha;
21 | private SeekBar skbar_alpha;
22 | private int red;
23 | private SeekBar skbar_red;
24 | private int green;
25 | private SeekBar skbar_green;
26 | private int blue;
27 | private SeekBar skbar_blue;
28 | private ImageView tab_topShow;
29 | private ImageView tab_bottomShow;
30 | private ImageView tab_rightShow;
31 | private ImageView tab_leftShow;
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.activity_starshow);
37 | ShadowLayout = findViewById(R.id.ShadowLayout);
38 | skbar_x = findViewById(R.id.skbar_x);
39 | skbar_y = findViewById(R.id.skbar_y);
40 | skbar_limit = findViewById(R.id.skbar_limit);
41 | skbar_corner = findViewById(R.id.skbar_corner);
42 | skbar_alpha = findViewById(R.id.skbar_alpha);
43 | skbar_red = findViewById(R.id.skbar_red);
44 | skbar_green = findViewById(R.id.skbar_green);
45 | skbar_blue = findViewById(R.id.skbar_blue);
46 | tab_topShow = findViewById(R.id.tab_topShow);
47 | tab_topShow.setOnClickListener(this);
48 | tab_bottomShow = findViewById(R.id.tab_bottomShow);
49 | tab_bottomShow.setOnClickListener(this);
50 | tab_rightShow = findViewById(R.id.tab_rightShow);
51 | tab_rightShow.setOnClickListener(this);
52 | tab_leftShow = findViewById(R.id.tab_leftShow);
53 | tab_leftShow.setOnClickListener(this);
54 |
55 |
56 | skbar_corner.setMax((int) (ShadowLayout.getCornerRadius() * 3));
57 | skbar_corner.setProgress((int) ShadowLayout.getCornerRadius());
58 | skbar_corner.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
59 | @Override
60 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
61 | ShadowLayout.setCornerRadius(progress);
62 | }
63 |
64 | @Override
65 | public void onStartTrackingTouch(SeekBar seekBar) {
66 |
67 | }
68 |
69 | @Override
70 | public void onStopTrackingTouch(SeekBar seekBar) {
71 |
72 | }
73 | });
74 |
75 |
76 | skbar_limit.setMax((int) (ShadowLayout.getShadowLimit() * 3));
77 | skbar_limit.setProgress((int) ShadowLayout.getShadowLimit());
78 | skbar_limit.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
79 | @Override
80 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
81 | ShadowLayout.setShadowLimit(progress);
82 | }
83 |
84 | @Override
85 | public void onStartTrackingTouch(SeekBar seekBar) {
86 |
87 | }
88 |
89 | @Override
90 | public void onStopTrackingTouch(SeekBar seekBar) {
91 |
92 | }
93 | });
94 |
95 |
96 | skbar_x.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
97 | @Override
98 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
99 | ShadowLayout.setShadowOffsetX(progress - 100);
100 | }
101 |
102 | @Override
103 | public void onStartTrackingTouch(SeekBar seekBar) {
104 |
105 | }
106 |
107 | @Override
108 | public void onStopTrackingTouch(SeekBar seekBar) {
109 |
110 | }
111 | });
112 |
113 |
114 | skbar_y.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
115 | @Override
116 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
117 | ShadowLayout.setShadowOffsetY(progress - 100);
118 | }
119 |
120 | @Override
121 | public void onStartTrackingTouch(SeekBar seekBar) {
122 |
123 | }
124 |
125 | @Override
126 | public void onStopTrackingTouch(SeekBar seekBar) {
127 |
128 | }
129 | });
130 |
131 |
132 | skbar_alpha.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
133 | @Override
134 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
135 | alpha = progress;
136 | ShadowLayout.setShadowColor(Color.argb(alpha, red, green, blue));
137 | }
138 |
139 | @Override
140 | public void onStartTrackingTouch(SeekBar seekBar) {
141 |
142 | }
143 |
144 | @Override
145 | public void onStopTrackingTouch(SeekBar seekBar) {
146 |
147 | }
148 | });
149 |
150 |
151 | skbar_red.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
152 | @Override
153 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
154 | red = progress;
155 | ShadowLayout.setShadowColor(Color.argb(alpha, red, green, blue));
156 | }
157 |
158 | @Override
159 | public void onStartTrackingTouch(SeekBar seekBar) {
160 |
161 | }
162 |
163 | @Override
164 | public void onStopTrackingTouch(SeekBar seekBar) {
165 |
166 | }
167 | });
168 |
169 |
170 | skbar_green.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
171 | @Override
172 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
173 | green = progress;
174 | ShadowLayout.setShadowColor(Color.argb(alpha, red, green, blue));
175 | }
176 |
177 | @Override
178 | public void onStartTrackingTouch(SeekBar seekBar) {
179 |
180 | }
181 |
182 | @Override
183 | public void onStopTrackingTouch(SeekBar seekBar) {
184 |
185 | }
186 | });
187 |
188 |
189 | skbar_blue.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
190 | @Override
191 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
192 | blue = progress;
193 | ShadowLayout.setShadowColor(Color.argb(alpha, red, green, blue));
194 | }
195 |
196 | @Override
197 | public void onStartTrackingTouch(SeekBar seekBar) {
198 |
199 | }
200 |
201 | @Override
202 | public void onStopTrackingTouch(SeekBar seekBar) {
203 |
204 | }
205 | });
206 |
207 |
208 | }
209 |
210 |
211 | @Override
212 | public void onClick(View v) {
213 | switch (v.getId()) {
214 | case R.id.tab_topShow:
215 | ShadowLayout.setShadowHiddenTop(select(tab_topShow));
216 | break;
217 |
218 | case R.id.tab_bottomShow:
219 | ShadowLayout.setShadowHiddenBottom(select(tab_bottomShow));
220 | break;
221 |
222 | case R.id.tab_leftShow:
223 | ShadowLayout.setShadowHiddenLeft(select(tab_leftShow));
224 | break;
225 |
226 | case R.id.tab_rightShow:
227 | ShadowLayout.setShadowHiddenRight(select(tab_rightShow));
228 | break;
229 | }
230 | }
231 |
232 |
233 | public boolean select(ImageView imageView) {
234 | if (imageView.isSelected()) {
235 | imageView.setSelected(false);
236 | return false;
237 | } else {
238 | imageView.setSelected(true);
239 | return true;
240 | }
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/app/src/main/java/com/leo/WikiActivity.java:
--------------------------------------------------------------------------------
1 | package com.leo;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.net.http.SslError;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 | import android.view.KeyEvent;
10 | import android.view.View;
11 | import android.webkit.JavascriptInterface;
12 | import android.webkit.SslErrorHandler;
13 | import android.webkit.WebChromeClient;
14 | import android.webkit.WebSettings;
15 | import android.webkit.WebView;
16 | import android.webkit.WebViewClient;
17 | import android.widget.Toast;
18 |
19 | import com.leo.databinding.ActivityWikiWebBinding;
20 | import com.lihang.ShadowLayout;
21 |
22 | import androidx.annotation.Nullable;
23 | import androidx.appcompat.app.AppCompatActivity;
24 | import androidx.databinding.DataBindingUtil;
25 |
26 | /**
27 | * Created by leo
28 | * on 2020/8/5.
29 | * ShadowLayout成长历史
30 | */
31 | public class WikiActivity extends AppCompatActivity {
32 | ActivityWikiWebBinding binding;
33 | String urlStr;
34 |
35 | @Override
36 | protected void onCreate(@Nullable Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 | binding = DataBindingUtil.setContentView(this, R.layout.activity_wiki_web);
39 |
40 |
41 | // urlStr = "https://github.com/lihangleo2";
42 | urlStr = "https://github.com/lihangleo2/ShadowLayout/wiki";
43 | //声明WebSettings子类
44 | WebSettings webSettings = binding.webView.getSettings();
45 |
46 | webSettings.setJavaScriptEnabled(true);
47 | //设置自适应屏幕,两者合用
48 | webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
49 | webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
50 | webSettings.setDomStorageEnabled(true);
51 |
52 | //缩放操作
53 | webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
54 | webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
55 | webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
56 |
57 | //其他细节操作
58 | webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //开启缓存LOAD_CACHE_ELSE_NETWORK//LOAD_NO_CACHE关闭缓存
59 | webSettings.setAllowFileAccess(true); //设置可以访问文件
60 | webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
61 | webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
62 | webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
63 |
64 |
65 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
66 | //解决webView不加载图片
67 | webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
68 | }
69 |
70 |
71 | ////步骤3. 复写shouldOverrideUrlLoading()方法,使得打开网页时不调用系统浏览器, 而是在本WebView中显示
72 | binding.webView.setWebViewClient(new WebViewClient() {
73 | @Override
74 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
75 | try {
76 | if (url.startsWith("http:") || url.startsWith("https:")) {
77 | view.loadUrl(url);
78 | return false;
79 | } else {
80 | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
81 | startActivity(intent);
82 | return true;
83 | }
84 | } catch (Exception e) {
85 | return true;
86 | }
87 |
88 | }
89 |
90 | @Override
91 | public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
92 |
93 |
94 | if (binding.progressBar != null) {
95 | binding.progressBar.setVisibility(View.GONE);
96 | }
97 |
98 | Toast.makeText(WikiActivity.this, "网页加载失败", Toast.LENGTH_SHORT).show();
99 |
100 | }
101 |
102 |
103 | // onReceivedSslError
104 |
105 |
106 | @Override
107 | public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
108 |
109 | handler.proceed();
110 | }
111 |
112 | //webView加载结束后的动作
113 | @Override
114 | public void onPageFinished(WebView view, String url) {
115 | //设定加载结束的操作
116 | if (binding.progressBar != null) {
117 | binding.progressBar.setVisibility(View.GONE);
118 | }
119 |
120 |
121 | }
122 | });
123 |
124 |
125 | binding.webView.setWebChromeClient(new WebChromeClient() {
126 |
127 | @Override
128 | public void onProgressChanged(WebView view, int newProgress) {
129 | if (binding.progressBar.getVisibility() == View.GONE && newProgress != 100) {
130 | //点击webView内部,进度条可见
131 | binding.progressBar.setVisibility(View.VISIBLE);
132 | }
133 |
134 | if (newProgress == 100 && binding.progressBar.getVisibility() == View.VISIBLE) {
135 | //bug:不走finish所以不能设置不可见
136 | binding.progressBar.setVisibility(View.GONE);
137 | }
138 |
139 |
140 | if (binding.progressBar != null) {
141 | binding.progressBar.setProgress(newProgress);
142 | }
143 | }
144 | });
145 |
146 |
147 | binding.webView.loadUrl(urlStr);
148 | //js互调相关
149 | binding.webView.addJavascriptInterface(new CrosswalkInterface(this), "JSbridge");
150 |
151 |
152 | binding.shadowLayoutBarLeft.setOnClickListener(v -> {
153 | if (binding.webView.canGoBack()) {
154 | binding.webView.goBack();
155 | } else {
156 | finish();
157 | }
158 | });
159 |
160 | }
161 |
162 |
163 | @Override
164 | public boolean onKeyDown(int keyCode, KeyEvent event) {
165 | if (keyCode == KeyEvent.KEYCODE_BACK && binding.webView.canGoBack()) {
166 | binding.webView.goBack();// 返回前一个页面
167 | return true;
168 | }
169 | return super.onKeyDown(keyCode, event);
170 | }
171 |
172 |
173 | @Override
174 | protected void onResume() {
175 | super.onResume();
176 | if (binding.webView != null) {
177 | binding.webView.onResume();
178 | }
179 | }
180 |
181 | @Override
182 | protected void onPause() {
183 | super.onPause();
184 | if (binding.webView != null) {
185 | binding.webView.onPause();
186 | }
187 | }
188 |
189 | @Override
190 | protected void onDestroy() {
191 | super.onDestroy();
192 | if (binding.webView != null) {
193 | binding.webView.destroy();
194 | }
195 | }
196 |
197 | public class CrosswalkInterface {
198 | Context context;
199 |
200 | public CrosswalkInterface(Context context) {
201 | this.context = context;
202 | }
203 |
204 | @JavascriptInterface
205 | public void exit() {
206 | finish();
207 | }
208 | }
209 |
210 |
211 | }
212 |
--------------------------------------------------------------------------------
/app/src/main/java/com/leo/loadingview/MainLoadingActivity.kt:
--------------------------------------------------------------------------------
1 | package com.leo.loadingview
2 |
3 |
4 | import android.os.Bundle
5 | import android.widget.Toast
6 | import androidx.appcompat.app.AppCompatActivity
7 | import androidx.databinding.DataBindingUtil
8 | import com.leo.R
9 | import com.leo.databinding.ActivityLoadingMainBinding
10 |
11 |
12 | class MainLoadingActivity : AppCompatActivity() {
13 | private lateinit var mBinding: ActivityLoadingMainBinding
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | mBinding = DataBindingUtil.setContentView(this, R.layout.activity_loading_main)
17 | supportActionBar?.title = "SmartLoadingView的使用"
18 | //
19 | mBinding.run {
20 | /**
21 | * 1.smart_full_screen:全屏
22 | * 不支持关注模式
23 | * */
24 |
25 | //finishLoadingWithFullScreen 的使用
26 | smartFullscreenAuto.setOnClickListener {
27 | //1.1、开始加载
28 | smartFullscreenAuto.startLoading()
29 |
30 | //1.2、模拟2s后,加载成功并跳转(finishLoadingWithFullScreen会自动跳转页面并关闭当前页面)
31 | it.postDelayed({
32 | smartFullscreenAuto.finishLoadingWithFullScreen(this@MainLoadingActivity, SecondActivity::class.java)
33 | //也可以自己处理动画回调
34 | //smartFullscreenAuto.finishLoading(true) {}
35 | }, 2000)
36 | }
37 |
38 | //模拟失败
39 | smartFullscreenFail.setOnClickListener {
40 | smartFullscreenFail.startLoading()
41 | it.postDelayed({
42 | smartFullscreenFail.finishLoading(false) {
43 | Toast.makeText(this@MainLoadingActivity,"加载失败",Toast.LENGTH_SHORT).show()
44 | }
45 | }, 2000)
46 | }
47 |
48 |
49 | //模拟失败,并展示失败文案
50 | smartFullscreenFailtxt.setOnClickListener {
51 | smartFullscreenFailtxt.startLoading()
52 | it.postDelayed({
53 | //smartFullscreenFailtxt.setAnimaledText("我是自定义错误文案")
54 | smartFullscreenFailtxt.finishLoading(false)
55 | }, 2000)
56 | }
57 |
58 |
59 | /**
60 | * 2.smart_button
61 | * 支持关注模式
62 | * */
63 | //正常情况下的:"点击关注" 和 "取消关注"
64 | smartButtonSuccess.setOnClickListener {
65 | if (!smartButtonSuccess.isFinished) {
66 | smartButtonSuccess.startLoading()
67 | it.postDelayed({
68 | //2.1、加载成功--带loading动画的加载成功
69 | smartButtonSuccess.finishLoading(true) {
70 | Toast.makeText(this@MainLoadingActivity,"关注成功",Toast.LENGTH_SHORT).show()
71 | }
72 | }, 2000)
73 | } else {
74 | //2.2、再次点击,取消关注。通过此方法设置不带动画
75 | smartButtonSuccess.isFinished = false
76 | }
77 | }
78 |
79 | //模拟关注失败
80 | smartButtonFail.setOnClickListener {
81 | smartButtonFail.startLoading()
82 | it.postDelayed({
83 | smartButtonFail.finishLoading(false) {
84 | Toast.makeText(this@MainLoadingActivity,"关注失败,请稍后再试~",Toast.LENGTH_SHORT).show()
85 | }
86 | }, 2000)
87 | }
88 |
89 | //不带动画的 ”关注“ 和 ”取消关注“
90 | smartButtonNoanimal.setOnClickListener {
91 | smartButtonNoanimal.isFinished = !smartButtonNoanimal.isFinished
92 | }
93 |
94 |
95 | /**
96 | * 3.smart_tick
97 | * 支持关注模式
98 | * */
99 | //这里的用法和 smart_button 类似
100 | smartTickDemo.setOnClickListener {
101 | if (!smartTickDemo.isFinished) {
102 | smartTickDemo.startLoading()
103 | it.postDelayed({
104 | //2.1、加载成功--带loading动画的加载成功
105 | smartTickDemo.finishLoading(true) {
106 | Toast.makeText(this@MainLoadingActivity,"关注成功",Toast.LENGTH_SHORT).show()
107 | }
108 | }, 2000)
109 | } else {
110 | //2.2、再次点击,取消关注。通过此方法设置不带动画
111 | smartTickDemo.isFinished = false
112 | }
113 | }
114 |
115 |
116 | /**
117 | * 4.smart_tick_hide
118 | * 支持关注模式
119 | * */
120 | //这里的用法和 smart_button 类似
121 | smartTickHideDemo.setOnClickListener {
122 | if (!smartTickHideDemo.isFinished) {
123 | smartTickHideDemo.startLoading()
124 | it.postDelayed({
125 | //2.1、加载成功--带loading动画的加载成功
126 | smartTickHideDemo.finishLoading(true) {
127 | Toast.makeText(this@MainLoadingActivity,"关注成功",Toast.LENGTH_SHORT).show()
128 | }
129 | }, 2000)
130 | } else {
131 | //2.2、再次点击,取消关注。通过此方法设置不带动画
132 | smartTickHideDemo.isFinished = false
133 | }
134 | }
135 |
136 |
137 | /**
138 | * 5.smart_tick_center_hide
139 | * 支持关注模式
140 | * */
141 | //这里的用法和 smart_button 类似
142 | smartTickCenterHideDemo.setOnClickListener {
143 | if (!smartTickCenterHideDemo.isFinished) {
144 | smartTickCenterHideDemo.startLoading()
145 | it.postDelayed({
146 | //2.1、加载成功--带loading动画的加载成功
147 | smartTickCenterHideDemo.finishLoading(true) {
148 | Toast.makeText(this@MainLoadingActivity,"关注成功",Toast.LENGTH_SHORT).show()
149 | }
150 | }, 2000)
151 | } else {
152 | //2.2、再次点击,取消关注。通过此方法设置不带动画
153 | smartTickCenterHideDemo.isFinished = false
154 | }
155 | }
156 |
157 | }
158 | }
159 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/leo/loadingview/SecondActivity.java:
--------------------------------------------------------------------------------
1 | package com.leo.loadingview;
2 |
3 | import android.os.Bundle;
4 |
5 | import androidx.annotation.Nullable;
6 | import androidx.appcompat.app.AppCompatActivity;
7 |
8 | import com.leo.R;
9 |
10 | /**
11 | * Created by leo
12 | * on 2019/5/23.
13 | */
14 | public class SecondActivity extends AppCompatActivity {
15 | @Override
16 | protected void onCreate(@Nullable Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.activity_second);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/cb_select_new.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/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/drawable/shap_progressbar_web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_loading_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
18 |
19 |
22 |
23 |
34 |
35 |
49 |
50 |
64 |
65 |
82 |
83 |
84 |
96 |
97 |
114 |
115 |
116 |
133 |
134 |
151 |
152 |
153 |
165 |
166 |
167 |
181 |
182 |
194 |
195 |
209 |
210 |
222 |
223 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
24 |
25 |
34 |
35 |
36 |
37 |
38 |
51 |
52 |
53 |
61 |
62 |
63 |
64 |
65 |
75 |
76 |
77 |
85 |
86 |
87 |
88 |
102 |
103 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_shadow.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 |
25 |
26 |
27 |
30 |
31 |
32 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
72 |
73 |
77 |
78 |
88 |
89 |
98 |
99 |
100 |
109 |
110 |
118 |
119 |
120 |
121 |
122 |
132 |
133 |
141 |
142 |
143 |
144 |
145 |
146 |
155 |
156 |
164 |
165 |
166 |
167 |
168 |
177 |
178 |
186 |
187 |
188 |
189 |
198 |
199 |
207 |
208 |
209 |
210 |
220 |
221 |
229 |
230 |
231 |
232 |
242 |
243 |
251 |
252 |
253 |
254 |
263 |
264 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
291 |
292 |
293 |
300 |
301 |
302 |
303 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_starshow.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
23 |
24 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
44 |
45 |
50 |
51 |
58 |
59 |
60 |
61 |
68 |
69 |
74 |
75 |
82 |
83 |
84 |
85 |
92 |
93 |
98 |
99 |
104 |
105 |
106 |
107 |
114 |
115 |
120 |
121 |
126 |
127 |
128 |
129 |
136 |
137 |
142 |
143 |
150 |
151 |
152 |
153 |
160 |
161 |
166 |
167 |
174 |
175 |
176 |
177 |
184 |
185 |
190 |
191 |
198 |
199 |
200 |
201 |
208 |
209 |
214 |
215 |
222 |
223 |
224 |
231 |
232 |
237 |
238 |
246 |
247 |
248 |
252 |
253 |
258 |
259 |
267 |
268 |
269 |
270 |
277 |
278 |
283 |
284 |
292 |
293 |
294 |
298 |
299 |
304 |
305 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_wiki_web.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
21 |
22 |
31 |
32 |
42 |
43 |
44 |
47 |
48 |
49 |
59 |
60 |
66 |
67 |
68 |
69 |
70 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/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/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/shadowlayout_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-hdpi/shadowlayout_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/shadowlayout_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-mdpi/shadowlayout_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/back_icon_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/back_icon_black.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/check_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/check_off.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/check_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/check_on.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/game_6_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/game_6_right.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/game_6_wrong.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/game_6_wrong.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/regist_gou_false.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/regist_gou_false.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/regist_gou_true.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/regist_gou_true.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/shadowlayout_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/shadowlayout_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/test_background_false.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/test_background_false.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/test_background_true.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xhdpi/test_background_true.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/shadowlayout_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xxhdpi/shadowlayout_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/shadowlayout_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/app/src/main/res/mipmap-xxxhdpi/shadowlayout_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 | #fff
7 | #855a20
8 | #3E3EF9
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1dp
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ShadowLayout
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
21 |
22 |
23 |
24 |
25 |
34 |
35 |
36 |
42 |
43 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/test/java/com/leo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.leo;
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.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id("com.android.application") version "7.3.1" apply false
4 | id("org.jetbrains.kotlin.android") version "1.8.0" apply false
5 | id("com.android.library") version "7.3.1" apply false
6 | }
--------------------------------------------------------------------------------
/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 -Dfile.encoding=UTF-8
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 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
24 | android.disableAutomaticComponentCreation=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 01 18:18:06 CST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | #distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
4 | distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-7.4-bin.zip
5 | distributionPath=wrapper/dists
6 | zipStorePath=wrapper/dists
7 | zipStoreBase=GRADLE_USER_HOME
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | maven("https://jitpack.io")
7 | }
8 | }
9 | dependencyResolutionManagement {
10 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
11 | repositories {
12 | google()
13 | mavenCentral()
14 | maven("https://jitpack.io")
15 | }
16 | }
17 |
18 | rootProject.name = "ShadowLayoutX"
19 | include(":app")
20 | include(":shadowLibrary")
21 |
--------------------------------------------------------------------------------
/shadowLibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/shadowLibrary/build.gradle:
--------------------------------------------------------------------------------
1 | //apply plugin: 'com.android.library'
2 | //apply plugin: 'maven-publish'
3 | //
4 | //android {
5 | // compileSdkVersion 30
6 | // defaultConfig {
7 | // minSdkVersion 21
8 | // targetSdkVersion 30
9 | // versionCode 20
10 | // versionName "3.3.2"
11 | //
12 | // testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
13 | //
14 | // }
15 | //
16 | // buildTypes {
17 | // release {
18 | // minifyEnabled false
19 | // proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | // }
21 | // }
22 | //
23 | //}
24 | //
25 | //dependencies {
26 | // implementation fileTree(dir: 'libs', include: ['*.jar'])
27 | // implementation 'androidx.appcompat:appcompat:1.2.0'
28 | // implementation 'com.github.bumptech.glide:glide:4.9.0'
29 | //// annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
30 | //}
31 | //
32 | ////解决发布版本bug:参考连接 https://blog.csdn.net/qq_41885673/article/details/121588094
33 | //afterEvaluate {
34 | // publishing {
35 | // publications {
36 | // release(MavenPublication) {
37 | // from components.release
38 | // groupId = 'com.lihangleo2' //groupId 随便取
39 | // artifactId = 'ShadowLayout' //artifactId 随便取
40 | // version = '3.3.2'
41 | // }
42 | // }
43 | // }
44 | //}
45 | plugins {
46 | id 'com.android.library'
47 | id 'org.jetbrains.kotlin.android'
48 | id 'maven-publish'
49 | }
50 |
51 | android {
52 | namespace 'com.lihang'
53 | compileSdk 31
54 |
55 | defaultConfig {
56 | minSdk 21
57 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
58 | consumerProguardFiles "consumer-rules.pro"
59 | }
60 |
61 | buildTypes {
62 | release {
63 | minifyEnabled false
64 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
65 | }
66 | }
67 | compileOptions {
68 | sourceCompatibility JavaVersion.VERSION_1_8
69 | targetCompatibility JavaVersion.VERSION_1_8
70 | }
71 |
72 | kotlinOptions {
73 | jvmTarget = '1.8'
74 | }
75 |
76 | }
77 |
78 | //解决发布版本bug:参考连接 https://blog.csdn.net/qq_41885673/article/details/121588094
79 | afterEvaluate {
80 | publishing {
81 | publications {
82 | release(MavenPublication) {
83 | from components.release
84 | groupId = 'com.lihangleo2' //groupId 随便取
85 | artifactId = 'ShadowLayout' //artifactId 随便取
86 | version = '3.4.1'
87 | }
88 | }
89 | }
90 | }
91 |
92 | dependencies {
93 | implementation 'androidx.appcompat:appcompat:1.2.0'
94 | implementation("com.github.bumptech.glide:glide:4.16.0")
95 | // annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
96 | }
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/shadowLibrary/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
22 |
--------------------------------------------------------------------------------
/shadowLibrary/src/androidTest/java/com/lihang/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.lihang;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.lihang.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/java/com/lihang/GlideRoundTransform.java:
--------------------------------------------------------------------------------
1 | package com.lihang;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapShader;
6 | import android.graphics.Canvas;
7 | import android.graphics.Matrix;
8 | import android.graphics.Paint;
9 | import android.graphics.Path;
10 | import android.graphics.RectF;
11 | import android.graphics.Shader;
12 | import com.bumptech.glide.Glide;
13 | import com.bumptech.glide.load.Transformation;
14 | import com.bumptech.glide.load.engine.Resource;
15 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
16 | import com.bumptech.glide.load.resource.bitmap.BitmapResource;
17 |
18 | import java.security.MessageDigest;
19 |
20 | import androidx.annotation.NonNull;
21 |
22 |
23 | /**
24 | * Created by leo
25 | * on 2019/12/2.
26 | *
27 | * 这个是glide只加载2个圆角
28 | */
29 | class GlideRoundTransform implements Transformation {
30 | private BitmapPool mBitmapPool;
31 |
32 | private float leftTop_radius;
33 | private float leftBottom_radius;
34 | private float rightTop_radius;
35 | private float rightBottom_radius;
36 | private boolean isLeftTop, isRightTop, isLeftBottom, isRightBottom;
37 |
38 |
39 | /**
40 | * @param context 上下文
41 | */
42 | public GlideRoundTransform(Context context, float leftTop_radius, float leftBottom_radius, float rightTop_radius, float rightBottom_radius) {
43 | this.mBitmapPool = Glide.get(context).getBitmapPool();
44 | this.leftTop_radius = leftTop_radius;
45 | if (leftTop_radius != 0) {
46 | isLeftTop = true;
47 | }
48 | this.leftBottom_radius = leftBottom_radius;
49 | if (leftBottom_radius != 0) {
50 | isLeftBottom = true;
51 | }
52 | this.rightTop_radius = rightTop_radius;
53 | if (rightTop_radius != 0) {
54 | isRightTop = true;
55 | }
56 | this.rightBottom_radius = rightBottom_radius;
57 | if (rightBottom_radius != 0) {
58 | isRightBottom = true;
59 | }
60 | }
61 |
62 | @NonNull
63 | @Override
64 | public Resource transform(@NonNull Context context, @NonNull Resource resource, int outWidth, int outHeight) {
65 |
66 | Bitmap source = resource.get();
67 | int finalWidth, finalHeight;
68 | //输出目标的宽高或高宽比例
69 | float scale;
70 | if (outWidth > outHeight) {
71 | //如果 输出宽度 > 输出高度 求高宽比
72 |
73 | scale = (float) outHeight / (float) outWidth;
74 | finalWidth = source.getWidth();
75 | //固定原图宽度,求最终高度
76 | finalHeight = (int) ((float) source.getWidth() * scale);
77 | if (finalHeight > source.getHeight()) {
78 | //如果 求出的最终高度 > 原图高度 求宽高比
79 |
80 | scale = (float) outWidth / (float) outHeight;
81 | finalHeight = source.getHeight();
82 | //固定原图高度,求最终宽度
83 | finalWidth = (int) ((float) source.getHeight() * scale);
84 | }
85 | } else if (outWidth < outHeight) {
86 | //如果 输出宽度 < 输出高度 求宽高比
87 |
88 | scale = (float) outWidth / (float) outHeight;
89 | finalHeight = source.getHeight();
90 | //固定原图高度,求最终宽度
91 | finalWidth = (int) ((float) source.getHeight() * scale);
92 | if (finalWidth > source.getWidth()) {
93 | //如果 求出的最终宽度 > 原图宽度 求高宽比
94 |
95 | scale = (float) outHeight / (float) outWidth;
96 | finalWidth = source.getWidth();
97 | finalHeight = (int) ((float) source.getWidth() * scale);
98 | }
99 | } else {
100 | //如果 输出宽度=输出高度
101 | finalHeight = source.getHeight();
102 | finalWidth = finalHeight;
103 | }
104 |
105 | //修正圆角
106 | this.leftTop_radius *= (float) finalHeight / (float) outHeight;
107 | this.leftBottom_radius *= (float) finalHeight / (float) outHeight;
108 | this.rightTop_radius *= (float) finalHeight / (float) outHeight;
109 | this.rightBottom_radius *= (float) finalHeight / (float) outHeight;
110 | Bitmap outBitmap = this.mBitmapPool.get(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
111 | if (outBitmap == null) {
112 | outBitmap = Bitmap.createBitmap(finalWidth, finalHeight, Bitmap.Config.ARGB_8888);
113 | }
114 |
115 | Canvas canvas = new Canvas(outBitmap);
116 | Paint paint = new Paint();
117 | //关联画笔绘制的原图bitmap
118 | BitmapShader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
119 | //计算中心位置,进行偏移
120 | int width = (source.getWidth() - finalWidth) / 2;
121 | int height = (source.getHeight() - finalHeight) / 2;
122 | if (width != 0 || height != 0) {
123 | Matrix matrix = new Matrix();
124 | matrix.setTranslate((float) (-width), (float) (-height));
125 | shader.setLocalMatrix(matrix);
126 | }
127 |
128 | paint.setShader(shader);
129 | paint.setAntiAlias(true);
130 | RectF rectF = new RectF(0.0F, 0.0F, (float) canvas.getWidth(), (float) canvas.getHeight());
131 |
132 | float[] outerR = new float[]{leftTop_radius, leftTop_radius, rightTop_radius, rightTop_radius, rightBottom_radius, rightBottom_radius, leftBottom_radius, leftBottom_radius};//左上,右上,右下,左下
133 | Path path = new Path();
134 | path.addRoundRect(rectF, outerR, Path.Direction.CW);
135 | canvas.drawPath(path,paint);
136 |
137 | return BitmapResource.obtain(outBitmap, this.mBitmapPool);
138 | }
139 |
140 |
141 | @Override
142 | public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
143 | }
144 | }
145 |
146 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/java/com/lihang/GlideRoundUtils.java:
--------------------------------------------------------------------------------
1 | package com.lihang;
2 |
3 | import android.graphics.drawable.Drawable;
4 | import android.os.Build;
5 | import android.view.View;
6 |
7 | import com.bumptech.glide.Glide;
8 | import com.bumptech.glide.load.resource.bitmap.CenterCrop;
9 | import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
10 | import com.bumptech.glide.request.target.CustomTarget;
11 | import com.bumptech.glide.request.transition.Transition;
12 |
13 | import androidx.annotation.NonNull;
14 | import androidx.annotation.Nullable;
15 | import androidx.annotation.RequiresApi;
16 |
17 | /**
18 | * Created by leo
19 | * on 2020/8/3.
20 | */
21 | class GlideRoundUtils {
22 | public static void setRoundCorner(final View view, final Drawable resourceId, final float cornerDipValue, final String currentTag) {
23 |
24 | if (cornerDipValue == 0) {
25 | view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
26 | @Override
27 | public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
28 | view.removeOnLayoutChangeListener(this);
29 | Glide.with(view)
30 | .asDrawable()
31 | .load(resourceId)
32 | .transform(new CenterCrop())
33 | .override(view.getMeasuredWidth(), view.getMeasuredHeight())
34 | .into(new CustomTarget() {
35 | @Override
36 | public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
37 |
38 | String lastTag = (String) view.getTag(R.id.action_container);
39 | if (lastTag.equals(currentTag)) {
40 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
41 | view.setBackgroundDrawable(resource);
42 | } else {
43 | view.setBackground(resource);
44 | }
45 | }
46 | }
47 |
48 | @Override
49 | public void onLoadCleared(@Nullable Drawable placeholder) {
50 | }
51 | });
52 | }
53 | });
54 |
55 |
56 | if (view.getMeasuredWidth() != 0 || view.getMeasuredHeight() != 0) {
57 | Glide.with(view)
58 | .asDrawable()
59 | .load(resourceId)
60 | .transform(new CenterCrop())
61 | .override(view.getMeasuredWidth(), view.getMeasuredHeight())
62 | .into(new CustomTarget() {
63 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
64 | @Override
65 | public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
66 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
67 | view.setBackgroundDrawable(resource);
68 | } else {
69 | view.setBackground(resource);
70 | }
71 | }
72 |
73 | @Override
74 | public void onLoadCleared(@Nullable Drawable placeholder) {
75 | }
76 | });
77 | }
78 |
79 | } else {
80 |
81 | view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
82 | @Override
83 | public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
84 | view.removeOnLayoutChangeListener(this);
85 | Glide.with(view)
86 | .load(resourceId)
87 | .transform(new CenterCrop(), new RoundedCorners((int) cornerDipValue))
88 | .override(view.getMeasuredWidth(), view.getMeasuredHeight())
89 | .into(new CustomTarget() {
90 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
91 | @Override
92 | public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
93 | String lastTag = (String) view.getTag(R.id.action_container);
94 | if (lastTag.equals(currentTag)) {
95 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
96 | view.setBackgroundDrawable(resource);
97 | } else {
98 | view.setBackground(resource);
99 | }
100 | }
101 | }
102 |
103 | @Override
104 | public void onLoadCleared(@Nullable Drawable placeholder) {
105 |
106 | }
107 | });
108 | }
109 | });
110 |
111 |
112 | if (view.getMeasuredWidth() != 0 || view.getMeasuredHeight() != 0) {
113 | Glide.with(view)
114 | .load(resourceId)
115 | .transform(new CenterCrop(), new RoundedCorners((int) cornerDipValue))
116 | .override(view.getMeasuredWidth(), view.getMeasuredHeight())
117 | .into(new CustomTarget() {
118 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
119 | @Override
120 | public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
121 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
122 | view.setBackgroundDrawable(resource);
123 | } else {
124 | view.setBackground(resource);
125 | }
126 | }
127 |
128 | @Override
129 | public void onLoadCleared(@Nullable Drawable placeholder) {
130 |
131 | }
132 | });
133 | }
134 |
135 | }
136 |
137 | }
138 |
139 |
140 | public static void setCorners(final View view, final Drawable resourceId, final float leftTop_corner, final float leftBottom_corner, final float rightTop_corner, final float rightBottom_corner, final String currentTag) {
141 | if (leftTop_corner == 0 && leftBottom_corner == 0 && rightTop_corner == 0 && rightBottom_corner == 0) {
142 |
143 | view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
144 | @Override
145 | public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
146 | view.removeOnLayoutChangeListener(this);
147 | Glide.with(view)
148 | .load(resourceId)
149 | .override(view.getMeasuredWidth(), view.getMeasuredHeight())
150 | .into(new CustomTarget() {
151 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
152 | @Override
153 | public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
154 | String lastTag = (String) view.getTag(R.id.action_container);
155 | if (lastTag.equals(currentTag)) {
156 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
157 | view.setBackgroundDrawable(resource);
158 | } else {
159 | view.setBackground(resource);
160 | }
161 | }
162 | }
163 |
164 | @Override
165 | public void onLoadCleared(@Nullable Drawable placeholder) {
166 |
167 | }
168 | });
169 | }
170 | });
171 |
172 |
173 | if (view.getMeasuredWidth() != 0 || view.getMeasuredHeight() != 0) {
174 | Glide.with(view)
175 | .load(resourceId)
176 | .override(view.getMeasuredWidth(), view.getMeasuredHeight())
177 | .into(new CustomTarget() {
178 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
179 | @Override
180 | public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
181 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
182 | view.setBackgroundDrawable(resource);
183 | } else {
184 | view.setBackground(resource);
185 | }
186 | }
187 |
188 | @Override
189 | public void onLoadCleared(@Nullable Drawable placeholder) {
190 |
191 | }
192 | });
193 |
194 | }
195 |
196 | } else {
197 |
198 | /**
199 | * 注意:
200 | * 有特殊角,长宽不为0的状况(实际上也存在长宽不为0但还未渲染到画面上)
201 | * */
202 | final GlideRoundTransform transform = new GlideRoundTransform(view.getContext(), leftTop_corner, leftBottom_corner, rightTop_corner, rightBottom_corner);
203 | view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
204 | @Override
205 | public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
206 | view.removeOnLayoutChangeListener(this);
207 | // GlideRoundTransform transform = new GlideRoundTransform(view.getContext(), leftTop_corner, leftBottom_corner, rightTop_corner, rightBottom_corner);
208 | Glide.with(view)
209 | .load(resourceId)
210 | .transform(transform)
211 | .override(view.getMeasuredWidth(), view.getMeasuredHeight())
212 | .into(new CustomTarget() {
213 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
214 | @Override
215 | public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
216 | String lastTag = (String) view.getTag(R.id.action_container);
217 | if (lastTag.equals(currentTag)) {
218 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
219 | view.setBackgroundDrawable(resource);
220 | } else {
221 | view.setBackground(resource);
222 | }
223 | }
224 |
225 | }
226 |
227 | @Override
228 | public void onLoadCleared(@Nullable Drawable placeholder) {
229 |
230 | }
231 | });
232 | }
233 | });
234 |
235 |
236 | if (view.getMeasuredWidth() != 0 || view.getMeasuredHeight() != 0) {
237 | Glide.with(view)
238 | .load(resourceId)
239 | .transform(transform)
240 | .override(view.getMeasuredWidth(), view.getMeasuredHeight())
241 | .into(new CustomTarget() {
242 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
243 | @Override
244 | public void onResourceReady(@NonNull Drawable resource, @Nullable Transition super Drawable> transition) {
245 | String lastTag = (String) view.getTag(R.id.action_container);
246 | if (lastTag.equals(currentTag)) {
247 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
248 | view.setBackgroundDrawable(resource);
249 | } else {
250 | view.setBackground(resource);
251 | }
252 | }
253 | }
254 |
255 | @Override
256 | public void onLoadCleared(@Nullable Drawable placeholder) {
257 |
258 | }
259 | });
260 | }
261 | }
262 |
263 | }
264 |
265 | }
266 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/java/com/lihang/help/CirclBigView.java:
--------------------------------------------------------------------------------
1 | package com.lihang.help;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ValueAnimator;
5 | import android.app.Activity;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.graphics.Canvas;
9 | import android.graphics.Paint;
10 | import android.util.AttributeSet;
11 | import android.view.View;
12 |
13 | import androidx.annotation.Nullable;
14 |
15 | import com.lihang.R;
16 | import com.lihang.SmartLoadingView;
17 |
18 |
19 | /**
20 | * 圆圈扩散自定义View
21 | * By leo
22 | * 2019.5.23
23 | */
24 |
25 | public class CirclBigView extends View {
26 |
27 | //圆圈扩散动画
28 | private ValueAnimator animator_big;
29 | private int myRadius;
30 | //父类控件半径(父类最短一边,长度的一半)
31 | private int fatherRadius;
32 | private Paint showPaint;
33 | private int y;//当前Y轴位置
34 | private int x;//当前X轴位置
35 |
36 | //最大能扩散到的半径
37 | private int maxRadius;
38 |
39 |
40 | public CirclBigView(Context context) {
41 | this(context, null);
42 | }
43 |
44 | public CirclBigView(Context context, @Nullable AttributeSet attrs) {
45 | this(context, attrs, 0);
46 | }
47 |
48 | public CirclBigView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
49 | super(context, attrs, defStyleAttr);
50 | showPaint = new Paint();
51 | showPaint.setAntiAlias(true);
52 | showPaint.setStyle(Paint.Style.FILL);
53 | showPaint.setColor(getResources().getColor(R.color.guide_anim));
54 | }
55 |
56 |
57 | public void setXY(int x, int y) {
58 | this.x = x;
59 | this.y = y;
60 | int y_true = y + fatherRadius;
61 | //知道了view圆心,计算出到手机4个角的距离,以最大距离为准
62 | int left_top = (int) Math.sqrt((x * x) + (y_true * y_true));
63 | int left_bottom = (int) Math.sqrt((x * x) + ((UIUtil.getHeight(getContext()) - y_true) * (UIUtil.getHeight(getContext()) - y_true)));
64 |
65 | int right_top = (int) Math.sqrt(((UIUtil.getWidth(getContext()) - x) * (UIUtil.getWidth(getContext()) - x)) + (y_true * y_true));
66 | int right_bottom = (int) Math.sqrt(((UIUtil.getWidth(getContext()) - x) * (UIUtil.getWidth(getContext()) - x)) + ((UIUtil.getHeight(getContext()) - y_true) * (UIUtil.getHeight(getContext()) - y_true)));
67 |
68 | int left_big = left_top >= left_bottom ? left_top : left_bottom;
69 | int right_big = right_top >= right_bottom ? right_top : right_bottom;
70 | maxRadius = left_big >= right_big ? left_big : right_big;
71 | //这里虚拟键有个bug,我们把半径大小稍加长
72 | maxRadius = maxRadius + UIUtil.getWidth(getContext()) / 6;
73 |
74 |
75 | animator_big = ValueAnimator.ofInt(myRadius, maxRadius);
76 | animator_big.setDuration(200);
77 | animator_big.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
78 | @Override
79 | public void onAnimationUpdate(ValueAnimator valueAnimator) {
80 | myRadius = (int) valueAnimator.getAnimatedValue();
81 | postInvalidate();
82 | }
83 | });
84 |
85 | invalidate();
86 | }
87 |
88 | public void setRadius(int radius) {
89 | myRadius = radius;
90 | fatherRadius = radius;
91 | }
92 |
93 | public void setCircleR(int currentR) {
94 | myRadius = currentR;
95 | postInvalidate();
96 | }
97 |
98 |
99 | public void setColorBg(int colorBg) {
100 | showPaint.setColor(colorBg);
101 | }
102 |
103 |
104 | @Override
105 | protected void onDraw(Canvas canvas) {
106 | super.onDraw(canvas);
107 | canvas.drawCircle(x, y + fatherRadius, myRadius, showPaint);
108 | }
109 |
110 |
111 | public void startShowAni(final SmartLoadingView.LoadingListener listener, final SmartLoadingView smartLoadingView) {
112 |
113 | if (listener != null) {
114 | if (!animator_big.isRunning()) {
115 | animator_big.start();
116 | }
117 | if (listener != null) {
118 | animator_big.addListener(new Animator.AnimatorListener() {
119 | @Override
120 | public void onAnimationStart(Animator animation) {
121 |
122 | }
123 |
124 | @Override
125 | public void onAnimationEnd(Animator animation) {
126 | listener.loadingFinish(true);
127 | }
128 |
129 | @Override
130 | public void onAnimationCancel(Animator animation) {
131 |
132 | }
133 |
134 | @Override
135 | public void onAnimationRepeat(Animator animation) {
136 |
137 | }
138 | });
139 | }
140 |
141 | }
142 | }
143 |
144 |
145 | public void startShowAni(final Activity activity, final Class clazz) {
146 |
147 | if (!animator_big.isRunning()) {
148 | animator_big.start();
149 | animator_big.addListener(new Animator.AnimatorListener() {
150 | @Override
151 | public void onAnimationStart(Animator animation) {
152 |
153 | }
154 |
155 | @Override
156 | public void onAnimationEnd(Animator animation) {
157 | activity.startActivity(new Intent(activity, clazz));
158 | activity.finish();
159 | activity.overridePendingTransition(R.anim.alpha_enter, R.anim.alpha_exit);
160 | }
161 |
162 | @Override
163 | public void onAnimationCancel(Animator animation) {
164 |
165 | }
166 |
167 | @Override
168 | public void onAnimationRepeat(Animator animation) {
169 |
170 | }
171 | });
172 | }
173 | }
174 |
175 | }
176 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/java/com/lihang/help/OkView.java:
--------------------------------------------------------------------------------
1 | package com.lihang.help;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.content.Context;
5 | import android.graphics.Canvas;
6 | import android.graphics.DashPathEffect;
7 | import android.graphics.Paint;
8 | import android.graphics.Path;
9 | import android.graphics.PathEffect;
10 | import android.graphics.PathMeasure;
11 | import android.util.AttributeSet;
12 | import android.view.View;
13 |
14 | import androidx.annotation.Nullable;
15 |
16 | /**
17 | * Created by leo
18 | * on 2019/11/21.
19 | */
20 | public class OkView extends View {
21 | //绘制一个小圆圈
22 | private Paint paint;
23 | //绘制打勾paint
24 | private Paint okPaint;
25 |
26 | //背景圆圈的半径
27 | private int myRadius;
28 | //绘制打勾的路径
29 | private Path path = new Path();
30 | //绘制路径的长度,也可以理解为完成度
31 | private PathMeasure pathMeasure;
32 |
33 | //绘制对勾(√)的动画
34 | private ValueAnimator animator_draw_ok;
35 |
36 | //对路径处理实现绘制动画效果
37 | private PathEffect effect;
38 |
39 | private boolean startDrawOk;
40 |
41 | public OkView(Context context) {
42 | this(context, null);
43 | }
44 |
45 | public OkView(Context context, @Nullable AttributeSet attrs) {
46 | this(context, attrs, 0);
47 | }
48 |
49 | public OkView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
50 | super(context, attrs, defStyleAttr);
51 | paint = new Paint();
52 | paint.setAntiAlias(true);
53 | paint.setStyle(Paint.Style.FILL);
54 |
55 |
56 | okPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
57 | okPaint.setStrokeWidth(5);
58 | okPaint.setStyle(Paint.Style.STROKE);
59 | okPaint.setStrokeCap(Paint.Cap.ROUND);
60 |
61 |
62 | }
63 |
64 |
65 | @Override
66 | protected void onDraw(Canvas canvas) {
67 | super.onDraw(canvas);
68 | canvas.drawCircle(getWidth() / 2, getHeight() / 2, myRadius, paint);
69 |
70 | if (startDrawOk) {
71 | canvas.drawPath(path, okPaint);
72 | }
73 | }
74 |
75 | public void setOkColor(int color) {
76 | okPaint.setColor(color);
77 | }
78 |
79 | public void setCircleColor(int color) {
80 | paint.setColor(color);
81 | }
82 |
83 |
84 | public void setRadius(int radius) {
85 | myRadius = radius;
86 | //对勾的路径
87 | int cHeight = radius * 2;
88 | path.moveTo(+cHeight / 8 * 3, cHeight / 2);
89 | path.lineTo(+cHeight / 2, cHeight / 5 * 3);
90 | path.lineTo(+cHeight / 3 * 2, cHeight / 5 * 2);
91 | pathMeasure = new PathMeasure(path, true);
92 |
93 | invalidate();
94 | }
95 |
96 |
97 | public void start(int duration) {
98 | animator_draw_ok = ValueAnimator.ofFloat(1, 0);
99 | animator_draw_ok.setDuration(duration);
100 | animator_draw_ok.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
101 | @Override
102 | public void onAnimationUpdate(ValueAnimator animation) {
103 | startDrawOk = true;
104 | float value = (Float) animation.getAnimatedValue();
105 | effect = new DashPathEffect(new float[]{pathMeasure.getLength(), pathMeasure.getLength()}, value * pathMeasure.getLength());
106 | okPaint.setPathEffect(effect);
107 | invalidate();
108 | }
109 | });
110 | animator_draw_ok.start();
111 | }
112 |
113 |
114 | }
115 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/java/com/lihang/help/UIUtil.java:
--------------------------------------------------------------------------------
1 | package com.lihang.help;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageInfo;
5 | import android.content.pm.PackageManager;
6 | import android.os.Build;
7 | import android.util.TypedValue;
8 | import android.view.WindowManager;
9 |
10 | import java.io.UnsupportedEncodingException;
11 | import java.lang.reflect.Field;
12 | import java.security.MessageDigest;
13 | import java.security.NoSuchAlgorithmException;
14 | import java.util.Locale;
15 | import java.util.UUID;
16 | import java.util.regex.Matcher;
17 | import java.util.regex.Pattern;
18 |
19 |
20 | /**
21 | * Created by lihang Leo on 2016/12/10.
22 | */
23 | public class UIUtil {
24 |
25 | private static final String TAG = UIUtil.class.getName();
26 |
27 | /**
28 | * Dip to Px
29 | *
30 | * @param context
31 | * @param dipValue
32 | * @return
33 | */
34 | public static int dip2px(Context context, float dipValue) {
35 | float scale = context.getResources().getDisplayMetrics().density;
36 | return (int) (dipValue * scale + 0.5f);
37 | }
38 |
39 | /**
40 | * Px To Dip
41 | *
42 | * @param context
43 | * @param pxValue
44 | * @return
45 | */
46 | public static int px2dip(Context context, float pxValue) {
47 | float scale = context.getResources().getDisplayMetrics().density;
48 | return (int) (pxValue / scale + 0.5f);
49 | }
50 |
51 | //sp转px
52 | public static int Sp2Px(Context context, int sp) {
53 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());
54 | }
55 |
56 |
57 | public static int getWidth(Context context) {
58 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
59 | int width = wm.getDefaultDisplay().getWidth();
60 | return width;
61 | }
62 |
63 | public static int getHeight(Context context) {
64 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
65 | int height = wm.getDefaultDisplay().getHeight();
66 | return height;
67 | }
68 |
69 | //获取手机状态栏高度
70 | public static int getStatusBarHeight(Context context) {
71 | Class> c = null;
72 | Object obj = null;
73 | Field field = null;
74 | int x = 0, statusBarHeight = 0;
75 | try {
76 | c = Class.forName("com.android.internal.R$dimen");
77 | obj = c.newInstance();
78 | field = c.getField("status_bar_height");
79 | x = Integer.parseInt(field.get(obj).toString());
80 | statusBarHeight = context.getResources().getDimensionPixelSize(x);
81 | } catch (Exception e1) {
82 | e1.printStackTrace();
83 | }
84 | return statusBarHeight;
85 | }
86 |
87 |
88 |
89 | //获得独一无二的Psuedo ID
90 | public static String getDeviceId() {
91 | String serial = null;
92 | String m_szDevIDShort = "35" +
93 | Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +
94 |
95 | Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +
96 |
97 | Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +
98 |
99 | Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +
100 |
101 | Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +
102 |
103 | Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +
104 |
105 | Build.USER.length() % 10; //13 位
106 |
107 | try {
108 | serial = Build.class.getField("SERIAL").get(null).toString();
109 | //API>=9 使用serial号
110 | return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
111 | } catch (Exception exception) {
112 | //serial需要一个初始化
113 | serial = "serial"; // 随便一个初始化
114 | }
115 | //使用硬件信息拼凑出来的15位号码
116 | return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
117 | }
118 |
119 |
120 | /**
121 | * 获取当前手机系统语言。
122 | *
123 | * @return 返回当前系统语言。例如:当前设置的是“中文-中国”,则返回“zh-CN”
124 | */
125 | public static String getSystemLanguage() {
126 | return Locale.getDefault().getLanguage();
127 | }
128 |
129 | /**
130 | * 获取当前系统上的语言列表(Locale列表)
131 | *
132 | * @return 语言列表
133 | */
134 | public static Locale[] getSystemLanguageList() {
135 | return Locale.getAvailableLocales();
136 | }
137 |
138 | /**
139 | * 获取当前手机系统版本号
140 | *
141 | * @return 系统版本号
142 | */
143 | public static String getSystemVersion() {
144 | return Build.VERSION.RELEASE;
145 | }
146 |
147 | /**
148 | * 获取手机型号
149 | *
150 | * @return 手机型号
151 | */
152 | public static String getSystemModel() {
153 | return Build.MODEL;
154 | }
155 |
156 | /**
157 | * 获取手机厂商
158 | *
159 | * @return 手机厂商
160 | */
161 | public static String getDeviceBrand() {
162 | return Build.BRAND;
163 | }
164 |
165 |
166 | /**
167 | * get App versionCode
168 | *
169 | * @param context
170 | * @return
171 | */
172 | public static int getVersionCode(Context context) {
173 | PackageManager packageManager = context.getPackageManager();
174 | PackageInfo packageInfo;
175 | int versionCode = 1;
176 | try {
177 | packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
178 | versionCode = packageInfo.versionCode ;
179 | } catch (PackageManager.NameNotFoundException e) {
180 | e.printStackTrace();
181 | }
182 | return versionCode;
183 | }
184 |
185 | /**
186 | * get App versionName
187 | *
188 | * @param context
189 | * @return
190 | */
191 | public static String getVersionName(Context context) {
192 | PackageManager packageManager = context.getPackageManager();
193 | PackageInfo packageInfo;
194 | String versionName = "";
195 | try {
196 | packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
197 | versionName = packageInfo.versionName;
198 | } catch (PackageManager.NameNotFoundException e) {
199 | e.printStackTrace();
200 | }
201 | return versionName;
202 | }
203 |
204 |
205 | public static String md5(String content) {//MD5加密
206 | byte[] hash;
207 | try {
208 | hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8"));
209 | } catch (NoSuchAlgorithmException e) {
210 | throw new RuntimeException("NoSuchAlgorithmException",e);
211 | } catch (UnsupportedEncodingException e) {
212 | throw new RuntimeException("UnsupportedEncodingException", e);
213 | }
214 |
215 | StringBuilder hex = new StringBuilder(hash.length * 2);
216 | for (byte b : hash) {
217 | if ((b & 0xFF) < 0x10){
218 | hex.append("0");
219 | }
220 | hex.append(Integer.toHexString(b & 0xFF));
221 | }
222 | return hex.toString();
223 | }
224 |
225 |
226 |
227 | /**
228 | * 判断手机格式是否正确
229 | *
230 | * @param mobiles
231 | * @return true为格式正确
232 | */
233 | public static boolean isMobileNO(String mobiles) {
234 | Pattern p = Pattern
235 | .compile("^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}$");
236 | Matcher m = p.matcher(mobiles);
237 | return m.matches();
238 | }
239 |
240 |
241 |
242 |
243 | }
244 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/res/anim/alpha_enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/res/anim/alpha_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/res/anim/alpha_hide.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/shadowLibrary/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 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2a000000
4 | #fff
5 | #000
6 |
7 | #3e80fc
8 | #bbbbbb
9 |
10 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 5dp
4 | 15dp
5 | 0dp
6 |
7 | 0dp
8 | 14dp
9 | 7dp
10 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/shadowLibrary/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ShadowLayout
3 |
4 |
--------------------------------------------------------------------------------
/shadowLibrary/src/test/java/com/lihang/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.lihang;
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 | }
--------------------------------------------------------------------------------
/showImages/GLIDE.md:
--------------------------------------------------------------------------------
1 | ## glide版本冲突终极解决方案
2 | 如果你出现了版本冲突,不知道怎么解决的话。就用Library方式集成,同时修改shadowLibrary里build.gradle的glide版本号。(如果版本过低的话,可能需要修改GlideRoundUtils里glide的加载方法)
3 |
4 | ## 如果你不知道怎么集成的话,按如下步骤
5 | ### 1、首先下载本demo,打开项目如下
6 | 
7 |
8 |
9 | ### 2、然后点击 File --> New --> Import Module
10 | 
11 |
12 |
13 | ### 3、出现如下假面后,点击右边的文件夹,选中shadowLibrary,然后点击Finish
14 | 
15 |
16 |
17 | finish后就会以module的方式出现在你的项目里。
18 |
19 |
20 | ### 4、来到你项目的build.gradle里引入下
21 | implementation project(':shadowLibrary')
22 |
23 |
24 | ### 5、最后来到shadowLibrary的bulid.gradle里修改下glide版本即可
25 | 
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/showImages/README218.md:
--------------------------------------------------------------------------------
1 | [](https://jitpack.io/#lihangleo2/ShadowLayout)
2 |
3 | ## 万能阴影布局,定制化你要的阴影。 ShadowLayout 2.0震撼上线(需要阴影地方,被它嵌套即可享受阴影,阴影可定制化,效果赶超CardView)
4 | * 支持定制化阴影
5 | * 支持随意更改阴影颜色值
6 | * 支持x,y轴阴影偏移
7 | * 可随意更改阴影扩散区域
8 | * 支持阴影圆角属性
9 | * 支持单边或多边不显示阴影
10 | * 支持ShadowLayout背景填充颜色,背景圆角随阴影圆角改变
11 | * 控件支持动态设置shape和selector(项目里再也不用画shape了)
12 |
13 | #### 2.1.8更新功能及ShadowLayout成长历程
14 | * 新增更改四个圆角属性
15 | [Shadow成长历程](https://github.com/lihangleo2/ShadowLayout/wiki)
16 |
17 |
18 |
19 | ### [最近有人反应内存情况,请看分析](https://juejin.im/post/5d4c1392f265da03bc126584#heading-12)
20 |
21 | ## 效果展示(截图分辨率模糊,真机运行效果赶超CardView)
22 | |基础功能展示|各属性展示|随意更改颜色|
23 | |:---:|:---:|:---:|
24 | |||
25 |
26 | ### 后续功能更新
27 | |2.1.6新增shape,selector功能|2.1.7isSym属性对比|2.1.8单独更改某圆角大小|
28 | |:---:|:---:|:---:|
29 | ||
|
30 |
31 |
32 | ## 扫描二维体验效果(下载密码是:123456)
33 | 
34 |
35 |
36 |
37 | ## 添加依赖
38 |
39 | - 项目build.gradle添加如下
40 | ```java
41 | allprojects {
42 | repositories {
43 | maven { url 'https://jitpack.io' }
44 | }
45 | }
46 | ```
47 | - app build.gradle添加如下
48 | ```java
49 | dependencies {
50 | implementation 'com.github.lihangleo2:ShadowLayout:2.1.8'
51 | }
52 | ```
53 |
54 |
55 |
56 | ## 使用(这里只放了几个基本属性,全部属性请看下方介绍)
57 | ```xml
58 |
65 |
66 |
74 |
75 |
76 | ```
77 |
78 |
79 | # 自定义属性
80 | #### 1、圆角属性 app:hl_cornerRadius="18dp"
81 | - 阴影圆角属性(同时如果设置了背景填充色也是背景圆角)
82 |
83 |
84 | #### 2、阴影扩散程度 app:hl_shadowLimit="5dp"
85 | - 阴影的扩散区域
86 |
87 |
88 | #### 3、阴影布局背景颜色值 app:hl_shadowBackColor="#fff"
89 | - 阴影布局背景填充色,同时注意圆角属性即是阴影圆角
90 |
91 |
92 | #### 4、阴影的颜色 app:hl_shadowColor="#2a000000"
93 | - 阴影的颜色可以随便改变,透明度的改变可以改变阴影的清晰程度,如果未设置透明度,则默认透明度为16%
94 |
95 |
96 | #### 5、x轴的偏移量 app:hl_dx="0dp"
97 | - 也可以理解为左右偏移量
98 |
99 |
100 | #### 6、y轴的偏移量 app:hl_dy="0dp"
101 | - 也可以理解为上下的偏移量
102 |
103 |
104 | #### 7、阴影的4边可见不可见 app:hl_leftShow="false"
105 | - 左边的阴影不可见,其他3边保持不变
106 |
107 |
108 | #### 8、动态设置shape,selector。pressed和selected背景颜色值 app:hl_shadowBackColorClicked="#ff0000"
109 | - 不点击状态下,显示hl_shadowBackColor颜色值。点击时切换成hl_shadowBackColorClicked。松开手指后恢复正常;如果是setSelect(true)则显示hl_shadowBackColorClicked,false显示hl_shadowBackColor
110 |
111 |
112 | #### 9、设置selector的样式 app:hl_selectorMode="selected"
113 | - selected表示只支持selected样式;pressed表示只支持点击状态;selected|pressed则表示2者都支持
114 |
115 |
116 | #### 10、是否使用阴影 app:hl_isShowShadow="false"
117 | - 这个属性是因为有些同学只想使用shape和selector功能,那么就不使用阴影就好了
118 |
119 |
120 | #### 11、 控件区域是否对称,默认是对称。不对称的话,那么控件区域随着阴影区域走:app:hl_isSym="false"
121 | - 如下图:右边是对称,不管你怎么偏移,控件所占的区域都是均等的,这也造成了有些同学ui上不好控制。那么你可以加上app:hl_isSym="false"属性。控件区域随着阴影改变,如下图左边样子。
122 |
123 |
124 |
125 |
126 | #### 11、更改控件4个圆角的大小:app:hl_cornerRadius_leftTop="0dp";app:hl_cornerRadius_leftBottom="0dp";app:hl_cornerRadius_rigthTop="0dp";app:hl_cornerRadius_rightBottom="0dp"
127 | - 这个属性是单独控制某一个圆角的圆角大小
128 |
129 |
130 |
131 | ## 关于作者。
132 | Android工作多年了,一直向往大厂。在前进的道路上是孤独的。如果你在学习的路上也感觉孤独,请和我一起。让我们在学习道路上少些孤独
133 | * [关于我的经历](https://mp.weixin.qq.com/s?__biz=MzAwMDA3MzU2Mg==&mid=2247483667&idx=1&sn=1a575ea2c636980e5f4c579d3a73d8ab&chksm=9aefcb26ad98423041c61ad7cbad77f0534495d11fc0a302b9fdd3a3e6b84605cad61d192959&mpshare=1&scene=23&srcid=&sharer_sharetime=1572505105563&sharer_shareid=97effcbe7f9d69e6067a40da3e48344a#rd)
134 | * QQ群: 209010674
(点击图标,可以直接加入)
135 |
136 |
137 |
138 | ## Licenses
139 |
140 | ```
141 | MIT License
142 |
143 | Copyright (c) 2019 leo
144 |
145 | Permission is hereby granted, free of charge, to any person obtaining a copy
146 | of this software and associated documentation files (the "Software"), to deal
147 | in the Software without restriction, including without limitation the rights
148 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
149 | copies of the Software, and to permit persons to whom the Software is
150 | furnished to do so, subject to the following conditions:
151 |
152 | The above copyright notice and this permission notice shall be included in all
153 | copies or substantial portions of the Software.
154 | ```
155 |
--------------------------------------------------------------------------------
/showImages/ShadowLayout_.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/ShadowLayout_.png
--------------------------------------------------------------------------------
/showImages/SmartLoadingViewGuide.md:
--------------------------------------------------------------------------------
1 | # SmartLoadingView - 一个自带loading的联网请求按钮
2 |
3 | ## 特点功能
4 | 想让你的按钮动起来吗,想让你的app具备活力吗。那来试试它吧。具体介绍如下:
5 | ```
6 | 1. 支持在任何布局上使用
7 | 2. smart_full_screen模式:全屏扩散跳转动画,让你的按钮和跳转页面更有活力
8 | 3. smart_tick模式:仿抖音,关注按钮及动画
9 | 4. smart_tick_hide模式:打勾动画及隐藏
10 | 5. smart_tick_center_hide模式:打勾隐藏,及移动到屏幕中间提醒模式
11 | 6. smart_button模式:正常关注和取消关注
12 | ```
13 |
14 | ## 效果展示
15 | 为录制流畅,截图分辨率模糊。可下载apk查看真机效果
16 | * ### smart_full_screen模式:全屏扩散动画(不支持关注)
17 | |全屏扩散页面跳转|加载失败|失败文案在按钮上|
18 | |:---:|:---:|:---:|
19 | |
|
|
20 |
21 |
22 | * ### smart_button模式:正常按钮动画(支持关注)
23 | |关注并加载成功|关注失败|不带动画关注|
24 | |:---:|:---:|:---:|
25 | |
|
|
26 |
27 |
28 | * ### smart_tick模式:仿抖音打勾关注(支持关注);smart_tick_hide模式:打勾隐藏(支持关注);smart_tick_center_hide模式:打勾隐藏,并移至中间提醒(支持关注)。
29 | |仿抖音打勾关注|打勾隐藏|打勾隐藏,移至中间|
30 | |:---:|:---:|:---:|
31 | |
|
|
32 |
33 |
34 | ## 基本使用
35 | #### 一、简单使用
36 | xml设置如下,注意app:hl_button_type="smart_button"
37 | ```xml
38 |
49 | ```
50 |
51 |
52 | 使用如下:没看错就这么简单(5种buttonType均如此)
53 | ```java
54 | //1.1 设置点击事件,点击调用加载loading
55 | smartLoadingView.startLoading()
56 |
57 | //1.2 联网成功,关注成功调用如下代码
58 | smartLoadingView.finishLoading()
59 |
60 | //1.3 联网失败,调用如下代码
61 | smartLoadingView.finishLoading(false)
62 |
63 | ```
64 |
65 |
66 | #### 二、全屏模式:smart_full_screen(注意:此模式不支持关注)
67 | ##### 2.1 全屏扩散及页面跳转:smartLoadingView.finishLoadingWithFullScreen(Activity activity, Class clazz)
68 | xml如下:
69 | ```xml
70 |
80 | ```
81 |
82 |
83 | 当点击按钮时,开启加载loading
84 |
85 |
86 | ```java
87 | smartLoadingView.startLoading()
88 | ```
89 |
90 |
91 | 当得到联网结果为success,且需要跳转页面时调用如下:
92 | ```java
93 | smartLoadingView.finishLoadingWithFullScreen(this, SecondActivity::class.java)
94 | ```
95 |
96 |
97 | 如果你不想用封装的api,想再扩散动画结束后自己操作,你可以使用如下方法:
98 | ```java
99 | //kotlin使用如下:
100 | smartLoadingView.finishLoading(true) {
101 | //处理自定义逻辑
102 | }
103 |
104 | //java使用如下:
105 | smartLoadingView.finishLoading(true, success -> {
106 | //处理自定义逻辑
107 | });
108 | ```
109 |
110 |
111 | ##### 2.2 如果联网结果失败fail时
112 | 执行完,就会平滑回到初始状态
113 | ```java
114 | //kotlin使用如下:
115 | smartLoadingView.finishLoading(false) {
116 | ToastUtils.showShort("加载失败")
117 | }
118 |
119 | //java使用如下:
120 | smartLoadingView.finishLoading(false, success -> {
121 | ToastUtils.showShort("加载失败")
122 | });
123 | ```
124 |
125 |
126 | ##### 2.3 如果联网结果失败,你想将错误信息显示在按钮上可以这样
127 | xml如下:
128 | ```xml
129 |
142 | ```
143 |
144 |
145 | 调用如下即可。
146 | ```java
147 | //如果想自定义错误文案,在调用finishLoading前,设置文案
148 | //smartLoadingView.setAnimaledText("我是自定义错误文案")
149 | smartLoadingView.finishLoading(false)
150 |
151 | ```
152 |
153 |
154 | #### 三、正常模式详细讲解:smart_button(支持关注)
155 | 特别说明:smart_button、smart_tick、smart_tick_hide、smart_tick_center_hide 这四种模式,用法一致。所以这里以smart_button 讲解为主
156 | ##### 3.1 这里我们用一个关注功能来说:如果我们有个按钮,初始状态显示"点击关注",点击按钮进行网络请求,成功了显示"关注成功";此时再点击,进行网络请求,成功后再显示"点击关注"
157 | 当点击按钮时, 我们要判断当前是什么状态,来进行接下来的逻辑:
158 | ```java
159 | if (!smartLoadingView.isFinished) {
160 | //当前不时结束,状态,开启加载loading
161 | smartLoadingView.startLoading()
162 | } else {
163 | //当前结束时,再次点击回到初始状态
164 | //kotlin使用
165 | smartLoadingView.isFinished = false
166 | //java使用
167 | //smartLoadingView.setFinished(false);
168 | }
169 | ```
170 |
171 |
172 | ##### 3.2 联网出结果,成功 or 失败同样调用如下
173 | ```java
174 | //true则走成功,false则走失败
175 | //kotlin使用
176 | smartLoadingView.finishLoading(true) {
177 |
178 | }
179 |
180 | //java使用
181 | smartLoadingView.finishLoading(true, success -> {
182 |
183 | });
184 | ```
185 |
186 |
187 | ##### 3.3 如果你不想使用动画,可以调用如下api。
188 | ```java
189 | //kotlin使用
190 | smartLoadingView.isFinished = true
191 |
192 | //java使用
193 | smartLoadingView.setFinished(true);
194 | ```
195 |
196 |
197 | ## 属性表格(Attributes)
198 | 因为SmartLoadingView就是TextView的拓展控件。部分属性延用了系统属性
199 |
200 | |name|format|description|系统api|
201 | |:---:|:---:|:---:|:---:|
202 | |android:text|string|文案内容|是|
203 | |app:hl_animaled_text|string|动画结束文案,默认为text|否|
204 | |android:textColor|color|文案颜色|是|
205 | |app:hl_animaled_textColor|color|动画结束文字颜色,默认为textColor|否|
206 | |android:textSize|dimension|文案字体大小|是|
207 | |android:background|color|背景色|是|
208 | |app:hl_animaled_background|color|动画结束背景色,默认为background颜色值|否|
209 | |app:hl_corners_radius|dimension|圆角属性|否|
210 | |android:enabled|boolean|是否可被点击|是|
211 | |app:hl_unEnabled_background|color|不可点击状态下背景色|否|
212 | |app:hl_ellipsize|enum|reverse:来回滚动;marquee:跑马灯。需文字大于控件宽度生效|否|
213 | |app:hl_ellipsize_speed|integer|文字滚动速度|否|
214 | |app:hl_button_type|enum|5种buttonType样式|否|
215 |
216 |
217 |
218 | ## 方法表格(Method)
219 | |name|format|description|
220 | |:---:|:---:|:---:|
221 | |startLoading()|void|开启加载loading|
222 | |setFinished()|boolean|不带动画设置控件结束状态|
223 | |finishLoading()|boolean|带动画设置控件结束状态|
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
--------------------------------------------------------------------------------
/showImages/bindTextView.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/bindTextView.gif
--------------------------------------------------------------------------------
/showImages/corners.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/corners.gif
--------------------------------------------------------------------------------
/showImages/first_show.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/first_show.gif
--------------------------------------------------------------------------------
/showImages/friend.md:
--------------------------------------------------------------------------------
1 | # 捐赠列表
2 |
3 | 你们的star和支持是我前进的最大动力!
4 |
5 | |昵称|日期|方式|留言|友情连接|赞赏金额|
6 | |:---:|:---:|:---:|:---:|:---:|:---:|
7 | |*华|2020-10-27|微信|你太客气了|/|1¥|
8 | |[匿名]|2020-10-27|微信|/|/|1¥|
9 | |[匿名]|2021-02-22|微信|请作者喝咖啡|/|0.1¥|
10 | |[100100100]|2021-05-31|微信|请作者喝咖啡|/|0.01¥|
11 | |[匿名]|2022-01-06|微信|请作者喝咖啡|/|10.24¥|
12 | |小翟|2023-01-06|微信|请作者喝咖啡|/|1¥|
13 | |vipyinzhiwei|2023-02-16|微信|请作者喝咖啡|/|6.66¥|
14 | |背包客|2023-06-28|微信|请作者喝咖啡|/|1¥|
15 | |永恒|2023-12-02|微信|请作者喝咖啡|/|66¥|
16 |
17 |
--------------------------------------------------------------------------------
/showImages/glide1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/glide1.png
--------------------------------------------------------------------------------
/showImages/glide2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/glide2.jpg
--------------------------------------------------------------------------------
/showImages/glide3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/glide3.png
--------------------------------------------------------------------------------
/showImages/glide4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/glide4.png
--------------------------------------------------------------------------------
/showImages/groupUse2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/groupUse2.gif
--------------------------------------------------------------------------------
/showImages/isSym.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/isSym.jpg
--------------------------------------------------------------------------------
/showImages/isSym_half.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/isSym_half.jpg
--------------------------------------------------------------------------------
/showImages/main.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/main.jpg
--------------------------------------------------------------------------------
/showImages/other_show.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/other_show.gif
--------------------------------------------------------------------------------
/showImages/pay_ali.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/pay_ali.png
--------------------------------------------------------------------------------
/showImages/pay_wx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/pay_wx.png
--------------------------------------------------------------------------------
/showImages/problem.md:
--------------------------------------------------------------------------------
1 | ## 因jitpack gradle7.0问题,导致原有版本3.2.4无法依赖问题。(实属jitpack大姨夫问题,请大家放心使用)
2 | 3.2.4发布了快2年了,一直也没动过。也是最近通过issue才发现有问题。3.3.2在发布的时候已经发现此问题,并得到了解决。本以为已发布的版本不会有问题,给大家带来的不便深感抱歉。
3 |
4 | ## 解决方法
5 | 原有3.2.4 release版本超过7天不能被更新。如果还在使用3.2.4且无法依赖的话,依赖以下
6 | ```java
7 | implementation 'com.github.lihangleo2:ShadowLayout:3.2.4rz'
8 | ```
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/showImages/ripple.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/ripple.gif
--------------------------------------------------------------------------------
/showImages/shapeSelector2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/shapeSelector2.gif
--------------------------------------------------------------------------------
/showImages/shape_gif.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/shape_gif.gif
--------------------------------------------------------------------------------
/showImages/show_3.3.1_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/show_3.3.1_1.jpg
--------------------------------------------------------------------------------
/showImages/show_3.3.1_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/show_3.3.1_2.jpg
--------------------------------------------------------------------------------
/showImages/show_3.3.1_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/show_3.3.1_3.jpg
--------------------------------------------------------------------------------
/showImages/singleShadow_bug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/singleShadow_bug.png
--------------------------------------------------------------------------------
/showImages/singleShadow_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/singleShadow_ok.png
--------------------------------------------------------------------------------
/showImages/stroke2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lihangleo2/ShadowLayout/869f8faf0e072664881ff404fdd82fbe890bc524/showImages/stroke2.gif
--------------------------------------------------------------------------------