├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── vincent │ │ └── blurdialog │ │ └── sample │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── vincent │ │ │ └── blurdialog │ │ │ └── sample │ │ │ ├── DialogApplication.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable-xxhdpi │ │ ├── ic_fingerprint.png │ │ └── messi.jpeg │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── menu │ │ └── main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── vincent │ └── blurdialog │ └── sample │ └── ExampleUnitTest.java ├── art ├── confirm.png ├── cus_confirm.png ├── cus_list.png ├── delete.png ├── list.png ├── none.png ├── progress.png ├── single.png └── waiting.png ├── blurdialog ├── build.gradle ├── libs │ └── .gitignore ├── proguard-rules.pro ├── publish.gradle └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── vincent │ │ └── blurdialog │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── vincent │ │ │ └── blurdialog │ │ │ ├── BlurDialog.java │ │ │ ├── adapter │ │ │ └── SingleSelectAdapter.java │ │ │ ├── blur │ │ │ ├── RealtimeBlurView.java │ │ │ └── RoundRectBlurView.java │ │ │ ├── helper │ │ │ └── BlurDialogHelper.java │ │ │ ├── listener │ │ │ ├── OnItemClick.java │ │ │ ├── OnNegativeClick.java │ │ │ └── OnPositiveClick.java │ │ │ └── view │ │ │ ├── DeterminateProgressView.java │ │ │ └── IndeterminateProgressView.java │ └── res │ │ ├── anim │ │ ├── vw_dialog_scale_in.xml │ │ ├── vw_dialog_slide_in_bottom.xml │ │ └── vw_dialog_slide_out_bottom.xml │ │ ├── drawable │ │ └── .gitignore │ │ ├── layout │ │ ├── vw_dialog_option_double.xml │ │ ├── vw_dialog_option_none.xml │ │ ├── vw_dialog_option_single.xml │ │ ├── vw_dialog_select_single.xml │ │ └── vw_dialog_single_item.xml │ │ ├── values-zh │ │ └── strings.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── vincent │ └── blurdialog │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea 38 | .idea/workspace.xml 39 | .idea/tasks.xml 40 | .idea/gradle.xml 41 | .idea/dictionaries 42 | .idea/libraries 43 | 44 | # Keystore files 45 | *.jks 46 | 47 | # External native build folder generated in Android Studio 2.2 and later 48 | .externalNativeBuild 49 | 50 | # Google Services (e.g. APIs or Firebase) 51 | google-services.json 52 | 53 | # Freeline 54 | freeline.py 55 | freeline/ 56 | freeline_project_description.json 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlurDialog 2 | A blur dialog in Android which is high-imitation of iOS. 3 | 4 | [![Download](https://api.bintray.com/packages/vincentwoo/maven/BlurDialog/images/download.svg) ](https://bintray.com/vincentwoo/maven/BlurDialog/_latestVersion) 5 | 6 |
7 | 确认对话框 9 | 单选项对话框 11 | 删除对话框 13 |  无选项对话框 15 | 列表对话框 17 | 等待对话框 19 | 进度对话框 21 | 自定义确认对话框 23 | 自定义列表对话框 25 |
26 | 27 | ## Step 28 | ### 1.Import to your project 29 | compile 'com.vincent.blurdialog:BlurDialog:1.0.1' 30 | 31 | ### 2.Add Render Script API to your project 32 | ```gradle 33 | android { 34 | ... 35 | defaultConfig { 36 | ... 37 | renderscriptTargetApi 19 38 | renderscriptSupportModeEnabled true // Enable RS support 39 | ... 40 | } 41 | ... 42 | } 43 | ``` 44 | 45 | ### 3.Use the dialog as the sample code 46 | 47 | ## Thanks 48 | Inspired by [RealtimeBlurView](https://github.com/mmin18/RealtimeBlurView) 49 | 50 | ## License 51 | ``` 52 | Copyright 2018 Vincent Woo 53 | 54 | Licensed under the Apache License, Version 2.0 (the "License"); 55 | you may not use this file except in compliance with the License. 56 | You may obtain a copy of the License at 57 | 58 | http://www.apache.org/licenses/LICENSE-2.0 59 | 60 | Unless required by applicable law or agreed to in writing, software 61 | distributed under the License is distributed on an "AS IS" BASIS, 62 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 63 | See the License for the specific language governing permissions and 64 | limitations under the License. 65 | ``` 66 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | defaultConfig { 6 | applicationId "com.vincent.blurdialog.sample" 7 | minSdkVersion 19 8 | targetSdkVersion 26 9 | versionCode 1 10 | versionName "1.0" 11 | renderscriptTargetApi 19 12 | renderscriptSupportModeEnabled true // Enable RS support 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | implementation fileTree(include: ['*.jar'], dir: 'libs') 25 | implementation 'com.android.support:appcompat-v7:26.1.0' 26 | implementation 'com.android.support.constraint:constraint-layout:1.1.0' 27 | testImplementation 'junit:junit:4.12' 28 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 29 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 30 | implementation project(':blurdialog') 31 | debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4' 32 | releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4' 33 | } 34 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/vincent/blurdialog/sample/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.sample; 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() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.vincent.blurdialog.sample", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/vincent/blurdialog/sample/DialogApplication.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.sample; 2 | 3 | import android.app.Application; 4 | 5 | import com.squareup.leakcanary.LeakCanary; 6 | 7 | /** 8 | * Created by vincent on 2018/4/26. 9 | */ 10 | 11 | public class DialogApplication extends Application { 12 | @Override public void onCreate() { 13 | super.onCreate(); 14 | if (LeakCanary.isInAnalyzerProcess(this)) { 15 | // This process is dedicated to LeakCanary for heap analysis. 16 | // You should not init your app in this process. 17 | return; 18 | } 19 | LeakCanary.install(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/vincent/blurdialog/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.sample; 2 | 3 | import android.content.DialogInterface; 4 | import android.os.Bundle; 5 | import android.os.Handler; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.support.v7.widget.Toolbar; 8 | import android.text.Html; 9 | import android.util.TypedValue; 10 | import android.view.Menu; 11 | import android.view.MenuItem; 12 | import android.widget.FrameLayout; 13 | import android.widget.ImageView; 14 | import android.widget.Toast; 15 | 16 | import com.vincent.blurdialog.BlurDialog; 17 | import com.vincent.blurdialog.listener.OnItemClick; 18 | import com.vincent.blurdialog.listener.OnNegativeClick; 19 | import com.vincent.blurdialog.listener.OnPositiveClick; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | import static com.vincent.blurdialog.BlurDialog.TYPE_DELETE; 25 | import static com.vincent.blurdialog.BlurDialog.TYPE_PROGRESS; 26 | import static com.vincent.blurdialog.BlurDialog.TYPE_SINGLE_OPTION; 27 | import static com.vincent.blurdialog.BlurDialog.TYPE_SINGLE_SELECT; 28 | 29 | public class MainActivity extends AppCompatActivity { 30 | private BlurDialog dialog; 31 | 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.activity_main); 36 | Toolbar toolbar = findViewById(R.id.toolbar); 37 | setSupportActionBar(toolbar); 38 | } 39 | 40 | @Override 41 | public boolean onCreateOptionsMenu(Menu menu) { 42 | getMenuInflater().inflate(R.menu.main, menu); 43 | return true; 44 | } 45 | 46 | @Override 47 | public boolean onOptionsItemSelected(MenuItem item) { 48 | switch (item.getItemId()) { 49 | case R.id.def_confirm: 50 | final BlurDialog dlg = new BlurDialog(); 51 | BlurDialog.Builder builder = new BlurDialog.Builder() 52 | .isCancelable(true) 53 | .isOutsideCancelable(true) 54 | .message("Messi is the best football player") 55 | .positiveMsg("Yes") 56 | .negativeMsg("No") 57 | .positiveClick(new OnPositiveClick() { 58 | @Override 59 | public void onClick() { 60 | dlg.dismiss(); 61 | Toast.makeText(MainActivity.this, "Yes, definitely!", Toast.LENGTH_SHORT).show(); 62 | } 63 | }) 64 | .negativeClick(new OnNegativeClick() { 65 | @Override 66 | public void onClick() { 67 | dlg.dismiss(); 68 | Toast.makeText(MainActivity.this, "No, CR7 is the best!", Toast.LENGTH_SHORT).show(); 69 | } 70 | }) 71 | .dismissListener(new DialogInterface.OnDismissListener() { 72 | @Override 73 | public void onDismiss(DialogInterface dialog) { 74 | } 75 | }) 76 | .type(BlurDialog.TYPE_DOUBLE_OPTION) 77 | .createBuilder(MainActivity.this); 78 | dlg.setBuilder(builder); 79 | dlg.show(); 80 | break; 81 | case R.id.def_single: 82 | dialog = new BlurDialog.Builder() 83 | .isCancelable(true) 84 | .isOutsideCancelable(true) 85 | .message("Messi is the best football player") 86 | .positiveMsg("Yes") 87 | .positiveClick(new OnPositiveClick() { 88 | @Override 89 | public void onClick() { 90 | Toast.makeText(MainActivity.this, "Yes, definitely!", Toast.LENGTH_SHORT).show(); 91 | } 92 | }) 93 | .dismissListener(new DialogInterface.OnDismissListener() { 94 | @Override 95 | public void onDismiss(DialogInterface dialog) { 96 | Toast.makeText(MainActivity.this, "I have no idea about it!", Toast.LENGTH_SHORT).show(); 97 | } 98 | }) 99 | .type(TYPE_SINGLE_OPTION) 100 | .build(MainActivity.this); 101 | dialog.show(); 102 | break; 103 | case R.id.def_none: 104 | ImageView iv = new ImageView(this); 105 | iv.setImageResource(R.drawable.ic_fingerprint); 106 | dialog = new BlurDialog.Builder() 107 | .isCancelable(true) 108 | .isOutsideCancelable(true) 109 | .message("Please input your fingerprint") 110 | .centerView(iv, 111 | new FrameLayout.LayoutParams( 112 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()), 113 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()))) 114 | .type(BlurDialog.TYPE_NONE_OPTION) 115 | .build(MainActivity.this); 116 | dialog.show(); 117 | break; 118 | case R.id.def_del: 119 | dialog = new BlurDialog.Builder() 120 | .radius(10)//dp 121 | .isCancelable(true) 122 | .isOutsideCancelable(true) 123 | .message("Do you want delete this project?") 124 | .positiveClick(new OnPositiveClick() { 125 | @Override 126 | public void onClick() { 127 | Toast.makeText(MainActivity.this, "Yes", Toast.LENGTH_SHORT).show(); 128 | } 129 | }) 130 | .negativeClick(new OnNegativeClick() { 131 | @Override 132 | public void onClick() { 133 | Toast.makeText(MainActivity.this, "No", Toast.LENGTH_SHORT).show(); 134 | } 135 | }) 136 | .dismissListener(new DialogInterface.OnDismissListener() { 137 | @Override 138 | public void onDismiss(DialogInterface dialog) { 139 | Toast.makeText(MainActivity.this, "I have no idea about it!", Toast.LENGTH_SHORT).show(); 140 | } 141 | }) 142 | .type(TYPE_DELETE) 143 | .build(MainActivity.this); 144 | dialog.show(); 145 | break; 146 | case R.id.def_list: 147 | final List list = new ArrayList<>(); 148 | list.add(Html.fromHtml("R10")); 149 | list.add(Html.fromHtml("KUN")); 150 | list.add(Html.fromHtml("Suarez")); 151 | list.add(Html.fromHtml("Neymar")); 152 | 153 | dialog = new BlurDialog.Builder() 154 | .isCancelable(true) 155 | .isOutsideCancelable(true) 156 | .message("Messi the best football player") 157 | .singleList(list) 158 | .itemClick(new OnItemClick() { 159 | @Override 160 | public void onClick(CharSequence item) { 161 | if (item.equals(list.get(0))) { 162 | Toast.makeText(MainActivity.this, "Ronaldinho", Toast.LENGTH_SHORT).show(); 163 | } 164 | 165 | if (item.equals(list.get(1))) { 166 | Toast.makeText(MainActivity.this, "Sergio Agüero", Toast.LENGTH_SHORT).show(); 167 | } 168 | 169 | if (item.equals(list.get(2))) { 170 | Toast.makeText(MainActivity.this, "Luis Suarez", Toast.LENGTH_SHORT).show(); 171 | } 172 | 173 | if (item.equals(list.get(3))) { 174 | Toast.makeText(MainActivity.this, "Neymar JR", Toast.LENGTH_SHORT).show(); 175 | } 176 | } 177 | }) 178 | .negativeClick(new OnNegativeClick() { 179 | @Override 180 | public void onClick() { 181 | Toast.makeText(MainActivity.this, "cancel", Toast.LENGTH_SHORT).show(); 182 | dialog.dismiss(); 183 | } 184 | }) 185 | .dismissListener(new DialogInterface.OnDismissListener() { 186 | @Override 187 | public void onDismiss(DialogInterface dialog) { 188 | } 189 | }) 190 | .type(TYPE_SINGLE_SELECT) 191 | .build(MainActivity.this); 192 | dialog.show(); 193 | break; 194 | case R.id.waiting: 195 | dialog = new BlurDialog.Builder() 196 | .isCancelable(true) 197 | .isOutsideCancelable(true) 198 | .message("Please wait...") 199 | .dismissListener(new DialogInterface.OnDismissListener() { 200 | @Override 201 | public void onDismiss(DialogInterface dialog) { 202 | Toast.makeText(MainActivity.this, "I have no idea about it!", Toast.LENGTH_SHORT).show(); 203 | } 204 | }) 205 | .type(BlurDialog.TYPE_WAIT) 206 | .build(MainActivity.this); 207 | dialog.show(); 208 | break; 209 | case R.id.progress: 210 | dialog = new BlurDialog.Builder() 211 | .isCancelable(true) 212 | .isOutsideCancelable(true) 213 | .message("正在下载中...") 214 | .positiveMsg("取消") 215 | .positiveClick(new OnPositiveClick() { 216 | @Override 217 | public void onClick() { 218 | dialog.dismiss(); 219 | Toast.makeText(MainActivity.this, "Download cancel", Toast.LENGTH_SHORT).show(); 220 | } 221 | }) 222 | .onProgressFinishedListener(new BlurDialog.OnProgressFinishedListener() { 223 | @Override 224 | public void onProgressFinished() { 225 | Toast.makeText(MainActivity.this, "Download finished", Toast.LENGTH_SHORT).show(); 226 | } 227 | }) 228 | .type(TYPE_PROGRESS) 229 | .build(MainActivity.this); 230 | dialog.show(); 231 | percent = 0; 232 | doProgress(); 233 | break; 234 | case R.id.custom_confirm: 235 | dialog = new BlurDialog.Builder() 236 | .isCancelable(true) 237 | .isOutsideCancelable(true) 238 | .message(Html.fromHtml("

Messi

The best football player")) 239 | .positiveMsg(Html.fromHtml("Yes")) //You can change color by Html 240 | .negativeMsg("No") 241 | .positiveClick(new OnPositiveClick() { 242 | @Override 243 | public void onClick() { 244 | Toast.makeText(MainActivity.this, "Yes, definitely!", Toast.LENGTH_SHORT).show(); 245 | } 246 | }) 247 | .negativeClick(new OnNegativeClick() { 248 | @Override 249 | public void onClick() { 250 | Toast.makeText(MainActivity.this, "No, CR7 is the best!", Toast.LENGTH_SHORT).show(); 251 | } 252 | }) 253 | .dismissListener(new DialogInterface.OnDismissListener() { 254 | @Override 255 | public void onDismiss(DialogInterface dialog) { 256 | Toast.makeText(MainActivity.this, "I have no idea about it!", Toast.LENGTH_SHORT).show(); 257 | } 258 | }) 259 | .type(BlurDialog.TYPE_DOUBLE_OPTION) 260 | .build(MainActivity.this); 261 | dialog.show(); 262 | break; 263 | case R.id.custom_list: 264 | final List li = new ArrayList<>(); 265 | li.add(Html.fromHtml("R10")); 266 | li.add(Html.fromHtml("KUN")); 267 | li.add(Html.fromHtml("Suarez")); 268 | li.add(Html.fromHtml("Neymar")); 269 | dialog = new BlurDialog.Builder() 270 | .isCancelable(true) 271 | .isOutsideCancelable(true) 272 | .message(Html.fromHtml("

Messi

The best football player")) 273 | .singleList(li) 274 | .singleListCancelMsg(Html.fromHtml("Exit"))//default is blue cancel 275 | .itemClick(new OnItemClick() { 276 | @Override 277 | public void onClick(CharSequence item) { 278 | if (item.equals(li.get(0))) { 279 | Toast.makeText(MainActivity.this, "Ronaldinho", Toast.LENGTH_SHORT).show(); 280 | } 281 | 282 | if (item.equals(li.get(1))) { 283 | Toast.makeText(MainActivity.this, "Sergio Agüero", Toast.LENGTH_SHORT).show(); 284 | } 285 | 286 | if (item.equals(li.get(2))) { 287 | Toast.makeText(MainActivity.this, "Luis Suarez", Toast.LENGTH_SHORT).show(); 288 | } 289 | 290 | if (item.equals(li.get(3))) { 291 | Toast.makeText(MainActivity.this, "Neymar JR", Toast.LENGTH_SHORT).show(); 292 | } 293 | } 294 | }) 295 | .negativeClick(new OnNegativeClick() { 296 | @Override 297 | public void onClick() { 298 | Toast.makeText(MainActivity.this, "exit the best friend list of Messi!", Toast.LENGTH_SHORT).show(); 299 | dialog.dismiss(); 300 | } 301 | }) 302 | .dismissListener(new DialogInterface.OnDismissListener() { 303 | @Override 304 | public void onDismiss(DialogInterface dialog) { 305 | } 306 | }) 307 | .type(TYPE_SINGLE_SELECT) 308 | .build(MainActivity.this); 309 | dialog.show(); 310 | break; 311 | } 312 | return true; 313 | } 314 | 315 | private float percent = 0; 316 | private void doProgress() { 317 | new Handler().postDelayed(new Runnable() { 318 | @Override 319 | public void run() { 320 | dialog.setProgress(percent += 6); 321 | doProgress(); 322 | } 323 | }, 1000); 324 | } 325 | } 326 | -------------------------------------------------------------------------------- /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-xxhdpi/ic_fingerprint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/drawable-xxhdpi/ic_fingerprint.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/messi.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/drawable-xxhdpi/messi.jpeg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 14 | 18 | 22 | 26 | 30 | 34 | 38 | 42 | -------------------------------------------------------------------------------- /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/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | BlurDialogSample 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/test/java/com/vincent/blurdialog/sample/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.sample; 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() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /art/confirm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/confirm.png -------------------------------------------------------------------------------- /art/cus_confirm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/cus_confirm.png -------------------------------------------------------------------------------- /art/cus_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/cus_list.png -------------------------------------------------------------------------------- /art/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/delete.png -------------------------------------------------------------------------------- /art/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/list.png -------------------------------------------------------------------------------- /art/none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/none.png -------------------------------------------------------------------------------- /art/progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/progress.png -------------------------------------------------------------------------------- /art/single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/single.png -------------------------------------------------------------------------------- /art/waiting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/art/waiting.png -------------------------------------------------------------------------------- /blurdialog/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion "26.0.2" 6 | 7 | defaultConfig { 8 | minSdkVersion 14 9 | targetSdkVersion 26 10 | versionCode 1 11 | versionName "1.0.0" 12 | renderscriptTargetApi 19 13 | renderscriptSupportModeEnabled true // Enable RS support 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | lintOptions { 23 | abortOnError false 24 | } 25 | } 26 | 27 | dependencies { 28 | compile fileTree(dir: 'libs', include: ['*.jar']) 29 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 30 | exclude group: 'com.android.support', module: 'support-annotations' 31 | }) 32 | compile 'com.android.support:appcompat-v7:26.1.0' 33 | compile 'com.android.support:recyclerview-v7:26.1.0' 34 | testCompile 'junit:junit:4.12' 35 | } 36 | 37 | apply from: 'publish.gradle' -------------------------------------------------------------------------------- /blurdialog/libs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/blurdialog/libs/.gitignore -------------------------------------------------------------------------------- /blurdialog/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android_SDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /blurdialog/publish.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.github.dcendents.android-maven' 2 | apply plugin: 'com.jfrog.bintray' 3 | 4 | def prjVersion = "1.0.2" 5 | def prjGroup = "com.vincent.blurdialog" 6 | def prjName = "BlurDialog" 7 | def prjArtifactId = "BlurDialog" 8 | def prjDescription = "A blur dialog in Android which is high-imitation of iOS" 9 | def siteUrl = 'https://github.com/fishwjy/BlurDialog' // 项目的主页 10 | def gitUrl = 'https://github.com/fishwjy/BlurDialog.git' // Git仓库的url 11 | def pckName = "BlurDialog" //发布到JCenter上的项目名字 12 | def bintrayRepo = "maven" 13 | 14 | version = prjVersion 15 | group = prjGroup 16 | project.archivesBaseName=prjArtifactId 17 | install { 18 | repositories.mavenInstaller { 19 | // This generates POM.xml with proper parameters 20 | pom.project { 21 | packaging 'aar' 22 | // Add your description here 23 | name prjName 24 | version prjVersion 25 | groupId prjGroup 26 | description prjDescription 27 | url siteUrl 28 | artifactId prjArtifactId 29 | // Set your license 30 | licenses { 31 | license { 32 | name 'The Apache Software License, Version 2.0' 33 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 34 | } 35 | } 36 | developers { 37 | developer { 38 | id 'vincentwoo' 39 | name 'VincentWoo' 40 | email 'fishwjy@gmail.com' 41 | } 42 | } 43 | scm { 44 | connection gitUrl 45 | developerConnection gitUrl 46 | url siteUrl 47 | } 48 | } 49 | } 50 | } 51 | 52 | task sourcesJar(type: Jar) { 53 | from android.sourceSets.main.java.srcDirs 54 | classifier = 'sources' 55 | } 56 | 57 | task javadoc(type: Javadoc) { 58 | options.encoding = "UTF-8" 59 | source = android.sourceSets.main.java.srcDirs 60 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 61 | } 62 | 63 | tasks.withType(JavaCompile) { 64 | options.encoding = "UTF-8" 65 | } 66 | 67 | task javadocJar(type: Jar, dependsOn: javadoc) { 68 | classifier = 'javadoc' 69 | from javadoc.destinationDir 70 | } 71 | 72 | artifacts { 73 | archives javadocJar 74 | archives sourcesJar 75 | } 76 | 77 | Properties properties = new Properties() 78 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 79 | bintray { 80 | user = properties.getProperty("bintray.user") 81 | key = properties.getProperty("bintray.apikey") 82 | configurations = ['archives'] 83 | publish = true 84 | dryRun = false 85 | pkg { 86 | repo = bintrayRepo 87 | name = pckName 88 | websiteUrl = siteUrl 89 | vcsUrl = gitUrl 90 | licenses = ["Apache-2.0"] 91 | publicDownloadNumbers = true 92 | version { 93 | name = prjVersion 94 | desc = prjDescription 95 | vcsTag = prjVersion 96 | 97 | gpg { 98 | sign = true 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /blurdialog/src/androidTest/java/com/vincent/blurdialog/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog; 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 | * Instrumentation 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() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.vincent.blurdialog.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /blurdialog/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/BlurDialog.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog; 2 | 3 | import android.animation.Animator; 4 | import android.animation.ObjectAnimator; 5 | import android.app.Dialog; 6 | import android.content.Context; 7 | import android.content.DialogInterface; 8 | import android.graphics.Color; 9 | import android.graphics.drawable.ColorDrawable; 10 | import android.support.annotation.Nullable; 11 | import android.support.v7.widget.LinearLayoutManager; 12 | import android.support.v7.widget.RecyclerView; 13 | import android.text.TextUtils; 14 | import android.util.TypedValue; 15 | import android.view.Gravity; 16 | import android.view.View; 17 | import android.view.Window; 18 | import android.view.WindowManager; 19 | import android.widget.FrameLayout; 20 | import android.widget.TextView; 21 | 22 | import com.vincent.blurdialog.adapter.SingleSelectAdapter; 23 | import com.vincent.blurdialog.blur.RoundRectBlurView; 24 | import com.vincent.blurdialog.helper.BlurDialogHelper; 25 | import com.vincent.blurdialog.listener.OnItemClick; 26 | import com.vincent.blurdialog.listener.OnNegativeClick; 27 | import com.vincent.blurdialog.listener.OnPositiveClick; 28 | import com.vincent.blurdialog.view.DeterminateProgressView; 29 | import com.vincent.blurdialog.view.IndeterminateProgressView; 30 | 31 | import java.util.List; 32 | 33 | /** 34 | * Created by vincent on 2017/11/22. 35 | */ 36 | 37 | public class BlurDialog { 38 | public static final int TYPE_DOUBLE_OPTION = 0; 39 | public static final int TYPE_SINGLE_OPTION = 1; 40 | public static final int TYPE_NONE_OPTION = 2; 41 | public static final int TYPE_DELETE = 3; 42 | public static final int TYPE_WAIT = 4; 43 | public static final int TYPE_PROGRESS = 5; 44 | public static final int TYPE_SINGLE_SELECT = 6; 45 | 46 | private int mWindowPaddingStart = 70; 47 | private int mWindowPaddingEnd = 70; 48 | 49 | private Dialog mDialog; 50 | 51 | private Builder builder; 52 | 53 | private float preProgress = 0; 54 | private float curProgress = 0; 55 | private ObjectAnimator mProgressAnimator; 56 | 57 | public BlurDialog() { 58 | } 59 | 60 | public BlurDialog(Builder builder) { 61 | this.builder = builder; 62 | } 63 | 64 | private BlurDialog createDialog(Context ctx) { 65 | mDialog = new Dialog(ctx, android.R.style.Theme_DeviceDefault_Dialog_NoActionBar); 66 | mDialog.setCanceledOnTouchOutside(builder.isOutsideCancelable); 67 | mDialog.setCancelable(builder.isCancelable); 68 | if (builder.dismissListener != null) mDialog.setOnDismissListener(builder.dismissListener); 69 | 70 | switch (builder.type) { 71 | case TYPE_DOUBLE_OPTION: 72 | confirmDoubleStyle(mDialog); 73 | break; 74 | case TYPE_SINGLE_OPTION: 75 | confirmSingleStyle(mDialog); 76 | break; 77 | case TYPE_NONE_OPTION: 78 | confirmNoneStyle(mDialog); 79 | break; 80 | case TYPE_DELETE: 81 | deleteStyle(mDialog); 82 | break; 83 | case TYPE_WAIT: 84 | waitStyle(mDialog, builder); 85 | break; 86 | case TYPE_PROGRESS: 87 | progressStyle(mDialog, builder); 88 | break; 89 | case TYPE_SINGLE_SELECT: 90 | selectSingleStyle(mDialog); 91 | break; 92 | } 93 | 94 | return this; 95 | } 96 | 97 | private void confirmDoubleStyle(Dialog dialog) { 98 | dialog.setContentView(R.layout.vw_dialog_option_double); 99 | 100 | TextView vw_dialog_tv_msg = dialog.findViewById(R.id.vw_dialog_tv_msg); 101 | vw_dialog_tv_msg.setText(builder.message); 102 | 103 | FrameLayout vw_dialog_fl_center = dialog.findViewById(R.id.vw_dialog_fl_center); 104 | if (builder.centerView != null && builder.centerViewParams != null) { 105 | vw_dialog_fl_center.setVisibility(View.VISIBLE); 106 | vw_dialog_fl_center.addView(builder.centerView, builder.centerViewParams); 107 | } else { 108 | vw_dialog_fl_center.setVisibility(View.GONE); 109 | } 110 | 111 | TextView vw_dialog_tv_ok = dialog.findViewById(R.id.vw_dialog_tv_ok); 112 | if (!TextUtils.isEmpty(builder.positiveMsg)) { 113 | vw_dialog_tv_ok.setText(builder.positiveMsg); 114 | } 115 | vw_dialog_tv_ok.setOnClickListener(new View.OnClickListener() { 116 | @Override 117 | public void onClick(View view) { 118 | if (builder.positiveClick != null) { 119 | builder.positiveClick.onClick(); 120 | } 121 | } 122 | }); 123 | 124 | TextView vw_dialog_tv_cancel = dialog.findViewById(R.id.vw_dialog_tv_cancel); 125 | if (!TextUtils.isEmpty(builder.negativeMsg)) { 126 | vw_dialog_tv_cancel.setText(builder.negativeMsg); 127 | } 128 | vw_dialog_tv_cancel.setOnClickListener(new View.OnClickListener() { 129 | @Override 130 | public void onClick(View view) { 131 | if (builder.negativeClick != null) { 132 | builder.negativeClick.onClick(); 133 | } 134 | } 135 | }); 136 | 137 | float radius = BlurDialogHelper.getRadius(dialog.getContext(), builder.radius); 138 | 139 | RoundRectBlurView bv = dialog.findViewById(R.id.bv); 140 | bv.setRadius(radius); 141 | 142 | vw_dialog_tv_ok = dialog.findViewById(R.id.vw_dialog_tv_ok); 143 | BlurDialogHelper.setBackGroundDrawable(dialog.getContext(), vw_dialog_tv_ok, new float[]{ 144 | 0, 0, //左上角 145 | 0, 0, //右上角 146 | radius, radius, //右下角 147 | 0, 0 //左下角 148 | }); 149 | 150 | vw_dialog_tv_cancel = dialog.findViewById(R.id.vw_dialog_tv_cancel); 151 | BlurDialogHelper.setBackGroundDrawable(dialog.getContext(), vw_dialog_tv_cancel, new float[]{ 152 | 0, 0, //左上角 153 | 0, 0, //右上角 154 | 0, 0, //右下角 155 | radius, radius //左下角 156 | }); 157 | 158 | centerStyle(dialog); 159 | } 160 | 161 | private void confirmSingleStyle(Dialog dialog) { 162 | confirmSingleStyle(dialog, mWindowPaddingStart, mWindowPaddingEnd); 163 | } 164 | 165 | private void confirmSingleStyle(Dialog dialog, int paddingStart, int paddingEnd) { 166 | dialog.setContentView(R.layout.vw_dialog_option_single); 167 | 168 | TextView vw_dialog_tv_msg = dialog.findViewById(R.id.vw_dialog_tv_msg); 169 | vw_dialog_tv_msg.setText(builder.message); 170 | 171 | FrameLayout vw_dialog_fl_center = dialog.findViewById(R.id.vw_dialog_fl_center); 172 | if (builder.centerView != null && builder.centerViewParams != null) { 173 | vw_dialog_fl_center.setVisibility(View.VISIBLE); 174 | vw_dialog_fl_center.addView(builder.centerView, builder.centerViewParams); 175 | } else { 176 | vw_dialog_fl_center.setVisibility(View.GONE); 177 | } 178 | 179 | TextView vw_dialog_tv_ok = dialog.findViewById(R.id.vw_dialog_tv_ok); 180 | if (!TextUtils.isEmpty(builder.positiveMsg)) { 181 | vw_dialog_tv_ok.setText(builder.positiveMsg); 182 | } 183 | vw_dialog_tv_ok.setOnClickListener(new View.OnClickListener() { 184 | @Override 185 | public void onClick(View view) { 186 | if (builder.positiveClick != null) { 187 | builder.positiveClick.onClick(); 188 | } 189 | } 190 | }); 191 | 192 | float radius = BlurDialogHelper.getRadius(dialog.getContext(), builder.radius); 193 | 194 | RoundRectBlurView bv = dialog.findViewById(R.id.bv); 195 | bv.setRadius(radius); 196 | 197 | vw_dialog_tv_ok = dialog.findViewById(R.id.vw_dialog_tv_ok); 198 | BlurDialogHelper.setBackGroundDrawable(dialog.getContext(), vw_dialog_tv_ok, new float[]{ 199 | 0, 0, //左上角 200 | 0, 0, //右上角 201 | radius, radius, //右下角 202 | radius, radius //左下角 203 | }); 204 | 205 | centerStyle(dialog, paddingStart, paddingEnd); 206 | } 207 | 208 | private void confirmNoneStyle(Dialog dialog) { 209 | confirmNoneStyle(dialog, mWindowPaddingStart, mWindowPaddingEnd); 210 | } 211 | 212 | private void confirmNoneStyle(Dialog dialog, int paddingStart, int paddingEnd) { 213 | dialog.setContentView(R.layout.vw_dialog_option_none); 214 | 215 | TextView vw_dialog_tv_msg = dialog.findViewById(R.id.vw_dialog_tv_msg); 216 | vw_dialog_tv_msg.setText(builder.message); 217 | 218 | FrameLayout vw_dialog_fl_center = dialog.findViewById(R.id.vw_dialog_fl_center); 219 | if (builder.centerView != null && builder.centerViewParams != null) { 220 | vw_dialog_fl_center.setVisibility(View.VISIBLE); 221 | vw_dialog_fl_center.addView(builder.centerView, builder.centerViewParams); 222 | } else { 223 | vw_dialog_fl_center.setVisibility(View.GONE); 224 | } 225 | 226 | float radius = BlurDialogHelper.getRadius(dialog.getContext(), builder.radius); 227 | 228 | RoundRectBlurView bv = dialog.findViewById(R.id.bv); 229 | bv.setRadius(radius); 230 | 231 | centerStyle(dialog, paddingStart, paddingEnd); 232 | } 233 | 234 | private void deleteStyle(Dialog dialog) { 235 | confirmDoubleStyle(dialog); 236 | TextView vw_dialog_tv_ok = dialog.findViewById(R.id.vw_dialog_tv_ok); 237 | vw_dialog_tv_ok.setText(dialog.getContext().getResources().getString(R.string.vw_dialog_delete)); 238 | vw_dialog_tv_ok.setTextColor(dialog.getContext().getResources().getColor(R.color.vw_dialog_red)); 239 | } 240 | 241 | private void waitStyle(Dialog dialog, Builder builder) { 242 | builder.centerView(new IndeterminateProgressView(dialog.getContext()), 243 | new FrameLayout.LayoutParams( 244 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, dialog.getContext().getResources().getDisplayMetrics()), 245 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, dialog.getContext().getResources().getDisplayMetrics()))); 246 | 247 | confirmNoneStyle(dialog, 120, 120); 248 | } 249 | 250 | private void progressStyle(Dialog dialog, Builder builder) { 251 | DeterminateProgressView view = new DeterminateProgressView(dialog.getContext()); 252 | builder.centerView(view, new FrameLayout.LayoutParams( 253 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, dialog.getContext().getResources().getDisplayMetrics()), 254 | (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, dialog.getContext().getResources().getDisplayMetrics()))); 255 | 256 | confirmSingleStyle(dialog); 257 | } 258 | 259 | private void selectSingleStyle(Dialog dialog) { 260 | dialog.setContentView(R.layout.vw_dialog_select_single); 261 | 262 | TextView vw_dialog_tv_cancel = dialog.findViewById(R.id.vw_dialog_tv_cancel); 263 | if (!TextUtils.isEmpty(builder.singleListCancelMsg)) { 264 | vw_dialog_tv_cancel.setText(builder.singleListCancelMsg); 265 | } 266 | vw_dialog_tv_cancel.setOnClickListener(new View.OnClickListener() { 267 | @Override 268 | public void onClick(View view) { 269 | if (builder.negativeClick != null) { 270 | builder.negativeClick.onClick(); 271 | } 272 | } 273 | }); 274 | 275 | float radius = BlurDialogHelper.getRadius(dialog.getContext(), builder.radius); 276 | 277 | RoundRectBlurView bv1 = dialog.findViewById(R.id.bv1); 278 | bv1.setRadius(radius); 279 | 280 | RoundRectBlurView bv2 = dialog.findViewById(R.id.bv2); 281 | bv2.setRadius(radius); 282 | 283 | vw_dialog_tv_cancel = dialog.findViewById(R.id.vw_dialog_tv_cancel); 284 | BlurDialogHelper.setBackGroundDrawable(dialog.getContext(), vw_dialog_tv_cancel, new float[]{ 285 | radius, radius, //左上角 286 | radius, radius, //右上角 287 | radius, radius, //右下角 288 | radius, radius //左下角 289 | }); 290 | 291 | RecyclerView rv_content = dialog.findViewById(R.id.rv_content); 292 | rv_content.setLayoutManager(new LinearLayoutManager(dialog.getContext())); 293 | rv_content.setAdapter(new SingleSelectAdapter(builder.singleList, radius, builder.itemClick)); 294 | 295 | bottomStyle(dialog); 296 | } 297 | 298 | private void centerStyle(Dialog dialog) { 299 | centerStyle(dialog, mWindowPaddingStart, mWindowPaddingEnd); 300 | } 301 | 302 | private void centerStyle(Dialog dialog, int paddingStart, int paddingEnd) { 303 | Window window = dialog.getWindow(); 304 | if (window == null) return; 305 | //设置window背景为透明色,否则会看到圆角外有黑色背景 306 | window.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00000000"))); 307 | //设置window弹出收起动画 308 | window.setWindowAnimations(R.style.vw_dialog_anim_center); 309 | //设置居中 310 | window.setGravity(Gravity.CENTER); 311 | //设置内边距 312 | window.getDecorView().setPadding( 313 | (int) TypedValue.applyDimension( 314 | TypedValue.COMPLEX_UNIT_DIP, 315 | paddingStart, 316 | dialog.getContext().getResources().getDisplayMetrics()), 317 | 0, 318 | (int) TypedValue.applyDimension( 319 | TypedValue.COMPLEX_UNIT_DIP, 320 | paddingEnd, 321 | dialog.getContext().getResources().getDisplayMetrics()), 322 | 0); 323 | //获得window窗口的属性 324 | android.view.WindowManager.LayoutParams lp = window.getAttributes(); 325 | lp.width = WindowManager.LayoutParams.MATCH_PARENT; 326 | lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 327 | //将设置好的属性set回去 328 | window.setAttributes(lp); 329 | } 330 | 331 | private void bottomStyle(Dialog dialog) { 332 | Window window = dialog.getWindow(); 333 | if (window == null) return; 334 | //设置window背景为透明色,否则会看到圆角外有黑色背景 335 | window.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00000000"))); 336 | //设置window弹出收起动画 337 | window.setWindowAnimations(R.style.vw_dialog_anim_bottom); 338 | //设置居中 339 | window.setGravity(Gravity.BOTTOM); 340 | //设置内边距 341 | window.getDecorView().setPadding( 342 | (int) TypedValue.applyDimension( 343 | TypedValue.COMPLEX_UNIT_DIP, 344 | 20, 345 | dialog.getContext().getResources().getDisplayMetrics()), 346 | 0, 347 | (int) TypedValue.applyDimension( 348 | TypedValue.COMPLEX_UNIT_DIP, 349 | 20, 350 | dialog.getContext().getResources().getDisplayMetrics()), 351 | (int) TypedValue.applyDimension( 352 | TypedValue.COMPLEX_UNIT_DIP, 353 | 10, 354 | dialog.getContext().getResources().getDisplayMetrics())); 355 | //获得window窗口的属性 356 | android.view.WindowManager.LayoutParams lp = window.getAttributes(); 357 | lp.width = WindowManager.LayoutParams.MATCH_PARENT; 358 | lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 359 | //将设置好的属性set回去 360 | window.setAttributes(lp); 361 | } 362 | 363 | public void show() { 364 | if (mDialog != null) { 365 | mDialog.show(); 366 | } 367 | } 368 | 369 | public void dismiss() { 370 | if (mDialog != null) { 371 | mDialog.dismiss(); 372 | } 373 | } 374 | 375 | public boolean isShowing() { 376 | if (mDialog != null) { 377 | return mDialog.isShowing(); 378 | } 379 | 380 | return false; 381 | } 382 | 383 | public static class Builder { 384 | private Context ctx; 385 | private boolean isCancelable; 386 | private boolean isOutsideCancelable; 387 | private int type = TYPE_DOUBLE_OPTION; 388 | private float radius = -1; //dp 389 | private CharSequence message; 390 | private CharSequence positiveMsg; 391 | private CharSequence negativeMsg; 392 | private List singleList; 393 | private CharSequence singleListCancelMsg; 394 | private View centerView; 395 | private FrameLayout.LayoutParams centerViewParams; 396 | 397 | private OnPositiveClick positiveClick; 398 | private OnNegativeClick negativeClick; 399 | private OnItemClick itemClick; 400 | private DialogInterface.OnDismissListener dismissListener; 401 | private OnProgressFinishedListener onProgressFinishedListener; 402 | 403 | public Builder type(int type) { 404 | this.type = type; 405 | return this; 406 | } 407 | 408 | public Builder isCancelable(boolean cancelable) { 409 | this.isCancelable = cancelable; 410 | return this; 411 | } 412 | 413 | public Builder isOutsideCancelable(boolean cancelable) { 414 | this.isOutsideCancelable = cancelable; 415 | return this; 416 | } 417 | 418 | public Builder radius(float radius) { 419 | this.radius = radius; 420 | return this; 421 | } 422 | 423 | public Builder message(CharSequence msg) { 424 | this.message = msg; 425 | return this; 426 | } 427 | 428 | public Builder singleList(List singleList) { 429 | this.singleList = singleList; 430 | return this; 431 | } 432 | 433 | public Builder singleListCancelMsg(CharSequence singleListCancelMsg) { 434 | this.singleListCancelMsg = singleListCancelMsg; 435 | return this; 436 | } 437 | 438 | public Builder centerView(View view, FrameLayout.LayoutParams params) { 439 | this.centerView = view; 440 | this.centerViewParams = params; 441 | return this; 442 | } 443 | 444 | public Builder positiveMsg(CharSequence positiveMsg) { 445 | this.positiveMsg = positiveMsg; 446 | return this; 447 | } 448 | 449 | public Builder negativeMsg(CharSequence negativeMsg) { 450 | this.negativeMsg = negativeMsg; 451 | return this; 452 | } 453 | 454 | public Builder positiveClick(OnPositiveClick positiveClick) { 455 | this.positiveClick = positiveClick; 456 | return this; 457 | } 458 | 459 | public Builder negativeClick(OnNegativeClick negativeClick) { 460 | this.negativeClick = negativeClick; 461 | return this; 462 | } 463 | 464 | public Builder itemClick(OnItemClick itemClick) { 465 | this.itemClick = itemClick; 466 | return this; 467 | } 468 | 469 | public Builder dismissListener(DialogInterface.OnDismissListener dismissListener) { 470 | this.dismissListener = dismissListener; 471 | return this; 472 | } 473 | 474 | public Builder onProgressFinishedListener(OnProgressFinishedListener onProgressFinishedListener) { 475 | this.onProgressFinishedListener = onProgressFinishedListener; 476 | return this; 477 | } 478 | 479 | public BlurDialog build(Context ctx) { 480 | this.ctx = ctx; 481 | BlurDialog helper = new BlurDialog(this); 482 | return helper.createDialog(ctx); 483 | } 484 | 485 | public Builder createBuilder(Context ctx) { 486 | this.ctx = ctx; 487 | return this; 488 | } 489 | } 490 | 491 | public void setBuilder(Builder builder) { 492 | this.builder = builder; 493 | createDialog(builder.ctx); 494 | } 495 | 496 | public interface OnProgressFinishedListener { 497 | void onProgressFinished(); 498 | } 499 | 500 | public void setProgress(float percent) { 501 | //防止频繁重绘,大于10的百分比变动才进行绘制,或者动画正在执行中也不进行绘制 502 | if (mProgressAnimator != null && mProgressAnimator.isRunning()) return; 503 | if (percent - preProgress < 10) return; 504 | 505 | if (builder.centerView != null && builder.centerView instanceof DeterminateProgressView 506 | && mDialog.isShowing() && preProgress < 100) { 507 | curProgress = percent > 100 ? 100 : percent; 508 | mProgressAnimator = ObjectAnimator.ofFloat(((DeterminateProgressView) builder.centerView), 509 | "progress", preProgress, curProgress); 510 | mProgressAnimator.addListener(new Animator.AnimatorListener() { 511 | @Override 512 | public void onAnimationStart(Animator animation) { 513 | 514 | } 515 | 516 | @Override 517 | public void onAnimationEnd(Animator animation) { 518 | preProgress = curProgress; 519 | if (curProgress == 100) { 520 | mDialog.dismiss(); 521 | builder.onProgressFinishedListener.onProgressFinished(); 522 | } 523 | } 524 | 525 | @Override 526 | public void onAnimationCancel(Animator animation) { 527 | 528 | } 529 | 530 | @Override 531 | public void onAnimationRepeat(Animator animation) { 532 | 533 | } 534 | }); 535 | mProgressAnimator.start(); 536 | } 537 | } 538 | } 539 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/adapter/SingleSelectAdapter.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.TextView; 10 | 11 | import com.vincent.blurdialog.R; 12 | import com.vincent.blurdialog.helper.BlurDialogHelper; 13 | import com.vincent.blurdialog.listener.OnItemClick; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by vincent on 2017/11/22. 20 | */ 21 | 22 | public class SingleSelectAdapter extends RecyclerView.Adapter { 23 | private List mList; 24 | private float mRadius; 25 | private OnItemClick itemClick; 26 | 27 | public SingleSelectAdapter(List list, float radius, OnItemClick itemClick) { 28 | if (list == null) { 29 | this.mList = new ArrayList<>(); 30 | } else { 31 | this.mList = list; 32 | } 33 | this.mRadius = radius; 34 | this.itemClick = itemClick; 35 | } 36 | 37 | @Override 38 | public SingleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 39 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.vw_dialog_single_item, parent, false); 40 | return new SingleViewHolder(view); 41 | } 42 | 43 | @Override 44 | public void onBindViewHolder(final SingleViewHolder holder, int position) { 45 | Context ctx = holder.itemView.getContext(); 46 | float[] radius; 47 | if (position == 0) { 48 | radius = new float[]{ 49 | mRadius, mRadius, //左上角 50 | mRadius, mRadius, //右上角 51 | 0, 0, //右下角 52 | 0, 0 //左下角 53 | }; 54 | holder.vw_dialog_item_divider.setVisibility(View.VISIBLE); 55 | } else if (position == mList.size() - 1) { 56 | radius = new float[]{ 57 | 0, 0, //左上角 58 | 0, 0, //右上角 59 | mRadius, mRadius, //右下角 60 | mRadius, mRadius //左下角 61 | }; 62 | holder.vw_dialog_item_divider.setVisibility(View.INVISIBLE); 63 | } else { 64 | radius = new float[]{ 65 | 0, 0, //左上角 66 | 0, 0, //右上角 67 | 0, 0, //右下角 68 | 0, 0 //左下角 69 | }; 70 | holder.vw_dialog_item_divider.setVisibility(View.VISIBLE); 71 | } 72 | 73 | BlurDialogHelper.setBackGroundDrawable(holder.itemView.getContext(), holder.itemView, radius); 74 | holder.vw_dialog_tv_item.setText(mList.get(position)); 75 | 76 | holder.itemView.setOnClickListener(new View.OnClickListener() { 77 | @Override 78 | public void onClick(View view) { 79 | if (itemClick != null) { 80 | itemClick.onClick(mList.get(holder.getAdapterPosition())); 81 | } 82 | } 83 | }); 84 | } 85 | 86 | @Override 87 | public int getItemCount() { 88 | return mList.size(); 89 | } 90 | 91 | static class SingleViewHolder extends RecyclerView.ViewHolder { 92 | @NonNull 93 | TextView vw_dialog_tv_item; 94 | @NonNull 95 | View vw_dialog_item_divider; 96 | 97 | public SingleViewHolder(View itemView) { 98 | super(itemView); 99 | vw_dialog_tv_item = itemView.findViewById(R.id.vw_dialog_tv_item); 100 | vw_dialog_item_divider = itemView.findViewById(R.id.vw_dialog_item_divider); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/blur/RealtimeBlurView.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.blur; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.ContextWrapper; 6 | import android.content.pm.ApplicationInfo; 7 | import android.content.res.TypedArray; 8 | import android.graphics.Bitmap; 9 | import android.graphics.Canvas; 10 | import android.graphics.Rect; 11 | import android.support.v8.renderscript.Allocation; 12 | import android.support.v8.renderscript.Element; 13 | import android.support.v8.renderscript.RenderScript; 14 | import android.support.v8.renderscript.ScriptIntrinsicBlur; 15 | import android.util.AttributeSet; 16 | import android.util.TypedValue; 17 | import android.view.View; 18 | import android.view.ViewTreeObserver; 19 | 20 | import com.vincent.blurdialog.R; 21 | 22 | /** 23 | * A realtime blurring overlay (like iOS UIVisualEffectView). Just put it above 24 | * the view you want to blur and it doesn't have to be in the same ViewGroup 25 | *
    26 | *
  • realtimeBlurRadius (10dp)
  • 27 | *
  • realtimeDownsampleFactor (4)
  • 28 | *
  • realtimeOverlayColor (#aaffffff)
  • 29 | *
30 | */ 31 | 32 | public class RealtimeBlurView extends View { 33 | private float mDownsampleFactor; // default 4 34 | private int mOverlayColor; // default #aaffffff 35 | private float mBlurRadius; // default 10dp (0 < r <= 25) 36 | 37 | private boolean mDirty; 38 | private Bitmap mBitmapToBlur, mBlurredBitmap; 39 | private Canvas mBlurringCanvas; 40 | private RenderScript mRenderScript; 41 | private ScriptIntrinsicBlur mBlurScript; 42 | private Allocation mBlurInput, mBlurOutput; 43 | private boolean mIsRendering; 44 | private final Rect mRectSrc = new Rect(), mRectDst = new Rect(); 45 | // mDecorView should be the root view of the activity (even if you are on a different window like a dialog) 46 | private View mDecorView; 47 | // If the view is on different root view (usually means we are on a PopupWindow), 48 | // we need to manually call invalidate() in onPreDraw(), otherwise we will not be able to see the changes 49 | private boolean mDifferentRoot; 50 | private static int RENDERING_COUNT; 51 | 52 | public RealtimeBlurView(Context context, AttributeSet attrs) { 53 | super(context, attrs); 54 | 55 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RealtimeBlurView); 56 | mBlurRadius = a.getDimension(R.styleable.RealtimeBlurView_realtimeBlurRadius, 57 | TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, context.getResources().getDisplayMetrics())); 58 | mDownsampleFactor = a.getFloat(R.styleable.RealtimeBlurView_realtimeDownsampleFactor, 4); 59 | mOverlayColor = a.getColor(R.styleable.RealtimeBlurView_realtimeOverlayColor, 0xAAFFFFFF); 60 | a.recycle(); 61 | } 62 | 63 | public void setBlurRadius(float radius) { 64 | if (mBlurRadius != radius) { 65 | mBlurRadius = radius; 66 | mDirty = true; 67 | invalidate(); 68 | } 69 | } 70 | 71 | public void setDownsampleFactor(float factor) { 72 | if (factor <= 0) { 73 | throw new IllegalArgumentException("Downsample factor must be greater than 0."); 74 | } 75 | 76 | if (mDownsampleFactor != factor) { 77 | mDownsampleFactor = factor; 78 | mDirty = true; // may also change blur radius 79 | releaseBitmap(); 80 | invalidate(); 81 | } 82 | } 83 | 84 | public void setOverlayColor(int color) { 85 | if (mOverlayColor != color) { 86 | mOverlayColor = color; 87 | invalidate(); 88 | } 89 | } 90 | 91 | private void releaseBitmap() { 92 | if (mBlurInput != null) { 93 | mBlurInput.destroy(); 94 | mBlurInput = null; 95 | } 96 | if (mBlurOutput != null) { 97 | mBlurOutput.destroy(); 98 | mBlurOutput = null; 99 | } 100 | if (mBitmapToBlur != null) { 101 | mBitmapToBlur.recycle(); 102 | mBitmapToBlur = null; 103 | } 104 | if (mBlurredBitmap != null) { 105 | mBlurredBitmap.recycle(); 106 | mBlurredBitmap = null; 107 | } 108 | } 109 | 110 | private void releaseScript() { 111 | if (mRenderScript != null) { 112 | mRenderScript.destroy(); 113 | mRenderScript = null; 114 | } 115 | if (mBlurScript != null) { 116 | mBlurScript.destroy(); 117 | mBlurScript = null; 118 | } 119 | } 120 | 121 | protected void release() { 122 | releaseBitmap(); 123 | releaseScript(); 124 | } 125 | 126 | protected boolean prepare() { 127 | if (mBlurRadius == 0) { 128 | release(); 129 | return false; 130 | } 131 | 132 | float downsampleFactor = mDownsampleFactor; 133 | 134 | if (mDirty || mRenderScript == null) { 135 | if (mRenderScript == null) { 136 | try { 137 | mRenderScript = RenderScript.create(getContext()); 138 | mBlurScript = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript)); 139 | } catch (android.support.v8.renderscript.RSRuntimeException e) { 140 | if (isDebug(getContext())) { 141 | if (e.getMessage() != null && e.getMessage().startsWith("Error loading RS jni library: java.lang.UnsatisfiedLinkError:")) { 142 | throw new RuntimeException("Error loading RS jni library, Upgrade buildToolsVersion=\"24.0.2\" or higher may solve this issue"); 143 | } else { 144 | throw e; 145 | } 146 | } else { 147 | // In release mode, just ignore 148 | releaseScript(); 149 | return false; 150 | } 151 | } 152 | } 153 | 154 | mDirty = false; 155 | float radius = mBlurRadius / downsampleFactor; 156 | if (radius > 25) { 157 | downsampleFactor = downsampleFactor * radius / 25; 158 | radius = 25; 159 | } 160 | mBlurScript.setRadius(radius); 161 | } 162 | 163 | final int width = getWidth(); 164 | final int height = getHeight(); 165 | 166 | int scaledWidth = Math.max(1, (int) (width / downsampleFactor)); 167 | int scaledHeight = Math.max(1, (int) (height / downsampleFactor)); 168 | 169 | if (mBlurringCanvas == null || mBlurredBitmap == null 170 | || mBlurredBitmap.getWidth() != scaledWidth 171 | || mBlurredBitmap.getHeight() != scaledHeight) { 172 | releaseBitmap(); 173 | 174 | boolean r = false; 175 | try { 176 | mBitmapToBlur = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888); 177 | if (mBitmapToBlur == null) { 178 | return false; 179 | } 180 | mBlurringCanvas = new Canvas(mBitmapToBlur); 181 | 182 | mBlurInput = Allocation.createFromBitmap(mRenderScript, mBitmapToBlur, 183 | Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); 184 | mBlurOutput = Allocation.createTyped(mRenderScript, mBlurInput.getType()); 185 | 186 | mBlurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888); 187 | if (mBlurredBitmap == null) { 188 | return false; 189 | } 190 | 191 | r = true; 192 | } catch (OutOfMemoryError e) { 193 | // Bitmap.createBitmap() may cause OOM error 194 | // Simply ignore and fallback 195 | } finally { 196 | if (!r) { 197 | releaseBitmap(); 198 | return false; 199 | } 200 | } 201 | } 202 | return true; 203 | } 204 | 205 | protected void blur(Bitmap bitmapToBlur, Bitmap blurredBitmap) { 206 | mBlurInput.copyFrom(bitmapToBlur); 207 | mBlurScript.setInput(mBlurInput); 208 | mBlurScript.forEach(mBlurOutput); 209 | mBlurOutput.copyTo(blurredBitmap); 210 | } 211 | 212 | private final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() { 213 | @Override 214 | public boolean onPreDraw() { 215 | final int[] locations = new int[2]; 216 | Bitmap oldBmp = mBlurredBitmap; 217 | View decor = mDecorView; 218 | if (decor != null && isShown() && prepare()) { 219 | boolean redrawBitmap = mBlurredBitmap != oldBmp; 220 | oldBmp = null; 221 | decor.getLocationOnScreen(locations); 222 | int x = -locations[0]; 223 | int y = -locations[1]; 224 | 225 | getLocationOnScreen(locations); 226 | x += locations[0]; 227 | y += locations[1]; 228 | 229 | // just erase transparent 230 | mBitmapToBlur.eraseColor(mOverlayColor & 0xffffff); 231 | 232 | int rc = mBlurringCanvas.save(); 233 | mIsRendering = true; 234 | RENDERING_COUNT++; 235 | try { 236 | mBlurringCanvas.scale(1.f * mBitmapToBlur.getWidth() / getWidth(), 1.f * mBitmapToBlur.getHeight() / getHeight()); 237 | mBlurringCanvas.translate(-x, -y); 238 | if (decor.getBackground() != null) { 239 | decor.getBackground().draw(mBlurringCanvas); 240 | } 241 | decor.draw(mBlurringCanvas); 242 | } catch (StopException e) { 243 | } finally { 244 | mIsRendering = false; 245 | RENDERING_COUNT--; 246 | mBlurringCanvas.restoreToCount(rc); 247 | } 248 | 249 | blur(mBitmapToBlur, mBlurredBitmap); 250 | 251 | if (redrawBitmap || mDifferentRoot) { 252 | invalidate(); 253 | } 254 | } 255 | 256 | return true; 257 | } 258 | }; 259 | 260 | protected View getActivityDecorView() { 261 | Context ctx = getContext(); 262 | for (int i = 0; i < 4 && ctx != null && !(ctx instanceof Activity) && ctx instanceof ContextWrapper; i++) { 263 | ctx = ((ContextWrapper) ctx).getBaseContext(); 264 | } 265 | if (ctx instanceof Activity) { 266 | return ((Activity) ctx).getWindow().getDecorView(); 267 | } else { 268 | return null; 269 | } 270 | } 271 | 272 | @Override 273 | protected void onAttachedToWindow() { 274 | super.onAttachedToWindow(); 275 | mDecorView = getActivityDecorView(); 276 | if (mDecorView != null) { 277 | mDecorView.getViewTreeObserver().addOnPreDrawListener(preDrawListener); 278 | mDifferentRoot = mDecorView.getRootView() != getRootView(); 279 | if (mDifferentRoot) { 280 | mDecorView.postInvalidate(); 281 | } 282 | } else { 283 | mDifferentRoot = false; 284 | } 285 | } 286 | 287 | @Override 288 | protected void onDetachedFromWindow() { 289 | if (mDecorView != null) { 290 | mDecorView.getViewTreeObserver().removeOnPreDrawListener(preDrawListener); 291 | } 292 | release(); 293 | super.onDetachedFromWindow(); 294 | } 295 | 296 | @Override 297 | public void draw(Canvas canvas) { 298 | if (mIsRendering) { 299 | // Quit here, don't draw views above me 300 | throw STOP_EXCEPTION; 301 | } else if (RENDERING_COUNT > 0) { 302 | // Doesn't support blurview overlap on another blurview 303 | } else { 304 | super.draw(canvas); 305 | } 306 | } 307 | 308 | @Override 309 | protected void onDraw(Canvas canvas) { 310 | super.onDraw(canvas); 311 | drawBlurredBitmap(canvas, mBlurredBitmap, mOverlayColor); 312 | } 313 | 314 | /** 315 | * Custom draw the blurred bitmap and color to define your own shape 316 | * 317 | * @param canvas 318 | * @param blurredBitmap 319 | * @param overlayColor 320 | */ 321 | protected void drawBlurredBitmap(Canvas canvas, Bitmap blurredBitmap, int overlayColor) { 322 | if (blurredBitmap != null) { 323 | mRectSrc.right = blurredBitmap.getWidth(); 324 | mRectSrc.bottom = blurredBitmap.getHeight(); 325 | mRectDst.right = getWidth(); 326 | mRectDst.bottom = getHeight(); 327 | canvas.drawBitmap(blurredBitmap, mRectSrc, mRectDst, null); 328 | } 329 | canvas.drawColor(overlayColor); 330 | } 331 | 332 | private static class StopException extends RuntimeException { 333 | } 334 | 335 | private static StopException STOP_EXCEPTION = new StopException(); 336 | 337 | static { 338 | try { 339 | RealtimeBlurView.class.getClassLoader().loadClass("android.support.v8.renderscript.RenderScript"); 340 | } catch (ClassNotFoundException e) { 341 | throw new RuntimeException("RenderScript support not enabled. Add \"android { defaultConfig { renderscriptSupportModeEnabled true }}\" in your build.gradle"); 342 | } 343 | } 344 | 345 | // android:debuggable="true" in AndroidManifest.xml (auto set by build tool) 346 | static Boolean DEBUG = null; 347 | 348 | static boolean isDebug(Context ctx) { 349 | if (DEBUG == null && ctx != null) { 350 | DEBUG = (ctx.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 351 | } 352 | return DEBUG == Boolean.TRUE; 353 | } 354 | } 355 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/blur/RoundRectBlurView.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.blur; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapShader; 7 | import android.graphics.Canvas; 8 | import android.graphics.Color; 9 | import android.graphics.Matrix; 10 | import android.graphics.Paint; 11 | import android.graphics.PorterDuff; 12 | import android.graphics.PorterDuffXfermode; 13 | import android.graphics.RectF; 14 | import android.graphics.Shader; 15 | import android.util.AttributeSet; 16 | import android.util.TypedValue; 17 | 18 | import com.vincent.blurdialog.R; 19 | 20 | /** 21 | * Created by vincent on 2017/11/22. 22 | */ 23 | 24 | public class RoundRectBlurView extends RealtimeBlurView { 25 | private Paint mPaint; 26 | private RectF mRectF; 27 | private float mXRadius; 28 | private float mYRadius; 29 | 30 | private Bitmap mRoundBitmap; 31 | private Canvas mTmpCanvas; 32 | 33 | public RoundRectBlurView(Context context, AttributeSet attrs) { 34 | super(context, attrs); 35 | 36 | mPaint = new Paint(); 37 | mPaint.setAntiAlias(true); 38 | mRectF = new RectF(); 39 | 40 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundRectBlurView); 41 | mXRadius = a.getDimension(R.styleable.RoundRectBlurView_xRadius, 42 | TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, context.getResources().getDisplayMetrics())); 43 | mYRadius = a.getDimension(R.styleable.RoundRectBlurView_yRadius, 44 | TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, context.getResources().getDisplayMetrics())); 45 | a.recycle(); 46 | } 47 | 48 | @Override 49 | protected void drawBlurredBitmap(Canvas canvas, Bitmap blurredBitmap, int overlayColor) { 50 | super.drawBlurredBitmap(canvas, blurredBitmap, overlayColor); 51 | // 制造一个和View一样大小的带圆角的bitmap,圆角之外的部分为透明色 52 | // 此bitmap用来将从父类传进来的canvas裁切为圆角 53 | mRectF.right = getWidth(); 54 | mRectF.bottom = getHeight(); 55 | if (mRoundBitmap == null) { 56 | mRoundBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 57 | } 58 | if (mTmpCanvas == null) { 59 | mTmpCanvas = new Canvas(mRoundBitmap); 60 | } 61 | mTmpCanvas.drawRoundRect(mRectF, mXRadius, mYRadius, mPaint); 62 | 63 | // 对父类传来的canvas进行圆角裁切 64 | mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); 65 | canvas.drawBitmap(mRoundBitmap, 0 , 0, mPaint); 66 | 67 | // if (blurredBitmap != null) { 68 | // mRectF.right = getWidth(); 69 | // mRectF.bottom = getHeight(); 70 | // 71 | // mPaint.reset(); 72 | // mPaint.setAntiAlias(true); 73 | // BitmapShader shader = new BitmapShader(blurredBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 74 | // Matrix matrix = new Matrix(); 75 | // matrix.postScale(mRectF.width() / blurredBitmap.getWidth(), mRectF.height() / blurredBitmap.getHeight()); 76 | // shader.setLocalMatrix(matrix); 77 | // mPaint.setShader(shader); 78 | // canvas.drawRoundRect(mRectF, mXRadius, mYRadius, mPaint); 79 | // 80 | // mPaint.reset(); 81 | // mPaint.setAntiAlias(true); 82 | // mPaint.setColor(overlayColor); 83 | // canvas.drawRoundRect(mRectF, mXRadius, mYRadius, mPaint); 84 | // } 85 | } 86 | 87 | public void setRadius(float radius) { 88 | this.mXRadius = radius; 89 | this.mYRadius = radius; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/helper/BlurDialogHelper.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.helper; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.graphics.drawable.GradientDrawable; 7 | import android.graphics.drawable.StateListDrawable; 8 | import android.os.Build; 9 | import android.util.TypedValue; 10 | import android.view.View; 11 | 12 | import com.vincent.blurdialog.R; 13 | 14 | /** 15 | * Created by vincent on 2017/11/22. 16 | */ 17 | 18 | public class BlurDialogHelper { 19 | public static void setBackGroundDrawable(Context ctx, View v, float[] radius) { 20 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 21 | v.setBackground(BlurDialogHelper.getClickBgDrawable(ctx, radius)); 22 | } else { 23 | v.setBackgroundDrawable(BlurDialogHelper.getClickBgDrawable(ctx, radius)); 24 | } 25 | } 26 | 27 | public static StateListDrawable getClickBgDrawable(Context ctx, float[] radius) { 28 | //获取颜色 29 | GradientDrawable selected = new GradientDrawable(); 30 | selected.setColor(ctx.getResources().getColor(R.color.vw_dialog_bg_shadow)); 31 | selected.setCornerRadii(radius); 32 | ColorDrawable unSelected = new ColorDrawable(Color.TRANSPARENT); 33 | 34 | StateListDrawable drawable = new StateListDrawable(); 35 | drawable.addState(new int[]{android.R.attr.state_pressed}, 36 | selected); 37 | drawable.addState(new int[]{-android.R.attr.state_pressed}, 38 | unSelected); 39 | 40 | return drawable; 41 | } 42 | 43 | public static float getRadius(Context ctx, float builderRadius) { 44 | if (builderRadius >= 0) { 45 | return TypedValue.applyDimension( 46 | TypedValue.COMPLEX_UNIT_DIP, 47 | builderRadius, 48 | ctx.getResources().getDisplayMetrics()); 49 | } else { 50 | return ctx.getResources().getDimension(R.dimen.vw_dialog_default_radius); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/listener/OnItemClick.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.listener; 2 | 3 | /** 4 | * Created by vincent on 2017/11/22. 5 | */ 6 | 7 | public interface OnItemClick { 8 | void onClick(CharSequence item); 9 | } 10 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/listener/OnNegativeClick.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.listener; 2 | 3 | /** 4 | * Created by vincent on 2017/11/22. 5 | */ 6 | 7 | public interface OnNegativeClick { 8 | void onClick(); 9 | } 10 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/listener/OnPositiveClick.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.listener; 2 | 3 | /** 4 | * Created by vincent on 2017/11/22. 5 | */ 6 | 7 | public interface OnPositiveClick { 8 | void onClick(); 9 | } 10 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/view/DeterminateProgressView.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.view; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.graphics.Canvas; 6 | import android.graphics.Color; 7 | import android.graphics.Paint; 8 | import android.graphics.PorterDuff; 9 | import android.graphics.PorterDuffXfermode; 10 | import android.graphics.RectF; 11 | import android.os.Build; 12 | import android.support.annotation.Nullable; 13 | import android.util.AttributeSet; 14 | import android.view.View; 15 | 16 | import com.vincent.blurdialog.BlurDialog; 17 | 18 | /** 19 | * Created by Vincent Woo 20 | * Date: 2018/4/23 21 | * Time: 17:41 22 | */ 23 | 24 | public class DeterminateProgressView extends View { 25 | private static final float STEP = 360f / 100f; 26 | 27 | private int mViewHeight, mViewWidth; 28 | private int mCenterX, mCenterY; 29 | private float mStrokeWidth = 2; 30 | private Paint mBasicPaint; 31 | private Paint mBasicCirclePaint; 32 | private RectF rectF; 33 | private PorterDuffXfermode xfermode; 34 | 35 | private float progress = 0; 36 | 37 | public DeterminateProgressView(Context context) { 38 | super(context); 39 | } 40 | 41 | public DeterminateProgressView(Context context, @Nullable AttributeSet attrs) { 42 | super(context, attrs); 43 | } 44 | 45 | public DeterminateProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 46 | super(context, attrs, defStyleAttr); 47 | } 48 | 49 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 50 | public DeterminateProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { 51 | super(context, attrs, defStyleAttr, defStyleRes); 52 | } 53 | 54 | @Override 55 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 56 | super.onSizeChanged(w, h, oldw, oldh); 57 | mViewWidth = w; 58 | mViewHeight = h; 59 | mCenterX = mViewWidth / 2; 60 | mCenterY = mViewHeight / 2; 61 | 62 | init(); 63 | } 64 | 65 | private void init() { 66 | mBasicPaint = new Paint(); 67 | mBasicPaint.setAntiAlias(true); 68 | mBasicPaint.setDither(true);//防抖动 69 | mBasicPaint.setFilterBitmap(true);//如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示速度,本设置项依赖于dither和xfermode的设置 70 | mBasicPaint.setColor(Color.parseColor("#FF47494D")); 71 | 72 | mBasicCirclePaint = new Paint(); 73 | mBasicCirclePaint.setAntiAlias(true); 74 | mBasicCirclePaint.setDither(true); 75 | mBasicCirclePaint.setFilterBitmap(true); 76 | mBasicCirclePaint.setColor(Color.parseColor("#FF47494D")); 77 | mBasicCirclePaint.setStyle(Paint.Style.STROKE); 78 | mBasicCirclePaint.setStrokeWidth(mStrokeWidth); 79 | 80 | // 加减1是为了不出现残影,适当将矩形扩大一点 81 | rectF = new RectF(mStrokeWidth * 3 - 1, mStrokeWidth * 3 - 1, 82 | mViewWidth - mStrokeWidth * 3 + 1, mViewHeight - mStrokeWidth * 3 + 1); 83 | xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT); 84 | } 85 | 86 | @Override 87 | protected void onDraw(Canvas canvas) { 88 | super.onDraw(canvas); 89 | 90 | int saved = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG); 91 | 92 | //画外层的黑圈 93 | canvas.drawCircle(mCenterX, mCenterY, mCenterX - mStrokeWidth, mBasicCirclePaint); 94 | //画内层的黑圆 95 | canvas.drawCircle(mCenterX, mCenterY, mCenterX - mStrokeWidth * 3, mBasicPaint); 96 | //画扇形 97 | mBasicPaint.setXfermode(xfermode); 98 | canvas.drawArc(rectF, -90, progress * STEP, true, mBasicPaint); 99 | mBasicPaint.setXfermode(null); 100 | 101 | canvas.restoreToCount(saved); 102 | } 103 | 104 | public float getProgress() { 105 | return progress; 106 | } 107 | 108 | public void setProgress(float progress) { 109 | this.progress = progress; 110 | invalidate(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /blurdialog/src/main/java/com/vincent/blurdialog/view/IndeterminateProgressView.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog.view; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.graphics.Canvas; 6 | import android.graphics.Color; 7 | import android.graphics.Paint; 8 | import android.graphics.SweepGradient; 9 | import android.os.Build; 10 | import android.support.annotation.NonNull; 11 | import android.support.annotation.Nullable; 12 | import android.util.AttributeSet; 13 | import android.view.View; 14 | import android.view.ViewTreeObserver; 15 | import android.view.animation.Animation; 16 | import android.view.animation.LinearInterpolator; 17 | import android.view.animation.RotateAnimation; 18 | 19 | /** 20 | * Created by Vincent Woo 21 | * Date: 2018/4/23 22 | * Time: 10:18 23 | */ 24 | 25 | public class IndeterminateProgressView extends View { 26 | private int mViewHeight, mViewWidth; 27 | private int mCenterX, mCenterY; 28 | private float mStrokeWidth = 2; 29 | private Paint mProgressPaint; 30 | private RotateAnimation mRotate; 31 | 32 | public IndeterminateProgressView(Context context) { 33 | this(context, null); 34 | } 35 | 36 | public IndeterminateProgressView(Context context, @Nullable AttributeSet attrs) { 37 | this(context, attrs, 0); 38 | } 39 | 40 | public IndeterminateProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 41 | super(context, attrs, defStyleAttr); 42 | // parseAttrs(context, attrs); 43 | } 44 | 45 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 46 | public IndeterminateProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { 47 | super(context, attrs, defStyleAttr, defStyleRes); 48 | // parseAttrs(context, attrs); 49 | } 50 | 51 | private void init() { 52 | mProgressPaint = new Paint(); 53 | mProgressPaint.setShader(new SweepGradient(mCenterX, mCenterY, 54 | Color.parseColor("#00000000"), Color.parseColor("#FF47494D"))); 55 | mProgressPaint.setAntiAlias(true); 56 | mProgressPaint.setDither(true);//防抖动 57 | mProgressPaint.setFilterBitmap(true);//如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示速度,本设置项依赖于dither和xfermode的设置 58 | mProgressPaint.setStrokeWidth(mStrokeWidth); 59 | mProgressPaint.setStyle(Paint.Style.STROKE); 60 | mProgressPaint.setStrokeCap(Paint.Cap.ROUND); 61 | 62 | mRotate = new RotateAnimation(0f, 360f, 63 | Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 64 | mRotate.setInterpolator(new LinearInterpolator()); 65 | mRotate.setDuration(1500);//设置动画持续时间 66 | mRotate.setRepeatCount(-1);//设置重复次数 67 | // rotate.setFillAfter(true);//动画执行完后是否停留在执行完的状态 68 | 69 | getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 70 | @Override 71 | public void onGlobalLayout() { 72 | startAnimation(); 73 | } 74 | }); 75 | } 76 | 77 | @Override 78 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 79 | super.onSizeChanged(w, h, oldw, oldh); 80 | mViewWidth = w; 81 | mViewHeight = h; 82 | mCenterX = mViewWidth / 2; 83 | mCenterY = mViewHeight / 2; 84 | 85 | init(); 86 | } 87 | 88 | @Override 89 | protected void onDraw(Canvas canvas) { 90 | canvas.drawCircle(mCenterX, mCenterY, mCenterX - mStrokeWidth, mProgressPaint); 91 | } 92 | 93 | public float getStrokeWidth() { 94 | return mStrokeWidth; 95 | } 96 | 97 | public void setStrokeWidth(float px) { 98 | this.mStrokeWidth = px; 99 | } 100 | 101 | public void startAnimation() { 102 | if (mRotate != null) { 103 | IndeterminateProgressView.this.startAnimation(mRotate); 104 | } 105 | } 106 | 107 | @Override 108 | protected void onVisibilityChanged(@NonNull View changedView, int visibility) { 109 | if (View.VISIBLE == visibility) { 110 | startAnimation(); 111 | } 112 | } 113 | 114 | @Override 115 | protected void onDetachedFromWindow() { 116 | mRotate.reset(); 117 | super.onDetachedFromWindow(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/anim/vw_dialog_scale_in.xml: -------------------------------------------------------------------------------- 1 | 3 | 12 | 17 | 18 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/anim/vw_dialog_slide_in_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/anim/vw_dialog_slide_out_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/drawable/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/blurdialog/src/main/res/drawable/.gitignore -------------------------------------------------------------------------------- /blurdialog/src/main/res/layout/vw_dialog_option_double.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 21 | 22 | 27 | 28 | 38 | 39 | 45 | 46 | 51 | 52 | 57 | 58 | 68 | 69 | 73 | 74 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/layout/vw_dialog_option_none.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 21 | 22 | 27 | 28 | 41 | 42 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/layout/vw_dialog_option_single.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 20 | 21 | 25 | 26 | 34 | 35 | 41 | 42 | 47 | 48 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/layout/vw_dialog_select_single.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 24 | 25 | 29 | 30 | 31 | 32 | 36 | 37 | 50 | 51 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/layout/vw_dialog_single_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 19 | 20 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/values-zh/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 删除 3 | 4 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #007AFF 4 | #A0FFFFFF 5 | #EC4E4F 6 | #525564 7 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6dp 4 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Delete 3 | 4 | -------------------------------------------------------------------------------- /blurdialog/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /blurdialog/src/test/java/com/vincent/blurdialog/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.vincent.blurdialog; 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() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.0.1' 11 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0' 12 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 13 | 14 | // NOTE: Do not place your application dependencies here; they belong 15 | // in the individual module build.gradle files 16 | } 17 | } 18 | 19 | allprojects { 20 | repositories { 21 | google() 22 | jcenter() 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishwjy/BlurDialog/3ce0262f38a14e2284f53f067ecf592f9579bbe3/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 18 17:29:47 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':blurdialog' 2 | --------------------------------------------------------------------------------