16 |
17 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # ProgressDialog Library Contributing Guide
2 |
3 | **How you can contribute to this Project ?**
4 |
5 | - You can point out any issue which you faced while using this library.
6 | - You can suggest new features to be added to this library.
7 | - You can give pull requests with any reasonable changes or feature additions.
8 | - I haven't done JUnit testing for this library. You can help out with the same.
9 | - You can share about this library to your peer Android developers.
10 |
11 | **Guidelines to be followed while Contributing to this Project**
12 |
13 | - Make sure to follow the coding style which is used right now.
14 | - Don't forget to add Documentation comments to newly added **PUBLIC** methods/properties.
15 | - Make sure that the newly added code/modified code does not add bugs to the existing code.
16 | - Make sure that the code is optimized for performance and the best coding practices are used.
17 | - Ensure to make considerable changes/additions to the code before giving Pull Requests.
18 |
--------------------------------------------------------------------------------
/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 | # ProgressDialog Library [](https://jitpack.io/#techinessoverloaded/progress-dialog/) [](https://github.com/techinessoverloaded/progress-dialog/releases/latest) [](https://jitpack.io/#techinessoverloaded/progress-dialog) [](https://github.com/techinessoverloaded/progress-dialog/actions/workflows/checkLibraryBuildStatus.yml) [](https://github.com/techinessoverloaded/progress-dialog/actions/workflows/generateDocs.yml) [](https://github.com/dependabot)
2 |
3 |
4 | An easily customisable ProgressDialog Library for Android API 24 and above provided by Techiness Overloaded (Developer name: Arunprasadh C). Quite Useful for showing progress during any operation. Has support for both Determinate and Indeterminate ProgressBar. Also supports Dark Theme. Has javadoc Documentation for all public Constructors, Attributes and Methods, making it easy to learn about the Library from Android Studio IDE.
5 |
6 | > [!NOTE]
7 | > It is highly recommended to use the Latest Release Version of the Library and it is strongly recommended NOT to use any Pre-release versions of the library as they are used for testing out changes and are not production-ready. It is readily observable that Pre-release versions have "a" or "rc" in their version code (Example: Version 1.4.0a4 or 1.4.4-rc1). It is strictly recommended not to use version 1.4.2 or 1.5.0 as the build artifacts are not properly published. You can instead prefer the latest version (1.5.1).
8 |
9 | **Usage examples available at** [Usage Examples](#steps-to-add-progressdialog-library-to-your-android-studio-project)
10 | **Java Documentation of Class and Methods available at** [Java Documentation of Library](https://techinessoverloaded.github.io/progress-dialog/java/latest/com/techiness/progressdialoglibrary/ProgressDialog.html)
11 | **Kotlin Documentation of Class and Methods available at** [Kotlin Documentation of Library](https://techinessoverloaded.github.io/progress-dialog/kotlin/latest/progressdialoglibrary/com.techiness.progressdialoglibrary/-progress-dialog/index.html)
12 | You can find the Entire **Change Log at** [ProgressDialog Library Change Log](https://techinessoverloaded.github.io/progress-dialog/changelog.html)
13 | See the [Contributing Guide](https://github.com/techinessoverloaded/progress-dialog/blob/master/CONTRIBUTING.md) to learn more about Contributing to this Project.
14 |
15 | ## Key Features
16 | - Highly Customisable.
17 | - Has support for Dark Theme.
18 | - Has support for AutoTheming from Android 11 (API Level 30).
19 | - Can be set in both Determinate and Indeterminate Mode.
20 | - Has support for Time Tracking in Determinate Mode.
21 | - Has support for Negative Button, Title, and ProgressView.
22 | - Desgined for usage in both Java and Kotlin Android Projects.
23 | - Clear Documentation is available.
24 |
25 | ## What's New in Version 1.5.1 (Feature Update) ?
26 | ### Features
27 | - Added Time Tracking feature for Determinate Mode ProgressDialog as suggested by [@vzool](https://github.com/vzool) in Issue [#13](https://github.com/techinessoverloaded/progress-dialog/issues/13). Time tracking can be enabled by passing `true` to the first parameter of `setOnShowListener` method. The time elapsed will be updated until the `progress` reaches `maxValue`.
28 | ### Bug Fixes
29 | - Fixed an Issue where unwanted views got displayed on the ProgressDialog, as pointed out by [@soenkegissel](https://github.com/soenkegissel) and [@mg2000](https://github.com/mg2000) in Issue [#16](https://github.com/techinessoverloaded/progress-dialog/issues/16).
30 | ### Maintenance
31 | - Merged Pull Requests [#11](https://github.com/techinessoverloaded/progress-dialog/pull/11), [#12](https://github.com/techinessoverloaded/progress-dialog/pull/12), [#14](https://github.com/techinessoverloaded/progress-dialog/pull/14), [#15](https://github.com/techinessoverloaded/progress-dialog/pull/15), [#17](https://github.com/techinessoverloaded/progress-dialog/pull/17) given by [@dependabot](https://github.com/dependabot) to update Material Version, Gradle Version, Gradle Build Action Version, ConstraintLayout Version and AppCompat Version.
32 |
33 | You can find the Entire **Change Log at** [ProgressDialog Library Change Log](https://techinessoverloaded.github.io/progress-dialog/changelog.html)
34 |
35 | ## Steps to add ProgressDialog Library to your Android Studio Project
36 |
37 | **Make Sure that you are using JDK Version 11**
38 | Include the following code in your Project-level Gradle Build file at the end of repositories:
39 |
40 | **Gradle Groovy DSL (If you have build.gradle file):**
41 | ```groovy
42 | allprojects {
43 | repositories {
44 | maven { url 'https://jitpack.io' }
45 | }
46 | }
47 | ```
48 |
49 | **Gradle Kotlin DSL (If you have build.gradle.kts file):**
50 | ```kotlin
51 | allprojects {
52 | repositories {
53 | maven { url = uri("https://jitpack.io") }
54 | }
55 | }
56 | ```
57 |
58 | Now, include the following dependency in your App-level Gradle Build file:
59 | > [!NOTE]
60 | > Current latest version is **1.5.1**
61 |
62 | **Gradle Groovy DSL (If you have build.gradle file):**
63 | ```groovy
64 | dependencies {
65 | implementation 'com.github.techinessoverloaded:progress-dialog:1.5.1'
66 | }
67 | ```
68 |
69 | **Gradle Kotlin DSL (If you have build.gradle.kts file):**
70 | ```kotlin
71 | dependencies {
72 | implementation("com.github.techinessoverloaded:progress-dialog:1.5.1")
73 | }
74 | ```
75 |
76 | #### Or you can also define the version as a String like this(You can copy either this code or the above one):
77 | **Gradle Groovy DSL (If you have build.gradle file):**
78 | ```groovy
79 | dependencies {
80 | def latest-version = "1.5.1"
81 | implementation "com.github.techinessoverloaded:progress-dialog:$latest-version"
82 | }
83 | ```
84 |
85 | **Gradle Kotlin DSL (If you have build.gradle.kts file):**
86 | ```kotlin
87 | dependencies {
88 | val latest-version = "1.5.1"
89 | implementation("com.github.techinessoverloaded:progress-dialog:$latest-version")
90 | }
91 | ```
92 |
93 | Now import ProgressDialog class in your Activity/Fragment:
94 | ```java
95 | import com.techiness.progressdialoglibrary.ProgressDialog;
96 | ```
97 |
98 | ## Various Constructors available
99 |
100 | ### Simple Constructor
101 | #### Uses Light Theme by Default.
102 | > [!NOTE]
103 | > Theme can be changed after Instantiation using ```setTheme(int themeConstant)``` method.
104 |
105 | > [!IMPORTANT]
106 | > If you want to Instantiate ```ProgressDialog``` Class in a **Fragment**, use ```requireContext()``` method instead of ```this``` keyword for passing ```Context``` object. Similarly, for Instantiating ```ProgressDialog``` Class in **Inner Classes**, use ```YourActivity.this``` in **Java** or ```this@YourActivity``` in **Kotlin** instead of simple ```this``` keyword for passing ```Context``` object.
107 |
108 | #### Java Code:
109 | ```java
110 | ProgressDialog progressDialog = new ProgressDialog(this); //same as new ProgressDialog(this, ProgressDialog.THEME_LIGHT);
111 | ```
112 | #### Kotlin Code:
113 | ```kotlin
114 | val progressDialog = ProgressDialog(this) //same as ProgressDialog(this, ProgressDialog.THEME_LIGHT)
115 | ```
116 |
117 | ### Constructor for Alternate Theme
118 | #### This Constructor can be used for setting Dark Theme.
119 | #### Java Code:
120 | ```java
121 | ProgressDialog progressDialog = new ProgressDialog(this, ProgressDialog.THEME_DARK);
122 | ```
123 | #### Kotlin Code:
124 | ```kotlin
125 | val progressDialog = ProgressDialog(this, ProgressDialog.THEME_DARK)
126 | ```
127 |
128 | ### Constructor for Alternate Mode
129 | #### Default mode is Indeterminate mode.
130 | > [!NOTE]
131 | > Mode can be changed as and when necessary using in-built methods.
132 | #### Java Code:
133 | ```java
134 | ProgressDialog progressDialog = new ProgressDialog(ProgressDialog.MODE_DETERMINATE,this); // for instantiating with Determinate mode
135 | ```
136 | ### Kotlin Code:
137 | ```kotlin
138 | val progressDialog = ProgressDialog(ProgressDialog.MODE_DETERMINATE,this) // for instantiating with Determinate mode
139 | ```
140 |
141 | ### Constructor for Alternate Mode and Theme
142 | #### This constructor can be used to customise both Mode and Theme of ProgressDialog.
143 | #### Java Code:
144 | ```java
145 | ProgressDialog progressDialog = new ProgressDialog(ProgressDialog.MODE_DETERMINATE,this,ProgressDialog.THEME_DARK);
146 | ```
147 | #### Kotlin Code:
148 | ```kotlin
149 | val progressDialog = ProgressDialog(ProgressDialog.MODE_DETERMINATE,this,ProgressDialog.THEME_DARK)
150 | ```
151 | ## Simple Examples
152 |
153 | #### Note: These examples are for simple illustration of ProgressDialog Library. For completely knowing about the Library, refer to the JavaDoc/KDoc Documentation of the Library through Android Studio.
154 |
155 | ### How to use `ProgressDialog.THEME_FOLLOW_SYSTEM` with Constructor ?
156 | #### Java Code:
157 | ```java
158 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) //Check if Android API Level is greater than or equal to 30
159 | {
160 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_FOLLOW_SYSTEM); //This is optional. This will enable Android's Autotheming for the entire App
161 | ProgressDialog progressDialog = new ProgressDialog(this,ProgressDialog.THEME_FOLLOW_SYSTEM); // Enables AutoTheming for the ProgressDialog instance.
162 | }
163 | else //Autotheming not compatible
164 | {
165 | ProgressDialog progressDialog = new ProgressDialog(this,ProgressDialog.THEME_DARK); // or any other constructors mentioned above
166 | }
167 | ```
168 | #### Kotlin Code:
169 | ```kotlin
170 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) //Check if Android API Level is greater than or equal to 30
171 | {
172 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_FOLLOW_SYSTEM) //This is optional. This will enable Android's Autotheming for the entire App
173 | val progressDialog = ProgressDialog(this,ProgressDialog.THEME_FOLLOW_SYSTEM) // Enables AutoTheming for the ProgressDialog instance.
174 | }
175 | else //Autotheming not compatible
176 | {
177 | val progressDialog = ProgressDialog(this,ProgressDialog.THEME_DARK) // or any other constructors mentioned above
178 | }
179 | ```
180 |
181 | ### How to use `ProgressDialog.THEME_FOLLOW_SYSTEM` with `setTheme(int themeConstant)` method ?
182 | #### Java Code:
183 | ```java
184 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) //Check if Android API Level is greater than or equal to 30
185 | {
186 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_FOLLOW_SYSTEM); //This is optional. This will enable Android's Autotheming for the entire App
187 | progressDialog.setTheme(ProgressDialog.THEME_FOLLOW_SYSTEM); // Enables AutoTheming for the ProgressDialog instance.
188 | }
189 | else //Autotheming not compatible
190 | {
191 | progressDialog.setTheme(ProgressDialog.THEME_DARK); // or ProgressDialog.THEME_LIGHT
192 | }
193 | ```
194 | #### Kotlin Code:
195 | ```kotlin
196 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) //Check if Android API Level is greater than or equal to 30
197 | {
198 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_FOLLOW_SYSTEM) //This is optional. This will enable Android's Autotheming for the entire App
199 | progressDialog.theme = ProgressDialog.THEME_FOLLOW_SYSTEM) // Enables AutoTheming for the ProgressDialog instance.
200 | }
201 | else //Autotheming not compatible
202 | {
203 | progressDialog.theme = ProgressDialog.THEME_DARK // or ProgressDialog.THEME_LIGHT
204 | }
205 | ```
206 |
207 | ### Indeterminate ProgressDialog without Title (Light Theme)
208 | #### Java Code:
209 | ```java
210 | ProgressDialog progressDialog = new ProgressDialog(this);
211 | progressDialog.show();
212 | ```
213 | #### Kotlin Code:
214 | ```kotlin
215 | val progressDialog = ProgressDialog(this)
216 | progressDialog.show()
217 | ```
218 | #### Output:
219 |
220 |
221 | ### Indeterminate ProgressDialog without Title (Dark Theme)
222 | #### Java Code:
223 | ```java
224 | progressDialog.setTheme(ProgressDialog.THEME_DARK);
225 | progressDialog.show();
226 | ```
227 | #### Kotlin Code:
228 | ```kotlin
229 | with(progressDialog)
230 | {
231 | theme = ProgressDialog.THEME_DARK
232 | show()
233 | }
234 | ```
235 | #### Output:
236 |
237 |
238 | ### Determinate ProgressDialog without Title, without ProgressView, with Secondary Progress (Light Theme)
239 | #### Java Code:
240 | ```java
241 | progressDialog.setTheme(ProgressDialog.THEME_LIGHT);
242 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
243 | progressDialog.setProgress(65);
244 | progressDialog.setSecondaryProgress(80);
245 | progressDialog.hideProgressText();
246 | progressDialog.show();
247 | ```
248 | #### Kotlin Code:
249 | ```kotlin
250 | with(progressDialog)
251 | {
252 | theme = ProgressDialog.THEME_LIGHT
253 | mode = ProgressDialog.MODE_DETERMINATE
254 | progress = 65
255 | secondaryProgress = 80
256 | hideProgressText()
257 | show()
258 | }
259 | ```
260 | #### Output:
261 |
262 |
263 | ### Determinate ProgressDialog without Title, without ProgressView, with Secondary Progress (Dark Theme)
264 | #### Java Code:
265 | ```java
266 | progressDialog.setTheme(ProgressDialog.THEME_DARK);
267 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
268 | progressDialog.setProgress(65);
269 | progressDialog.setSecondaryProgress(80);
270 | progressDialog.hideProgressText();
271 | progressDialog.show();
272 | ```
273 | #### Kotlin Code:
274 | ```kotlin
275 | with(progressDialog)
276 | {
277 | theme = ProgressDialog.THEME_DARK
278 | mode = ProgressDialog.MODE_DETERMINATE
279 | progress = 65
280 | secondaryProgress = 80
281 | hideProgressText()
282 | show()
283 | }
284 | ```
285 | #### Output:
286 |
287 |
288 | ### Determinate ProgressDialog without Title, with ProgressView as Percentage (Light Theme)
289 | #### Java Code:
290 | ```java
291 | progressDialog.setTheme(ProgressDialog.THEME_LIGHT);
292 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
293 | progressDialog.setProgress(65);
294 | progressDialog.show();
295 | ```
296 | #### Kotlin Code:
297 | ```kotlin
298 | with(progressDialog)
299 | {
300 | theme = ProgressDialog.THEME_LIGHT
301 | mode = ProgressDialog.MODE_DETERMINATE
302 | setprogress = 65
303 | show()
304 | }
305 | ```
306 | #### Output:
307 |
308 |
309 | ### Determinate ProgressDialog without Title, with ProgressView as Percentage (Dark Theme)
310 | #### Java Code:
311 | ```java
312 | progressDialog.setTheme(ProgressDialog.THEME_DARK);
313 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
314 | progressDialog.setProgress(65);
315 | progressDialog.show();
316 | ```
317 | #### Kotlin Code:
318 | ```kotlin
319 | with(progressDialog)
320 | {
321 | theme = ProgressDialog.THEME_DARK
322 | mode = ProgressDialog.MODE_DETERMINATE
323 | progress = 65
324 | show()
325 | }
326 | ```
327 | #### Output:
328 |
329 |
330 | ### Indeterminate ProgressDialog with Title (Light Theme)
331 | #### Java Code:
332 | ```java
333 | progressDialog.setTheme(ProgressDialog.THEME_LIGHT);
334 | progressDialog.setMode(ProgressDialog.MODE_INDETERMINATE);
335 | progressDialog.setTitle("Indeterminate");
336 | progressDialog.show();
337 | ```
338 | #### Kotlin Code:
339 | ```kotlin
340 | with(progressDialog)
341 | {
342 | theme = ProgressDialog.THEME_LIGHT
343 | mode = ProgressDialog.MODE_INDETERMINATE
344 | setTitle("Indeterminate")
345 | show()
346 | }
347 | ```
348 | #### Output:
349 |
350 |
351 | ### Indeterminate ProgressDialog with Title (Dark Theme)
352 | #### Java Code:
353 | ```java
354 | progressDialog.setTheme(ProgressDialog.THEME_DARK);
355 | progressDialog.setMode(ProgressDialog.MODE_INDETERMINATE);
356 | progressDialog.setTitle("Indeterminate");
357 | progressDialog.show();
358 | ```
359 | #### Kotlin Code:
360 | ```kotlin
361 | with(progressDialog)
362 | {
363 | theme = ProgressDialog.THEME_DARK
364 | mode = ProgressDialog.MODE_INDETERMINATE
365 | setTitle("Indeterminate")
366 | show()
367 | }
368 | ```
369 | #### Output:
370 |
371 |
372 | ### Determinate ProgressDialog with Title, Secondary Progress and ProgressView as Fraction (Light Theme)
373 | #### Java Code:
374 | ```java
375 | progressDialog.setTheme(ProgressDialog.THEME_LIGHT);
376 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
377 | progressDialog.setTitle("Determinate");
378 | progressDialog.setProgress(65);
379 | progressDialog.setSecondaryProgress(80);
380 | progressDialog.showProgressTextAsFraction(true);
381 | progressDialog.show();
382 | ```
383 | #### Kotlin Code:
384 | ```kotlin
385 | with(progressDialog)
386 | {
387 | theme = ProgressDialog.THEME_LIGHT
388 | mode = ProgressDialog.MODE_DETERMINATE
389 | setTitle("Determinate")
390 | progress = 65
391 | secondaryProgress = 80
392 | showProgressTextAsFraction(true)
393 | show()
394 | }
395 | ```
396 | #### Output:
397 |
398 |
399 | ### Determinate ProgressDialog with Title, Secondary Progress and ProgressView as Fraction (Dark Theme)
400 | #### Java Code:
401 | ```java
402 | progressDialog.setTheme(ProgressDialog.THEME_DARK);
403 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
404 | progressDialog.setTitle("Determinate");
405 | progressDialog.setProgress(65);
406 | progressDialog.setSecondaryProgress(80);
407 | progressDialog.showProgressTextAsFraction(true);
408 | progressDialog.show();
409 | ```
410 | #### Kotlin Code:
411 | ```kotlin
412 | with(progressDialog)
413 | {
414 | theme = ProgressDialog.THEME_DARK
415 | mode = ProgressDialog.MODE_DETERMINATE
416 | setTitle("Determinate")
417 | progress = 65
418 | secondaryProgress = 80
419 | showProgressTextAsFraction(true)
420 | show()
421 | }
422 | ```
423 | #### Output:
424 |
425 |
426 | ### Indeterminate ProgressDialog with NegativeButton and Custom OnClickListener for NegativeButton (Light Theme)
427 | > [!NOTE]
428 | > Enabling NegativeButton will automatically enable TitleView.
429 |
430 | #### Java Code:
431 | ```java
432 | progressDialog.setTheme(ProgressDialog.THEME_LIGHT);
433 | progressDialog.setMode(ProgressDialog.MODE_INDETERMINATE);
434 | progressDialog.setNegativeButton("Dismiss","Indeterminate",v -> {
435 | Toast.makeText(this,"Custom OnClickListener for Indeterminate",Toast.LENGTH_LONG).show();
436 | progressDialog.dismiss();
437 | });
438 | progressDialog.show();
439 | ```
440 | #### Kotlin Code:
441 | ```kotlin
442 | with(progressDialog)
443 | {
444 | theme = ProgressDialog.THEME_LIGHT
445 | mode = ProgressDialog.MODE_INDETERMINATE
446 | setNegativeButton("Dismiss", "Determinate") {
447 | Toast.makeText(this@KotlinActivity, "Custom OnClickListener for Indeterminate", Toast.LENGTH_LONG).show()
448 | dismiss()
449 | }
450 | show()
451 | }
452 | ```
453 | #### Output:
454 |
455 |
456 | ### Indeterminate ProgressDialog with NegativeButton and Custom OnClickListener for NegativeButton (Dark Theme)
457 | > [!NOTE]
458 | > Enabling NegativeButton will automatically enable TitleView.
459 |
460 | #### Java Code:
461 | ```java
462 | progressDialog.setTheme(ProgressDialog.THEME_DARK);
463 | progressDialog.setMode(ProgressDialog.MODE_INDETERMINATE);
464 | progressDialog.setNegativeButton("Dismiss","Indeterminate",v -> {
465 | Toast.makeText(this,"Custom OnClickListener for Indeterminate",Toast.LENGTH_LONG).show();
466 | progressDialog.dismiss();
467 | });
468 | progressDialog.show();
469 | ```
470 | #### Kotlin Code:
471 | ```kotlin
472 | with(progressDialog)
473 | {
474 | theme = ProgressDialog.THEME_DARK
475 | mode = ProgressDialog.MODE_INDETERMINATE
476 | setNegativeButton("Dismiss", "Determinate") {
477 | Toast.makeText(this@KotlinActivity, "Custom OnClickListener for Indeterminate", Toast.LENGTH_LONG).show()
478 | dismiss()
479 | }
480 | show()
481 | }
482 | ```
483 | #### Output:
484 |
485 |
486 | ### Determinate ProgressDialog with NegativeButton and Default OnClickListener for NegativeButton (Light Theme)
487 | > [!NOTE]
488 | > Enabling NegativeButton will automatically enable TitleView.
489 |
490 | #### Java Code:
491 | ```java
492 | progressDialog.setTheme(ProgressDialog.THEME_LIGHT);
493 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
494 | progressDialog.setProgress(54);
495 | progressDialog.showProgressTextAsFraction(true);
496 | progressDialog.setNegativeButton("Cancel","Determinate",null);
497 | progressDialog.show();
498 | ```
499 | #### Kotlin Code:
500 | ```kotlin
501 | with(progressDialog)
502 | {
503 | theme = ProgressDialog.THEME_LIGHT
504 | mode = ProgressDialog.MODE_DETERMINATE
505 | progress = 54
506 | showProgressTextAsFraction(true)
507 | setNegativeButton("Cancel","Determinate",null)
508 | show()
509 | }
510 | ```
511 | #### Output:
512 |
513 |
514 | ### Determinate ProgressDialog with NegativeButton and Default OnClickListener for NegativeButton (Dark Theme)
515 | ##### Note: Enabling NegativeButton will automatically enable TitleView.
516 | #### Java Code:
517 | ```java
518 | progressDialog.setTheme(ProgressDialog.THEME_DARK);
519 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
520 | progressDialog.setProgress(54);
521 | progressDialog.showProgressTextAsFraction(true);
522 | progressDialog.setNegativeButton("Cancel","Determinate",null);
523 | progressDialog.show();
524 | ```
525 | #### Kotlin Code:
526 | ```kotlin
527 | with(progressDialog)
528 | {
529 | theme = ProgressDialog.THEME_DARK
530 | mode = ProgressDialog.MODE_DETERMINATE
531 | progress = 54
532 | showProgressTextAsFraction(true)
533 | setNegativeButton("Cancel","Determinate",null)
534 | show()
535 | }
536 | ```
537 | #### Output:
538 |
539 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application")
3 | kotlin("android")
4 | }
5 |
6 | android {
7 | compileSdk = 32
8 |
9 | defaultConfig {
10 | applicationId = "com.techiness.progressdialogexample"
11 | minSdk = 24
12 | targetSdk = 32
13 | versionCode = 1
14 | versionName = "1.0"
15 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | getByName("release") {
20 | isMinifyEnabled = false
21 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
22 | }
23 | }
24 | compileOptions {
25 | sourceCompatibility = JavaVersion.VERSION_11
26 | targetCompatibility = JavaVersion.VERSION_11
27 | }
28 | kotlinOptions {
29 | jvmTarget = JavaVersion.VERSION_11.toString()
30 | }
31 | }
32 |
33 | dependencies {
34 | //implementation(project(":progressdialoglibrary"))
35 | val progressVersion = "1.5.1"
36 | implementation("androidx.appcompat:appcompat:1.7.0-alpha03")
37 | implementation("com.google.android.material:material:1.11.0")
38 | implementation("androidx.constraintlayout:constraintlayout:2.2.0")
39 | testImplementation("junit:junit:4.13.2")
40 | androidTestImplementation("androidx.test.ext:junit:1.2.1")
41 | androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
42 | implementation("com.github.techinessoverloaded:progress-dialog:$progressVersion")
43 | }
44 | repositories {
45 | mavenCentral()
46 | }
--------------------------------------------------------------------------------
/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.kts.kts.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/techiness/progressdialogexample/InstrumentedTestForLibrary.java:
--------------------------------------------------------------------------------
1 | package com.techiness.progressdialogexample;
2 |
3 | import android.content.Context;
4 | import androidx.test.platform.app.InstrumentationRegistry;
5 | import androidx.test.ext.junit.runners.AndroidJUnit4;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 | import static org.junit.Assert.*;
9 |
10 | import com.techiness.progressdialoglibrary.ProgressDialog;
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 InstrumentedTestForLibrary
19 | {
20 | private final Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
21 | private ProgressDialog progressDialog;
22 |
23 | @Test
24 | public void checkIfModeAndThemeAreSet1()
25 | {
26 | progressDialog = new ProgressDialog(appContext);
27 | assertEquals(progressDialog.getMode(), ProgressDialog.MODE_INDETERMINATE);
28 | assertEquals(progressDialog.getTheme(), ProgressDialog.THEME_LIGHT);
29 | }
30 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/techiness/progressdialogexample/KotlinActivity.kt:
--------------------------------------------------------------------------------
1 | package com.techiness.progressdialogexample
2 |
3 | import androidx.appcompat.app.AppCompatActivity
4 | import android.os.Bundle
5 | import android.widget.Toast
6 | import androidx.annotation.RestrictTo
7 | import com.techiness.progressdialoglibrary.ProgressDialog
8 |
9 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
10 | class KotlinActivity : AppCompatActivity() {
11 | override fun onCreate(savedInstanceState: Bundle?) {
12 | super.onCreate(savedInstanceState)
13 | setContentView(R.layout.activity_kotlin)
14 | ProgressDialog(this).also { progressDialog ->
15 | progressDialog.setOnShowListener {
16 | Toast.makeText(this@KotlinActivity, "From Kotlin", Toast.LENGTH_LONG).show()
17 | }
18 | progressDialog.show()
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/techiness/progressdialogexample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.techiness.progressdialogexample;
2 |
3 | import androidx.annotation.RestrictTo;
4 | import androidx.appcompat.app.AppCompatActivity;
5 | import androidx.appcompat.app.AppCompatDelegate;
6 | import androidx.appcompat.widget.SwitchCompat;
7 | import android.content.DialogInterface;
8 | import android.content.Intent;
9 | import android.os.Build;
10 | import android.os.Bundle;
11 | import android.os.Handler;
12 | import android.os.Looper;
13 | import android.widget.Button;
14 | import android.widget.Toast;
15 | import com.techiness.progressdialoglibrary.ProgressDialog;
16 |
17 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
18 | public class MainActivity extends AppCompatActivity
19 | {
20 | ProgressDialog progressDialog;
21 | Button showDeterBut,showInDeterBut,showDeterTitleBut,showInDeterTitleBut,showDeterWithoutProgressBut,showDeterWithNegativeButton,showInDeterWithNegativeButton;
22 | SwitchCompat darkSwitch;
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState)
25 | {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_main);
28 | bindViews();
29 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
30 | {
31 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
32 | progressDialog = new ProgressDialog(ProgressDialog.MODE_DETERMINATE,this,ProgressDialog.THEME_FOLLOW_SYSTEM);
33 | darkSwitch.setEnabled(false);
34 | }
35 | else
36 | {
37 | progressDialog = new ProgressDialog(MainActivity.this);
38 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
39 | }
40 | showDeterBut.setText(String.valueOf(progressDialog.getTheme()));
41 | progressDialog.setCancelable(true);
42 | setOnClickListeners();
43 | }
44 | private void bindViews()
45 | {
46 | darkSwitch=findViewById(R.id.darkSwitch);
47 | showDeterBut=findViewById(R.id.showDeterBut);
48 | showInDeterBut=findViewById(R.id.showInDeterBut);
49 | showDeterTitleBut=findViewById(R.id.showDeterTitleBut);
50 | showInDeterTitleBut=findViewById(R.id.showInDeterTitleBut);
51 | showDeterWithoutProgressBut=findViewById(R.id.showDeterWithoutProgressBut);
52 | showDeterWithNegativeButton=findViewById(R.id.showDeterWithNegativeButton);
53 | showInDeterWithNegativeButton=findViewById(R.id.showInDeterWithNegativeButton);
54 | }
55 | private void setOnClickListeners()
56 | {
57 | darkSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
58 | if(isChecked&&progressDialog.getTheme()!=ProgressDialog.THEME_DARK)
59 | {
60 | progressDialog.setTheme(ProgressDialog.THEME_DARK);
61 | }
62 | else
63 | {
64 | if(progressDialog.getTheme()!=ProgressDialog.THEME_LIGHT)
65 | {
66 | progressDialog.setTheme(ProgressDialog.THEME_LIGHT);
67 | }
68 | }
69 | });
70 | showDeterBut.setOnClickListener(v->onClick(1));
71 | showInDeterBut.setOnClickListener(v->onClick(2));
72 | showDeterTitleBut.setOnClickListener(v->onClick(3));
73 | showInDeterTitleBut.setOnClickListener(v->onClick(4));
74 | showDeterWithoutProgressBut.setOnClickListener(v->onClick(5));
75 | showDeterWithNegativeButton.setOnClickListener(v->onClick(6));
76 | showInDeterWithNegativeButton.setOnClickListener(v->onClick(7));
77 | }
78 | private void onClick(int requestCode)
79 | {
80 | switch(requestCode)
81 | {
82 | case 1:
83 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
84 | progressDialog.hideTitle();
85 | progressDialog.setProgress(65);
86 | progressDialog.setSecondaryProgress(0);
87 | progressDialog.hideNegativeButton();
88 | progressDialog.show();
89 | break;
90 | case 2:
91 | progressDialog.setMode(ProgressDialog.MODE_INDETERMINATE);
92 | progressDialog.hideTitle();
93 | progressDialog.show();
94 | progressDialog.hideNegativeButton();
95 | break;
96 | case 3:
97 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
98 | progressDialog.setTitle("Determinate");
99 | progressDialog.showProgressTextAsFraction(true);
100 | progressDialog.hideNegativeButton();
101 | progressDialog.setProgress(65);
102 | progressDialog.setSecondaryProgress(80);
103 | progressDialog.setCancelable(false);
104 | progressDialog.setOnShowListener(true, new DialogInterface.OnShowListener() {
105 | @Override
106 | public void onShow(DialogInterface dialog)
107 | {
108 | Toast.makeText(MainActivity.this,progressDialog.isCancelable()? "true": "false",Toast.LENGTH_LONG).show();
109 | }
110 | });
111 | progressDialog.show();
112 | new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
113 | @Override
114 | public void run()
115 | {
116 | progressDialog.setProgress(100);
117 | progressDialog.dismiss();
118 | }
119 | }, 50000);
120 | break;
121 | case 4:
122 | progressDialog.setMode(ProgressDialog.MODE_INDETERMINATE);
123 | progressDialog.setTitle("Indeterminate");
124 | progressDialog.hideNegativeButton();
125 | progressDialog.show();
126 | break;
127 | case 5:
128 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
129 | progressDialog.hideProgressText();
130 | progressDialog.setProgress(65);
131 | progressDialog.hideTitle();
132 | progressDialog.show();
133 | break;
134 | case 6:
135 | progressDialog.setMode(ProgressDialog.MODE_DETERMINATE);
136 | progressDialog.setProgress(54);
137 | progressDialog.setSecondaryProgress(0);
138 | progressDialog.showProgressTextAsFraction(true);
139 | progressDialog.setNegativeButton("Cancel","Determinate",null);
140 | progressDialog.setOnShowListener(true, new DialogInterface.OnShowListener() {
141 | @Override
142 | public void onShow(DialogInterface dialog)
143 | {
144 | Toast.makeText(MainActivity.this,"On Show",Toast.LENGTH_LONG).show();
145 | }
146 | });
147 | progressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
148 | @Override
149 | public void onDismiss(DialogInterface dialog) {
150 | Toast.makeText(MainActivity.this, "On Dismiss",Toast.LENGTH_LONG).show();
151 | }
152 | });
153 | progressDialog.show();
154 | break;
155 | case 7:
156 | progressDialog.setMode(ProgressDialog.MODE_INDETERMINATE);
157 | progressDialog.setNegativeButton("Go to next activity","Indeterminate",v -> {
158 | Toast.makeText(MainActivity.this,"Custom OnClickListener for Indeterminate",Toast.LENGTH_LONG).show();
159 | progressDialog.dismiss();
160 | Intent intent = new Intent(MainActivity.this,KotlinActivity.class);
161 | startActivity(intent);
162 | });
163 | progressDialog.show();
164 | break;
165 | default:
166 | break;
167 | }
168 | }
169 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_kotlin.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
15 |
21 |
30 |
39 |
48 |
57 |
66 |
75 |
84 |
85 |
--------------------------------------------------------------------------------
/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/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ProgressDialogExample
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/test/java/com/techiness/progressdialogexample/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.techiness.progressdialogexample;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 | dependencies {
8 | classpath("com.android.tools.build:gradle:7.3.1")
9 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21")
10 | classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.9.20")
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | google()
19 | mavenCentral()
20 | maven { url = uri("https://jitpack.io") }
21 | }
22 | }
23 |
24 | tasks.register("clean",Delete::class) {
25 | delete(rootProject.buildDir)
26 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri May 20 21:11:42 IST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/jitpack.yml:
--------------------------------------------------------------------------------
1 | jdk:
2 | - openjdk11
3 | before_install:
4 | - chmod +x gradlew
5 | install:
6 | - ./gradlew :progressdialoglibrary:clean :progressdialoglibrary:publishReleasePublicationToMavenLocal
7 |
--------------------------------------------------------------------------------
/output/deter_percent.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/deter_percent.jpg
--------------------------------------------------------------------------------
/output/deter_percent_dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/deter_percent_dark.jpg
--------------------------------------------------------------------------------
/output/deter_title.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/deter_title.jpg
--------------------------------------------------------------------------------
/output/deter_title_dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/deter_title_dark.jpg
--------------------------------------------------------------------------------
/output/deter_with_negativebtn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/deter_with_negativebtn.jpg
--------------------------------------------------------------------------------
/output/deter_with_negativebtn_dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/deter_with_negativebtn_dark.jpg
--------------------------------------------------------------------------------
/output/deter_without_progress.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/deter_without_progress.jpg
--------------------------------------------------------------------------------
/output/deter_without_progress_dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/deter_without_progress_dark.jpg
--------------------------------------------------------------------------------
/output/indeter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/indeter.jpg
--------------------------------------------------------------------------------
/output/indeter_dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/indeter_dark.jpg
--------------------------------------------------------------------------------
/output/indeter_with_negativebtn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/indeter_with_negativebtn.jpg
--------------------------------------------------------------------------------
/output/indeter_with_negativebtn_dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/indeter_with_negativebtn_dark.jpg
--------------------------------------------------------------------------------
/output/indeter_with_title.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/indeter_with_title.jpg
--------------------------------------------------------------------------------
/output/indeter_with_title_dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/output/indeter_with_title_dark.jpg
--------------------------------------------------------------------------------
/progressdialoglibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build/.transforms/
2 | /build/generated/
3 | /build/intermediates/
4 | /build/kotlin/
5 | /build/libs/
6 | /build/publications/
7 | /build/reports/
8 | /build/snapshot/
9 | /build/test-results/
10 | /build/tmp/
11 | /build/outputs/
12 | /build/dokka/
13 |
--------------------------------------------------------------------------------
/progressdialoglibrary/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.library")
3 | kotlin("android")
4 | id("maven-publish")
5 | id("org.jetbrains.dokka")
6 | }
7 |
8 | android {
9 | compileSdk = 32
10 |
11 | defaultConfig {
12 | minSdk = 24
13 | targetSdk = 32
14 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
15 | consumerProguardFiles("consumer-rules.pro")
16 | }
17 |
18 | buildFeatures {
19 | viewBinding = true
20 | }
21 |
22 | buildTypes {
23 | getByName("release") {
24 | isMinifyEnabled = false
25 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
26 | }
27 | }
28 | compileOptions {
29 | sourceCompatibility = JavaVersion.VERSION_11
30 | targetCompatibility = JavaVersion.VERSION_11
31 | }
32 | kotlinOptions {
33 | jvmTarget = JavaVersion.VERSION_11.toString()
34 | }
35 | publishing {
36 | singleVariant("release") {
37 | withSourcesJar()
38 | }
39 | }
40 | }
41 |
42 | afterEvaluate {
43 | publishing {
44 | publications {
45 | register("release") {
46 | from(components["release"])
47 | groupId = "com.github.techinessoverloaded"
48 | artifactId = "progress-dialog"
49 | version = "1.5.1"
50 | }
51 | }
52 | }
53 | }
54 |
55 | dependencies {
56 | implementation("androidx.appcompat:appcompat:1.7.0-alpha03")
57 | implementation("com.google.android.material:material:1.11.0")
58 | implementation("androidx.constraintlayout:constraintlayout:2.2.0")
59 | testImplementation("junit:junit:4.13.2")
60 | androidTestImplementation("androidx.test.ext:junit:1.2.1")
61 | androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
62 | }
63 | repositories {
64 | mavenCentral()
65 | }
--------------------------------------------------------------------------------
/progressdialoglibrary/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/techinessoverloaded/progress-dialog/9694d7aa95be45d49d6ffd026d034887a53e2bec/progressdialoglibrary/consumer-rules.pro
--------------------------------------------------------------------------------
/progressdialoglibrary/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.kts.kts.
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
--------------------------------------------------------------------------------
/progressdialoglibrary/src/androidTest/java/com/techiness/progressdialoglibrary/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.techiness.progressdialoglibrary;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.techiness.progressdialoglibrary.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/progressdialoglibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/progressdialoglibrary/src/main/java/com/techiness/progressdialoglibrary/ProgressDialog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * An easy-to-use ProgressDialog Library provided by Techiness Overloaded for Android API 24 and above.
3 | * Licensed under the Apache License, Version 2.0 (the "License")
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | */
8 | package com.techiness.progressdialoglibrary
9 |
10 | import android.annotation.SuppressLint
11 | import android.content.Context
12 | import android.content.DialogInterface
13 | import android.content.res.ColorStateList
14 | import android.graphics.drawable.ColorDrawable
15 | import android.graphics.drawable.Drawable
16 | import android.os.Build
17 | import android.os.Handler
18 | import android.os.Looper
19 | import android.view.LayoutInflater
20 | import android.view.View
21 | import androidx.annotation.*
22 | import androidx.appcompat.app.AlertDialog
23 | import androidx.core.content.ContextCompat
24 | import androidx.core.os.HandlerCompat
25 | import com.techiness.progressdialoglibrary.ProgressDialog.Companion.MODE_DETERMINATE
26 | import com.techiness.progressdialoglibrary.ProgressDialog.Companion.MODE_INDETERMINATE
27 | import com.techiness.progressdialoglibrary.ProgressDialog.Companion.THEME_DARK
28 | import com.techiness.progressdialoglibrary.ProgressDialog.Companion.THEME_LIGHT
29 | import com.techiness.progressdialoglibrary.databinding.LayoutProgressdialogBinding
30 | import java.util.*
31 | import java.util.concurrent.TimeUnit
32 |
33 | /**
34 | * An easy to use ProgressDialog library for Android API level 24 and above.
35 | * The below given parameters apply for all the overloaded constructors in Java or a Single Constructor with default arguments in Kotlin.
36 | * @param context The Activity context which must be provided for sure no matter which overloaded constructor is called.
37 | * @param modeConstant The [Int] constant, which is an optional parameter that accepts either [MODE_DETERMINATE] or [MODE_INDETERMINATE]. If it is not passed, [MODE_INDETERMINATE] will be set by default, which can be changed later by setting [mode].
38 | * @param themeConstant The [Int] constant, which is an optional parameter that accepts either [THEME_DARK], [THEME_LIGHT], or [THEME_FOLLOW_SYSTEM]
39 | * If it is not passed, [THEME_LIGHT] will be set by default, which can be changed later by setting [theme].
40 | *
41 | * **NOTE** : [THEME_FOLLOW_SYSTEM] can be used starting from Android API Level 30 (Android 11) only. Attempting to use it in lower versions will throw [IllegalArgumentException].
42 | */
43 | class ProgressDialog @JvmOverloads constructor(
44 | @ModeConstant modeConstant: Int = MODE_INDETERMINATE,
45 | private val context: Context,
46 | @ThemeConstant themeConstant: Int = THEME_LIGHT)
47 | {
48 | @SuppressLint("InlinedApi")
49 | @IntDef(THEME_LIGHT, THEME_DARK, THEME_FOLLOW_SYSTEM)
50 | @Retention(AnnotationRetention.SOURCE)
51 | annotation class ThemeConstant
52 |
53 | @IntDef(MODE_INDETERMINATE, MODE_DETERMINATE)
54 | @Retention(AnnotationRetention.SOURCE)
55 | annotation class ModeConstant
56 |
57 | companion object
58 | {
59 | /**
60 | * The default Theme for ProgressDialog (even if it is not passed in Constructor).
61 | * Suitable for apps having a Light Theme.
62 | * Theme can be changed later by setting [theme].
63 | */
64 | const val THEME_LIGHT = 1
65 |
66 | /**
67 | * This theme is suitable for apps having a Dark Theme.
68 | * This Constant SHOULD be passed explicitly in the Constructor for setting Dark Theme for ProgressDialog.
69 | * Theme can be changed later by setting [theme].
70 | */
71 | const val THEME_DARK = 2
72 |
73 | /**
74 | * When this ThemeConstant is used, ProgressDialog's theme is automatically changed to match the System's theme each time before [show] is called.
75 | * This Constant can be used starting from Android API Level 30 (Android 11) ONLY.
76 | * Setting [theme] will throw [IllegalArgumentException] if this Constant is passed in method call in Android versions lower than Android 11.
77 | */
78 | @RequiresApi(api = Build.VERSION_CODES.R)
79 | const val THEME_FOLLOW_SYSTEM = 3
80 |
81 | /**
82 | * The default mode for ProgressDialog where an Indeterminate Spinner is shown for indicating Progress (even if it is not passed in Constructor).
83 | * Suitable for implementations where the exact progress of an operation is unknown to the Developer.
84 | */
85 | const val MODE_INDETERMINATE = 4
86 |
87 | /**
88 | * In this mode, a Determinate ProgressBar is shown inside the ProgressDialog for indicating Progress.
89 | * It also has a TextView for numerically showing the Progress Value either as Percentage or as Fraction.
90 | * Progress Value is shown as Percentage by Default which can be changed using [showProgressTextAsFraction].
91 | */
92 | const val MODE_DETERMINATE = 5
93 | private const val SHOW_AS_FRACTION = 6
94 | private const val SHOW_AS_PERCENT = 7
95 | private const val HIDE_PROGRESS_TEXT = 8
96 | }
97 |
98 | private var progressDialog: AlertDialog
99 | private var progressViewMode = 0
100 | private var autoThemeEnabled = false
101 | private var binding: LayoutProgressdialogBinding = LayoutProgressdialogBinding.inflate(LayoutInflater.from(context))
102 | private lateinit var handler: Handler
103 | private lateinit var runnable: Runnable
104 | private var isTimeBeingTracked = false
105 |
106 | /**
107 | * Gets/Sets the mode of the ProgressDialog which is [MODE_INDETERMINATE] by Default.
108 | * If you're going to use only one Mode constantly, no need to set this. Instead, use an appropriate Constructor to set the required Mode during Instantiation.
109 | * Only [MODE_DETERMINATE] or [MODE_INDETERMINATE] should be passed as parameter for the Setter.
110 | * @throws [IllegalArgumentException] If any other value other than [MODE_DETERMINATE] or [MODE_INDETERMINATE] is passed to the Setter.
111 | */
112 | @ModeConstant var mode: Int = MODE_INDETERMINATE
113 | @Throws(IllegalArgumentException::class)
114 | set(@ModeConstant modeConstant)
115 | {
116 | when(modeConstant)
117 | {
118 | MODE_DETERMINATE ->
119 | {
120 | binding.textViewIndeterminate.hide()
121 | binding.progressbarIndeterminate.hide()
122 | binding.textViewDeterminate.unhide()
123 | binding.progressbarDeterminate.unhide()
124 | progressViewMode = SHOW_AS_PERCENT
125 | binding.progressTextView.unhide()
126 | binding.timeElapsedTextView.hide()
127 | incrementValue = if (incrementValue == 0) 1 else incrementValue
128 | field = modeConstant
129 | }
130 | MODE_INDETERMINATE -> {
131 | binding.textViewDeterminate.hide()
132 | binding.progressbarDeterminate.hide()
133 | binding.progressTextView.hide()
134 | binding.textViewIndeterminate.unhide()
135 | binding.progressbarIndeterminate.unhide()
136 | binding.timeElapsedTextView.hide()
137 | if(isTimeBeingTracked)
138 | isTimeBeingTracked = false
139 | field = modeConstant
140 | }
141 | else -> throw IllegalArgumentException("Invalid Values passed to function ! Make sure to pass MODE_INDETERMINATE or MODE_DETERMINATE only !")
142 | }
143 | }
144 |
145 | /**
146 | * Gets/Sets the theme of the ProgressDialog. The theme is [THEME_LIGHT] by Default.
147 | * If you're going to use only one Theme constantly, no need to set this. Instead, use an appropriate Constructor to set the required Theme during Instantiation.
148 | * Only [THEME_LIGHT], [THEME_DARK] or [THEME_FOLLOW_SYSTEM] should be passed as parameter for the Setter.
149 | * @throws [IllegalArgumentException] If any other value other than [THEME_LIGHT], [THEME_DARK] or [THEME_FOLLOW_SYSTEM] is passed to the Setter or if [THEME_FOLLOW_SYSTEM] is used in Android Versions BELOW Android 11 (API Level 30).
150 | */
151 | var theme = THEME_LIGHT
152 | @SuppressLint("InlinedApi")
153 | @ThemeConstant get()
154 | {
155 | return if(autoThemeEnabled) THEME_FOLLOW_SYSTEM else field
156 | }
157 | @Throws(IllegalArgumentException::class)
158 | set(@ThemeConstant themeConstant)
159 | {
160 | when(themeConstant)
161 | {
162 | THEME_DARK, THEME_LIGHT ->
163 | {
164 | autoThemeEnabled = false
165 | if (setThemeInternal(themeConstant))
166 | field = themeConstant
167 | }
168 | THEME_FOLLOW_SYSTEM ->
169 | {
170 | require(isAboveOrEqualToAnd11())
171 | { "THEME_FOLLOW_SYSTEM can be used starting from Android 11 (API Level 30) only !" }
172 | autoThemeEnabled = true
173 | }
174 | else -> throw IllegalArgumentException("Invalid Values passed to function ! Make sure to pass THEME_LIGHT, THEME_DARK or THEME_FOLLOW_SYSTEM only !")
175 | }
176 | }
177 |
178 | /**
179 | * Toggles the Cancelable property of ProgressDialog which is `false` by Default.
180 | * If it is set to `true`, the User can cancel the ProgressDialog by pressing Back Button or by touching any other part of the screen.
181 | * It is NOT RECOMMENDED to set Cancelable to `true` unless Time Tracking is enabled.
182 | */
183 | var isCancelable = false
184 | set(cancelable)
185 | {
186 | if(!cancelable)
187 | {
188 | if(!isTimeBeingTracked)
189 | {
190 | progressDialog.setCancelable(false)
191 | progressDialog.setCanceledOnTouchOutside(false)
192 | field = false
193 | }
194 | }
195 | else
196 | {
197 | progressDialog.setCancelable(true)
198 | progressDialog.setCanceledOnTouchOutside(true)
199 | field = true
200 | }
201 | }
202 |
203 | constructor(context: Context,@ThemeConstant themeConstant: Int = THEME_LIGHT):
204 | this(modeConstant = MODE_INDETERMINATE, context = context, themeConstant = themeConstant)
205 |
206 | init
207 | {
208 | val builder = AlertDialog.Builder(context)
209 | builder.setView(binding.root)
210 | progressDialog = builder.create()
211 | if (progressDialog.window != null)
212 | {
213 | progressDialog.window!!.setBackgroundDrawable(ColorDrawable(0))
214 | }
215 | mode = modeConstant
216 | theme = themeConstant
217 | isCancelable = false
218 | }
219 |
220 | /**
221 | * Gets/Sets the Progress Value of Determinate ProgressBar.
222 | * Can be used only in [MODE_DETERMINATE] Mode. Does not do anything if the ProgressDialog is in [MODE_INDETERMINATE] Mode.
223 | * If the parameter progress is greater than MaxValue for Setter, MaxValue will be set as Progress.
224 | * The Getter will return the current Progress Value if it is in [MODE_DETERMINATE] Mode, else -1 will be returned.
225 | * @see incrementProgress
226 | * @throws UnsupportedOperationException If the Setter is called on [MODE_INDETERMINATE] Mode.
227 | */
228 | var progress: Int
229 | get()
230 | {
231 | return if (isDeterminate) binding.progressbarDeterminate.progress else -1
232 | }
233 | @Throws(UnsupportedOperationException::class)
234 | set(progressValue)
235 | {
236 | if (isDeterminate)
237 | {
238 | binding.progressbarDeterminate.setProgress(progressValue, true)
239 | setProgressText()
240 | }
241 | else
242 | {
243 | throw UnsupportedOperationException("Cannot set Progress for Indeterminate ProgressDialog !")
244 | }
245 | }
246 |
247 | /**
248 | * Gets the Message showed in the ProgressDialog.
249 | * @return The Text displayed in current [MODE_INDETERMINATE] ProgressBar or [MODE_DETERMINATE] ProgressBar respectively.
250 | */
251 | fun getMessage() : CharSequence
252 | {
253 | return if(!isDeterminate) binding.textViewIndeterminate.text else binding.textViewDeterminate.text
254 | }
255 |
256 | /**
257 | * Sets the Text to be displayed alongside ProgressBar.
258 | * Message is "Loading" by Default.
259 | * @param message The Text to be displayed inside ProgressDialog.
260 | */
261 | fun setMessage(message: CharSequence)
262 | {
263 | if (!isDeterminate)
264 | {
265 | binding.textViewIndeterminate.text = message
266 | }
267 | else
268 | {
269 | binding.textViewDeterminate.text = message
270 | }
271 | }
272 |
273 | /**
274 | * Sets the Text from the resID provided, to be displayed alongside ProgressBar.
275 | * Message is "Loading" by Default.
276 | * @param messageResID The resource id for the string resource.
277 | */
278 | fun setMessage(@StringRes messageResID: Int)
279 | {
280 | setMessage(context.getText(messageResID).toString())
281 | }
282 |
283 | /**
284 | * Gets the Current Title of The ProgressDialog.
285 | * @return The Title of the ProgressDialog if the Title is Visible, else an empty [CharSequence].
286 | */
287 | fun getTitle() : CharSequence
288 | {
289 | return if(binding.titleView.isVisible()) binding.titleView.text else ""
290 | }
291 |
292 | /**
293 | * Sets the Title of ProgressDialog.
294 | * This is "ProgressDialog" by Default.
295 | * Title is Hidden by Default. This Method makes the Title Visible.
296 | * Title will be made visible automatically if [setNegativeButton] or
297 | * [setNegativeButton] was used before.
298 | * @param title The text to be set as the Title of ProgressDialog.
299 | */
300 | fun setTitle(title: CharSequence)
301 | {
302 | binding.titleView.text = title
303 | if (binding.titleView.isGone())
304 | binding.titleView.unhide()
305 | }
306 |
307 | /**
308 | * Sets the Title of ProgressDialog using the String resource given.
309 | * Title is "ProgressDialog" by Default.
310 | * Title is Hidden by Default. This Method makes the Title Visible.
311 | * Title will be made visible automatically if [setNegativeButton] or
312 | * [setNegativeButton] was used before.
313 | * @param titleResID The resource id of the string resource.
314 | */
315 | fun setTitle(@StringRes titleResID: Int)
316 | {
317 | setTitle(context.getText(titleResID).toString())
318 | }
319 |
320 | /**
321 | * Hides the Title of ProgressDialog.
322 | * Title is Hidden by Default.
323 | * Use this method only if you have used [setTitle] before.
324 | * This method won't work if [setNegativeButton] was used before.
325 | * @return true if Title is Hid. false if the Title is already Hidden or if NegativeButton is used.
326 | */
327 | fun hideTitle(): Boolean
328 | {
329 | if (binding.negativeButton.isVisible())
330 | return false
331 | if (binding.titleView.isVisible())
332 | binding.titleView.hide()
333 | return true
334 | }
335 |
336 | /**
337 | * Gets/Sets the Increment Value of the [MODE_DETERMINATE] ProgressDialog.
338 | * The default value is 1.
339 | * Gets the Increment Value only if the ProgressDialog is in [MODE_DETERMINATE] Mode, else -1 is returned.
340 | * Sets the Increment Value only if the ProgressDialog is in [MODE_DETERMINATE] Mode. If the passed parameter is greater than maxValue, it will not be set.
341 | */
342 | var incrementValue: Int = 1
343 | get()
344 | {
345 | return if (isDeterminate) field else -1
346 | }
347 | set(incrementAmount)
348 | {
349 | if (isDeterminate)
350 | {
351 | field = incrementAmount
352 | }
353 | }
354 |
355 | /**
356 | * Increments the Progress Value of Determinate ProgressBar using the Offset Value set using [incrementValue].
357 | * Can be used only in [MODE_DETERMINATE] Mode.
358 | * @throws UnsupportedOperationException If called in [MODE_INDETERMINATE] Mode.
359 | */
360 | @Throws(UnsupportedOperationException::class)
361 | fun incrementProgress()
362 | {
363 | if (isDeterminate)
364 | {
365 | binding.progressbarDeterminate.incrementProgressBy(incrementValue)
366 | setProgressText()
367 | }
368 | else
369 | {
370 | throw UnsupportedOperationException("Cannot Increment Progress in Indeterminate ProgressDialog !")
371 | }
372 | }
373 |
374 | /**
375 | * Gets/Sets the Maximum value of [MODE_DETERMINATE] ProgressBar.
376 | * Gets the Maximum Value only if the ProgressBar is in [MODE_DETERMINATE]. Else, -1 is returned.
377 | * Sets the parameter value as Maximum Value only if the ProgressBar is in [MODE_DETERMINATE] Mode.
378 | * It is advised to Set this value before setting [progress] or calling [incrementProgress] Method.
379 | * @throws UnsupportedOperationException If the Setter is called in [MODE_INDETERMINATE] Mode.
380 | */
381 | var maxValue: Int
382 | get()
383 | {
384 | return if (isDeterminate) binding.progressbarDeterminate.max else -1
385 | }
386 | @Throws(UnsupportedOperationException::class)
387 | set(maxValue)
388 | {
389 | if (isDeterminate)
390 | {
391 | binding.progressbarDeterminate.max = maxValue
392 | progress = progress
393 | }
394 | else
395 | {
396 | throw UnsupportedOperationException("Cannot set Max Value in Indeterminate ProgressDialog !")
397 | }
398 | }
399 |
400 | /**
401 | * Toggles the Progress TextView's format as Fraction if "true" is passed.
402 | * Progress TextView's Default format is Percentage format.
403 | * Can be used only in [MODE_DETERMINATE].
404 | * If [hideProgressText] was used before, this method will again make Progress TextView visible.
405 | * @param progressTextAsFraction The boolean value to change Progress TextView's format.
406 | * @return true if Mode is [MODE_DETERMINATE] and Progress is set. false otherwise and also on Redundant Calls.
407 | */
408 | fun showProgressTextAsFraction(progressTextAsFraction: Boolean): Boolean
409 | {
410 | return if (isDeterminate)
411 | {
412 | if (progressTextAsFraction)
413 | {
414 | when (progressViewMode)
415 | {
416 | SHOW_AS_FRACTION -> return false
417 | SHOW_AS_PERCENT, HIDE_PROGRESS_TEXT -> {
418 | progressViewMode = SHOW_AS_FRACTION
419 | binding.progressTextView.text = progressAsFraction
420 | }
421 | }
422 | } else {
423 | when (progressViewMode) {
424 | SHOW_AS_PERCENT -> return false
425 | SHOW_AS_FRACTION, HIDE_PROGRESS_TEXT -> {
426 | progressViewMode = SHOW_AS_PERCENT
427 | binding.progressTextView.text = progressAsPercent
428 | }
429 | }
430 | }
431 | true
432 | }
433 | else
434 | {
435 | false
436 | }
437 | }
438 |
439 | /**
440 | * Hides the Progress TextView.
441 | * Can be used only in [MODE_DETERMINATE].
442 | * @return true if Mode is [MODE_DETERMINATE] and Progress TextView is hidden. false otherwise.
443 | */
444 | fun hideProgressText(): Boolean
445 | {
446 | return if (isDeterminate)
447 | {
448 | progressViewMode = HIDE_PROGRESS_TEXT
449 | if (binding.progressTextView.isVisible())
450 | {
451 | binding.progressTextView.hide()
452 | }
453 | true
454 | }
455 | else
456 | {
457 | false
458 | }
459 | }
460 |
461 | /**
462 | * Starts the ProgressDialog and shows it on the Screen.
463 | */
464 | @SuppressLint("NewApi")
465 | fun show()
466 | {
467 | if (autoThemeEnabled)
468 | {
469 | if (isSystemInNightMode)
470 | {
471 | if(theme != THEME_DARK)
472 | setThemeInternal(THEME_DARK)
473 | }
474 | else if (!isSystemInNightMode)
475 | {
476 | if(theme != THEME_LIGHT)
477 | setThemeInternal(THEME_LIGHT)
478 | }
479 | }
480 | progressDialog.show()
481 | }
482 |
483 | /**
484 | * Dismisses the ProgressDialog, removing it from the Screen.
485 | * Calls [DialogInterface.OnDismissListener], if it is set using [setOnDismissListener].
486 | * To be used after the Task calling ProgressDialog is Over or if any Exception Occurs during Task execution.
487 | * In case of passing to Another Activity/Fragment, this method SHOULD be called before starting the next Activity/Fragment.
488 | * Else, it would cause WindowLeakedException.
489 | */
490 | fun dismiss()
491 | {
492 | progressDialog.dismiss()
493 | }
494 |
495 | /**
496 | * Sets the [DialogInterface.OnCancelListener] for ProgressDialog.
497 | * Should be used only if [isCancelable] was set true earlier since cancel() cannot be called explicitly
498 | * and ProgressDialog is NOT cancelable by Default.
499 | * @param onCancelListener [DialogInterface.OnCancelListener] listener object.
500 | * @return true if ProgressDialog is Cancelable. false otherwise.
501 | */
502 | fun setOnCancelListener(onCancelListener: DialogInterface.OnCancelListener): Boolean
503 | {
504 | return if (isCancelable)
505 | {
506 | if(isTimeBeingTracked)
507 | {
508 | progressDialog.setOnCancelListener { dialog ->
509 | if(HandlerCompat.hasCallbacks(handler, runnable))
510 | {
511 | handler.removeCallbacks(runnable)
512 | onCancelListener.onCancel(dialog)
513 | }
514 | }
515 | }
516 | true
517 | }
518 | else
519 | {
520 | false
521 | }
522 | }
523 |
524 | /**
525 | * Sets the [DialogInterface.OnDismissListener] for ProgressDialog.
526 | * @param onDismissListener [DialogInterface.OnDismissListener] listener object.
527 | */
528 | fun setOnDismissListener(onDismissListener: DialogInterface.OnDismissListener)
529 | {
530 | if(isTimeBeingTracked)
531 | {
532 | progressDialog.setOnDismissListener { dialog ->
533 | if(HandlerCompat.hasCallbacks(handler, runnable))
534 | {
535 | handler.removeCallbacks(runnable)
536 | onDismissListener.onDismiss(dialog)
537 | }
538 | }
539 | }
540 | }
541 |
542 | /**
543 | * Sets the [DialogInterface.OnShowListener] for ProgressDialog.
544 | * Time Tracking is disabled by Default. It can be enabled by passing `true` to the `isTimeTrackingEnabled` parameter of the function.
545 | * The `onshowListener` parameter can be `null` when `isTimeTrackingEnabled` parameter is passed. If `null` is passed for `onShowListener` when `isTimeTrackingEnabled` is not passed, no listener will be set.
546 | * Enabling Time Tracking will make [isCancelable] to `true` automatically, since Time Tracking is an indefinite operation.
547 | * It is recommended to set NEGATIVE BUTTON using [setNegativeButton] Method or set [DialogInterface.OnDismissListener] using [setOnDismissListener] after enabling Time Tracking feature.
548 | * Time Tracking will stop when [progress] reaches [maxValue] or when the Dialog is dismissed or cancelled.
549 | * @param onShowListener [DialogInterface.OnShowListener] listener object.
550 | * @throws IllegalArgumentException when attempting to enable Time Tracking in [MODE_INDETERMINATE] Mode.
551 | */
552 | @JvmOverloads
553 | @Throws(IllegalArgumentException::class)
554 | fun setOnShowListener(isTimeTrackingEnabled: Boolean = false, onShowListener: DialogInterface.OnShowListener?)
555 | {
556 | if(isTimeTrackingEnabled)
557 | {
558 | require(isDeterminate)
559 | {
560 | "Time Tracking can be enabled in MODE_DETERMINATE Only!"
561 | }
562 | binding.timeElapsedTextView.unhide()
563 | if(onShowListener == null)
564 | {
565 | progressDialog.setOnShowListener {
566 | startTimeTrackingLoop()
567 | }
568 | }
569 | else
570 | {
571 | progressDialog.setOnShowListener { dialog ->
572 | startTimeTrackingLoop()
573 | onShowListener.onShow(dialog)
574 | }
575 | }
576 | isTimeBeingTracked = true
577 | }
578 | else
579 | {
580 | progressDialog.setOnShowListener(onShowListener)
581 | binding.timeElapsedTextView.hide()
582 | isTimeBeingTracked = false
583 | }
584 | if(!isCancelable)
585 | {
586 | isCancelable = true
587 | setOnCancelListenerInternal()
588 | }
589 | setOnDismissListenerInternal()
590 | }
591 |
592 | /**
593 | * Checks if ProgressValue is equal to MaxValue.
594 | * Can be used only in [MODE_DETERMINATE].
595 | * @return true if ProgressValue is equal to MaxValue. false otherwise and also if mode is not [MODE_DETERMINATE].
596 | */
597 | fun hasProgressReachedMaxValue(): Boolean = if (isDeterminate) progress == maxValue else false
598 |
599 | /**
600 | * Gets the Integral Value required to reach MaxValue from the current ProgressValue.
601 | * Can be used only in [MODE_DETERMINATE].
602 | * @return The Integral Amount required to reach MaxValue. -1 if mode is not [MODE_DETERMINATE].
603 | */
604 | fun remainingProgress(): Int = if (isDeterminate) maxValue - progress else -1
605 |
606 | /**
607 | * Gets/Sets the Secondary ProgressValue.
608 | * Can be used only in [MODE_DETERMINATE].
609 | * Getter returns the Secondary ProgressValue only if the ProgressDialog is in [MODE_DETERMINATE] else -1 is returned.
610 | * Setter works only when called on [MODE_DETERMINATE] Mode.
611 | */
612 | var secondaryProgress: Int
613 | get() = if (isDeterminate) binding.progressbarDeterminate.secondaryProgress else -1
614 | set(secondaryProgressValue)
615 | {
616 | if (isDeterminate)
617 | {
618 | binding.progressbarDeterminate.secondaryProgress = secondaryProgressValue
619 | }
620 | }
621 |
622 | /**
623 | * Gets the Integral Value required to reach MaxValue from the current Secondary ProgressValue.
624 | * Can be used only in [MODE_DETERMINATE].
625 | * @return The Integral Amount required to reach MaxValue from Secondary ProgressValue. -1 if mode is not [MODE_DETERMINATE].
626 | */
627 | fun secondaryRemainingProgress(): Int = if (isDeterminate) maxValue - secondaryProgress else -1
628 |
629 | /**
630 | * Checks if Secondary ProgressValue is equal to MaxValue.
631 | * Can be used only in [MODE_DETERMINATE].
632 | * @return true if Secondary ProgressValue is equal to MaxValue. false otherwise and also if mode is not [MODE_DETERMINATE].
633 | */
634 | fun hasSecondaryProgressReachedMaxValue(): Boolean = if (isDeterminate) secondaryProgress == maxValue else false
635 |
636 | /**
637 | * Sets a Custom Drawable to the Indeterminate ProgressBar.
638 | * Can be used only in [MODE_DETERMINATE].
639 | * Use this when you need to define a custom Drawable Design for Indeterminate ProgressBar.
640 | * @param progressDrawable The Drawable object used to draw the Indeterminate ProgressBar.
641 | * @return true if mode is [MODE_INDETERMINATE] and the Drawable is set. false otherwise.
642 | * @see getIndeterminateDrawable
643 | */
644 | fun setIndeterminateDrawable(progressDrawable: Drawable?): Boolean
645 | {
646 | return if (!isDeterminate)
647 | {
648 | binding.progressbarIndeterminate.indeterminateDrawable = progressDrawable
649 | true
650 | }
651 | else
652 | {
653 | false
654 | }
655 | }
656 |
657 | /**
658 | * Sets a Custom Drawable from the passed Drawable resource to the Indeterminate ProgressBar.
659 | * Can be used only in [MODE_INDETERMINATE].
660 | * Use this when you need to define a custom Drawable Design for Indeterminate ProgressBar.
661 | * @param progressDrawableResID The resource id of the Drawable resource used to draw the Indeterminate ProgressBar.
662 | * @return true if mode is [MODE_INDETERMINATE] and the Drawable is set. false otherwise.
663 | * @see getIndeterminateDrawable
664 | */
665 | fun setIndeterminateDrawable(@DrawableRes progressDrawableResID: Int): Boolean
666 | {
667 | return setIndeterminateDrawable(ContextCompat.getDrawable(context, progressDrawableResID))
668 | }
669 |
670 | /**
671 | * Gets the Drawable object used to draw the Indeterminate ProgressBar.
672 | * Can be used only in [MODE_INDETERMINATE].
673 | * @return Drawable Object if mode is [MODE_INDETERMINATE]. null otherwise.
674 | * @see setIndeterminateDrawable
675 | */
676 | fun getIndeterminateDrawable(): Drawable?
677 | {
678 | return if (!isDeterminate) binding.progressbarIndeterminate.indeterminateDrawable else null
679 | }
680 |
681 | /**
682 | * Sets a Custom Drawable to the Determinate ProgressBar.
683 | * Can be used only in [MODE_DETERMINATE].
684 | * Use this when you need to define a custom Drawable Design for Determinate ProgressBar.
685 | * @param progressDrawable The Drawable object used to draw the Determinate ProgressBar.
686 | * @return true if mode is [MODE_DETERMINATE] and the Drawable is set. false otherwise.
687 | * @see getDeterminateDrawable
688 | */
689 | fun setDeterminateDrawable(progressDrawable: Drawable?): Boolean
690 | {
691 | return if (isDeterminate) {
692 | binding.progressbarDeterminate.progressDrawable = progressDrawable
693 | true
694 | } else {
695 | false
696 | }
697 | }
698 |
699 | /**
700 | * Sets a Custom Drawable from the passed Drawable resource to the Determinate ProgressBar.
701 | * Can be used only in [MODE_DETERMINATE].
702 | * Use this when you need to define a custom Drawable Design for Determinate ProgressBar.
703 | * @param progressDrawableResID The resource id of the Drawable resource used to draw the Determinate ProgressBar.
704 | * @return true if mode is [MODE_DETERMINATE] and the Drawable is set. false otherwise.
705 | * @see getDeterminateDrawable
706 | */
707 | fun setDeterminateDrawable(@DrawableRes progressDrawableResID: Int): Boolean {
708 | return setDeterminateDrawable(ContextCompat.getDrawable(context, progressDrawableResID))
709 | }
710 |
711 | /**
712 | * Gets the Drawable object used to draw the Determinate ProgressBar.
713 | * Can be used only in [MODE_DETERMINATE].
714 | * @return Drawable Object if mode is [MODE_DETERMINATE]. null otherwise.
715 | * @see setDeterminateDrawable
716 | */
717 | fun getDeterminateDrawable(): Drawable?
718 | {
719 | return if (isDeterminate) binding.progressbarDeterminate.progressDrawable else null
720 | }
721 |
722 | /**
723 | * Gets/Sets the Tint List Associated with the Current [MODE_DETERMINATE] or [MODE_INDETERMINATE] Mode ProgressDialog respectively.
724 | */
725 | var progressTintList: ColorStateList?
726 | get() = if (isDeterminate) binding.progressbarDeterminate.progressTintList else binding.progressbarIndeterminate.indeterminateTintList
727 | set(tintList)
728 | {
729 | if (!isDeterminate)
730 | binding.progressbarIndeterminate.indeterminateTintList = tintList
731 | else
732 | binding.progressbarDeterminate.progressTintList = tintList
733 | }
734 |
735 | /**
736 | * Gets/Sets the Secondary Progress Tint List Associated with the Current [MODE_DETERMINATE] or [MODE_INDETERMINATE] Mode ProgressDialog respectively.
737 | */
738 | var secondaryProgressTintList: ColorStateList?
739 | get() = if (isDeterminate) binding.progressbarDeterminate.secondaryProgressTintList else binding.progressbarIndeterminate.secondaryProgressTintList
740 | set(secondaryTintList)
741 | {
742 | if (!isDeterminate)
743 | binding.progressbarIndeterminate.secondaryProgressTintList = secondaryTintList
744 | else
745 | binding.progressbarDeterminate.secondaryProgressTintList = secondaryTintList
746 | }
747 |
748 | /**
749 | * Sets the NegativeButton with the passed text for the ProgressDialog and also sets the OnClickListener for the Button.
750 | * NegativeButton is hidden by default. This method makes it visible.
751 | * This method also enables the Title to be shown (even if it was hidden till then).
752 | * If [setTitle] or [setTitle] was used before, and new Title is passed, the new Title will Override the previously set Title.
753 | * If null is passed for listener, default listener which dismisses the ProgressDialog when clicked, will be used.
754 | * @param text The text to be set in the NegativeButton.
755 | * @param listener The [View.OnClickListener] listener to be set to NegativeButton. If null, default cancel listener will be used.
756 | */
757 | fun setNegativeButton(text: CharSequence, title: CharSequence, listener: View.OnClickListener?)
758 | {
759 | binding.negativeButton.text = text
760 | binding.negativeButton.setOnClickListener(listener ?: View.OnClickListener { dismiss() })
761 | if (binding.negativeButton.isGone())
762 | {
763 | enableNegativeButton(title)
764 | }
765 | }
766 |
767 | /**
768 | * Sets the NegativeButton with the text from passed resource id for the ProgressDialog and also sets the OnClickListener for the Button.
769 | * NegativeButton is hidden by default. This method makes it visible.
770 | * This method also enables the Title to be shown (even if it was hidden till then).
771 | * If [setTitle] or [setTitle] was used before, and new titleResID is passed, the new Title will Override the previously set Title.
772 | * If null is passed for listener, default listener which dismisses the ProgressDialog when clicked, will be used.
773 | * @param textResID The resource id of the text to be set in the NegativeButton.
774 | * @param listener The [View.OnClickListener] listener to be set to NegativeButton.
775 | */
776 | fun setNegativeButton(@StringRes textResID: Int, @StringRes titleResID: Int, listener: View.OnClickListener?)
777 | {
778 | setNegativeButton(context.getText(textResID).toString(), context.getText(titleResID).toString(), listener)
779 | }
780 |
781 | /**
782 | * Hides the NegativeButton. NegativeButton is Hidden by Default.
783 | * Use this method only if you have used [setNegativeButton] or
784 | * [setNegativeButton] before.
785 | * Note : This method will not hide the Title. You have to explicitly call [hideTitle] to do the same.
786 | */
787 | fun hideNegativeButton()
788 | {
789 | if (binding.negativeButton.isVisible())
790 | {
791 | binding.negativeButton.hide()
792 | }
793 | }
794 |
795 | private fun startTimeTrackingLoop()
796 | {
797 | val startTime = Date()
798 | var currentTime: Date
799 | var difference: Long
800 | var secondsDifference: Long
801 | var minutesDifference: Long
802 | var hoursDifference: Long
803 | var message: String
804 | handler = Handler(Looper.getMainLooper())
805 | runnable = object: Runnable
806 | {
807 | override fun run()
808 | {
809 | if (!hasProgressReachedMaxValue())
810 | {
811 | currentTime = Date()
812 | difference = currentTime.time - startTime.time
813 | secondsDifference = TimeUnit.MILLISECONDS.toSeconds(difference) % 60
814 | minutesDifference = TimeUnit.MILLISECONDS.toMinutes(difference) % 60
815 | hoursDifference = TimeUnit.MILLISECONDS.toHours(difference) % 60
816 | message = "Time Elapsed: ${hoursDifference.toString().padStart(2,'0')}h: ${minutesDifference.toString().padStart(2,'0')}m: ${secondsDifference.toString().padStart(2,'0')}s"
817 | binding.timeElapsedTextView.text = message
818 | handler.postDelayed(this,1000)
819 | }
820 | else
821 | {
822 | handler.removeCallbacks(this)
823 | }
824 | }
825 | }
826 | handler.post(runnable)
827 | }
828 |
829 | private val progressAsFraction: String
830 | get() = "${progress}/${maxValue}"
831 |
832 | private val progressAsPercent: String
833 | get()
834 | {
835 | val `val` = progress.toDouble() / maxValue.toDouble() * 100
836 | return String.format(Locale.getDefault(), "%.2f", `val`) + "%"
837 | }
838 |
839 | private fun setProgressText()
840 | {
841 | when (progressViewMode)
842 | {
843 | SHOW_AS_FRACTION -> binding.progressTextView.text =
844 | progressAsFraction
845 | SHOW_AS_PERCENT -> binding.progressTextView.text =
846 | progressAsPercent
847 | HIDE_PROGRESS_TEXT -> {}
848 | }
849 | }
850 |
851 | private fun View.isVisible(): Boolean
852 | {
853 | return this.visibility == View.VISIBLE
854 | }
855 |
856 | private fun View.isGone(): Boolean
857 | {
858 | return this.visibility == View.GONE
859 | }
860 |
861 | private fun View.unhide()
862 | {
863 | this.visibility = View.VISIBLE
864 | }
865 |
866 | private fun View.hide()
867 | {
868 | this.visibility = View.GONE
869 | }
870 |
871 | private val isDeterminate: Boolean
872 | get() = mode == MODE_DETERMINATE
873 |
874 | @get:RequiresApi(api = Build.VERSION_CODES.R)
875 | private val isSystemInNightMode: Boolean
876 | get() = context.resources.configuration.isNightModeActive
877 |
878 | @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.R)
879 | private fun isAboveOrEqualToAnd11(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
880 |
881 | private fun enableNegativeButton(title: CharSequence)
882 | {
883 | binding.negativeButton.unhide()
884 | if (binding.titleView.isGone())
885 | setTitle(title)
886 | }
887 |
888 | private fun setOnDismissListenerInternal()
889 | {
890 | if(isTimeBeingTracked)
891 | {
892 | progressDialog.setOnDismissListener {
893 | if (HandlerCompat.hasCallbacks(handler, runnable))
894 | {
895 | handler.removeCallbacks(runnable)
896 | }
897 | }
898 | }
899 | else
900 | {
901 | progressDialog.setOnDismissListener(null)
902 | }
903 | }
904 |
905 | private fun setOnCancelListenerInternal()
906 | {
907 | if(isTimeBeingTracked)
908 | {
909 | progressDialog.setOnCancelListener {
910 | if(HandlerCompat.hasCallbacks(handler, runnable))
911 | {
912 | handler.removeCallbacks(runnable)
913 | }
914 | }
915 | }
916 | else
917 | {
918 | progressDialog.setOnCancelListener(null)
919 | }
920 | }
921 |
922 | private fun setThemeInternal(@ThemeConstant themeConstant: Int): Boolean
923 | {
924 | return when (themeConstant)
925 | {
926 | THEME_DARK -> {
927 | binding.dialogLayout.background = ContextCompat.getDrawable(context, R.drawable.bg_dialog_dark)
928 | binding.titleView.setTextColor(ContextCompat.getColor(context, R.color.white))
929 | binding.textViewIndeterminate.setTextColor(ContextCompat.getColor(context, R.color.white))
930 | binding.textViewDeterminate.setTextColor(ContextCompat.getColor(context, R.color.white))
931 | binding.progressTextView.setTextColor(ContextCompat.getColor(context, R.color.white_dark))
932 | binding.timeElapsedTextView.setTextColor(ContextCompat.getColor(context, R.color.white_dark))
933 | binding.negativeButton.setTextColor(ContextCompat.getColor(context, R.color.white))
934 | true
935 | }
936 | THEME_LIGHT ->
937 | {
938 | binding.dialogLayout.background = ContextCompat.getDrawable(context, R.drawable.bg_dialog)
939 | binding.titleView.setTextColor(ContextCompat.getColor(context, R.color.black))
940 | binding.textViewIndeterminate.setTextColor(ContextCompat.getColor(context, R.color.black))
941 | binding.textViewDeterminate.setTextColor(ContextCompat.getColor(context, R.color.black))
942 | binding.progressTextView.setTextColor(ContextCompat.getColor(context, R.color.black_light))
943 | binding.timeElapsedTextView.setTextColor(ContextCompat.getColor(context, R.color.black_light))
944 | binding.negativeButton.setTextColor(ContextCompat.getColor(context, R.color.black))
945 | true
946 | }
947 | else -> false
948 | }
949 | }
950 | }
--------------------------------------------------------------------------------
/progressdialoglibrary/src/main/res/drawable/bg_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/progressdialoglibrary/src/main/res/drawable/bg_dialog_dark.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/progressdialoglibrary/src/main/res/layout/layout_progressdialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
23 |
40 |
51 |
61 |
79 |
80 |
96 |
97 |
112 |
123 |
134 |
135 |
156 |
157 |
--------------------------------------------------------------------------------
/progressdialoglibrary/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #000000
4 | #FFFFFF
5 | #2C2C2C
6 | #CCCCCC
7 | @color/white
8 | @color/black_light
9 |
--------------------------------------------------------------------------------
/progressdialoglibrary/src/main/res/values/public.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/progressdialoglibrary/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Loading
3 | ProgressDialog
4 | Cancel
5 | Time Elapsed: 00h: 00m: 00s
6 |
--------------------------------------------------------------------------------
/progressdialoglibrary/src/test/java/com/techiness/progressdialoglibrary/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.techiness.progressdialoglibrary;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | include(":progressdialoglibrary")
2 | include(":app")
3 | rootProject.name = "ProgressDialogExample"
--------------------------------------------------------------------------------