Repository: Codigami/CFAlertDialog Branch: master Commit: 24af2ac48ccd Files: 79 Total size: 163.4 KB Directory structure: gitextract__vlff_a4/ ├── .github/ │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── LICENSE.md ├── README.md ├── Resources/ │ └── CFAlertDialog.sketch ├── build.gradle ├── cfalertdialog/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── crowdfire/ │ │ └── cfalertdialog/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── crowdfire/ │ │ │ └── cfalertdialog/ │ │ │ ├── CFAlertDialog.java │ │ │ ├── utils/ │ │ │ │ ├── DeviceUtil.java │ │ │ │ ├── SwipeToHideViewListener.java │ │ │ │ └── ViewUtil.java │ │ │ └── views/ │ │ │ └── CFPushButton.java │ │ └── res/ │ │ ├── anim/ │ │ │ ├── alert_dismiss.xml │ │ │ ├── alert_present.xml │ │ │ ├── dialog_dismiss_bottom.xml │ │ │ ├── dialog_dismiss_center.xml │ │ │ ├── dialog_dismiss_top.xml │ │ │ ├── dialog_present_bottom.xml │ │ │ ├── dialog_present_center.xml │ │ │ ├── dialog_present_top.xml │ │ │ ├── interpolator_acceleration_1_5.xml │ │ │ ├── interpolator_deceleration_1_5.xml │ │ │ ├── interpolator_deceleration_3.xml │ │ │ ├── interpolator_overshoot_1.xml │ │ │ └── interpolator_overshoot_1_2.xml │ │ ├── drawable/ │ │ │ ├── cfdialog_buttons_spacing.xml │ │ │ ├── cfdialog_content_spacing_horizontal.xml │ │ │ ├── cfdialog_content_spacing_vertical.xml │ │ │ ├── cfdialog_default_button_background_drawable.xml │ │ │ ├── cfdialog_negative_button_background_drawable.xml │ │ │ └── cfdialog_positive_button_background_drawable.xml │ │ ├── layout/ │ │ │ ├── cfalert_layout.xml │ │ │ ├── cfdialog_imageview_header.xml │ │ │ ├── cfdialog_multi_select_item_layout.xml │ │ │ ├── cfdialog_selectable_item_layout.xml │ │ │ ├── cfdialog_single_select_item_layout.xml │ │ │ └── cfdialog_single_select_radio_button_layout.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── dimen.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ └── values.xml │ └── test/ │ └── java/ │ └── com/ │ └── crowdfire/ │ └── cfalertdialog/ │ └── ExampleUnitTest.java ├── cfalertdialogdemo/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── crowdfire/ │ │ └── cfalertdialogdemo/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── crowdfire/ │ │ │ └── cfalertdialogdemo/ │ │ │ ├── StartActivity.java │ │ │ └── views/ │ │ │ ├── ColorSelectionView.java │ │ │ └── SampleFooterView.java │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── black_border.xml │ │ │ ├── footer_button_disabled_drawable.xml │ │ │ ├── footer_button_drawable.xml │ │ │ ├── footer_or_drawable.xml │ │ │ ├── icon_drawable.xml │ │ │ ├── image_content_drawable.xml │ │ │ └── remove_header_button_background.xml │ │ ├── layout/ │ │ │ ├── activity_start.xml │ │ │ ├── color_selection_view.xml │ │ │ ├── dialog_footer_layout.xml │ │ │ └── dialog_header_layout.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── com/ │ └── crowdfire/ │ └── cfalertdialogdemo/ │ └── ExampleUnitTest.java ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contributing to CFAlertDialog We want to make contributing to this project as easy and transparent as possible. Here are a few guidelines for making all our lives easier. ## Asking questions We don't use GitHub as a support forum. For any usage questions that are not specific to the project itself, please ask on [Stack Overflow](https://stackoverflow.com/) instead. By doing so, you'll be more likely to quickly solve your problem, and you'll allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others. ## Reporting Issues A great way to contribute to the project is to send a detailed issue when you encounter an problem. It is very important to check for the same problem or suggestion in the project's issue list first. If you find a match, just add a small comment there. Doing this helps prioritize the most common problems and requests. When reporting issues, please include the following: - The platform name and version (e.g. Android 6.0) - The library version - The integration method (e.g. gradle/manually) - The version of Android Studio you're using - The full output of any stack trace or compiler error - A small demo project that replicates the issue (especially if the way to reproduce the issue is not straight-forward) - Any other details that would be useful in understanding the problem This information will help us review and fix your issue faster. Please do not be offended if we close your issue and reference this document. If you believe the issue is truly a fault in the project’s codebase, re-open it. ## Pull Requests We gladly accept any PR's assuming they are well written, documented ( if necessary ) and preferably have test code. If you're unsure if we'll accept a new feature please open an issue requesting it and we can have a discussion before you code and submit a PR. Checklist: - Fork the repo and create your branch from the latest master (to minimize the conflicts) - If you've added code that should be tested, add tests. - If you've changed APIs, update the documentation. - Ensure the test suite passes. - Make sure your code lints ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ ### New Issue Checklist * [ ] I have read and understood the [CONTRIBUTING guide](https://github.com/Codigami/CFAlertDialog/blob/develop/.github/CONTRIBUTING.md) * [ ] I have read the [Documentation](https://github.com/Codigami/CFAlertDialog/blob/develop/README.md) * [ ] I have searched for a similar issue in the [project](https://github.com/Codigami/CFAlertDialog/issues) and found none ### Issue Info Info | Value | -------------------------------|-------------------------------------| Platform Name | e.g. Android Platform Version | e.g. 6.0 CFAlertDialog Version | e.g. 2.1.1 Integration Method | e.g. gradle / manually Xcode Version | e.g. Android Studio 2.3 Repro rate | e.g. all the time (100%) / sometimes x% / only once Repro with our demo prj | e.g. does it happen with our demo project? Demo project link | e.g. link to a demo project that highlights the issue ### Issue Description and Steps Please fill in the detailed description of the issue (full output of any stack trace, compiler error, ...) and the steps to reproduce the issue. ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ### New Pull Request Checklist * [ ] I have read and understood the [CONTRIBUTING guide](https://github.com/Codigami/CFAlertDialog/blob/develop/.github/CONTRIBUTING.md) * [ ] I have read the [Documentation](https://github.com/Codigami/CFAlertDialog/blob/develop/README.md) * [ ] I have searched for a similar pull request in the [project](https://github.com/Codigami/CFAlertDialog/pulls) and found none * [ ] I have updated this branch with the latest master to avoid conflicts (via merge from master or rebase) * [ ] I have added the required tests to prove the fix/feature I am adding * [ ] I have updated the documentation (if necessary) * [ ] I have run the tests and they pass * [ ] I have run the lint and it passes This merge request fixes / refers to the following issues: ... ### Pull Request Description ... ================================================ FILE: .gitignore ================================================ # Built application files /*/build/ /build # Crashlytics configuations com_crashlytics_export_strings.xml # Local configuration file (sdk path, etc) local.properties # Gradle generated files .gradle/ .gradle # Signing files .signing/ # User-specific configurations .idea/libraries/ .idea/workspace.xml .idea/tasks.xml .idea/.name .idea/compiler.xml .idea/copyright/profiles_settings.xml .idea/encodings.xml .idea/misc.xml .idea/modules.xml .idea/scopes/scope_settings.xml .idea/vcs.xml *.iml # OS-specific files .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes ehthumbs.db Thumbs.db /.idea /examples/examples.iml /library/library.iml examples/examples.iml library/library.iml build/generated/mockable-android-25.jar local.properties bintray.properties ================================================ FILE: LICENSE.md ================================================ The MIT License (MIT) Copyright (c) 2017 Codigami Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # CFAlertDialog ![Android](/Resources/android_medium.png) [![Bintray](https://img.shields.io/bintray/v/crowdfire/releases/cfalertdialog.svg?maxAge=2592000)](https://bintray.com/crowdfire/cfalertdialog/cfalertdialog) [ ![Download](https://api.bintray.com/packages/crowdfire/cfalertdialog/cfalertdialog/images/download.svg) ](https://bintray.com/crowdfire/cfalertdialog/cfalertdialog/_latestVersion) [![Github All Releases](https://img.shields.io/github/downloads/codigami/cfalertdialog/total.svg)]() [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-CFAlertDialog-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/6252) [![license](https://img.shields.io/github/license/codigami/cfalertdialog.svg)]() [![Twitter URL](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/home?status=CFAlertDialog%20-%20Now%20display%20and%20customise%20dialogs%20on%20android%20like%20never%20before!%20%23OpenSource%20https%3A//github.com/Codigami/CFAlertDialog) `CFAlertDialog` is a library that helps you display and customise **alert dialogs** on Android. It offers an adaptive UI support. It’s functionality is almost similar to the native `AlertDialog`. You can also check out this library for ** iOS** [here](https://github.com/Codigami/CFAlertViewController) #### Types of use cases: #### Configuration options: ## Requirements : - CFAlertDialog works on any device with Android API level 14 and above. ### Install using gradle In your project's build.gradle add the following under dependencies ```java compile 'com.crowdfire.cfalertdialog:cfalertdialog:1.1.0' ``` ## Usage :

The above shown alert types can easily be implemented using the code snippet given below by some small tweaks ```android // Create Alert using Builder CFAlertDialog.Builder builder = new CFAlertDialog.Builder(this) .setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT) .setTitle("You've hit the limit") .setMessage("Looks like you've hit your usage limit. Upgrade to our paid plan to continue without any limits.") .addButton("UPGRADE", -1, -1, CFAlertActionStyle.POSITIVE, CFAlertActionAlignment.END, (dialog, which) -> { Toast.makeText(BaseActivity.this, "Upgrade tapped", Toast.LENGTH_SHORT).show(); dialog.dismiss(); }) // Show the alert builder.show(); ``` ## Customisations : ##### Alert Type The alert type will determine the position and animation style for the dialog. You may set this by calling the `setAlertStyle` method with any of the following values. ```java CFAlertStyle.NOTIFICATION, CFAlertStyle.ALERT, CFAlertStyle.BOTTOM_SHEET ``` The default type is `ALERT`. ##### Title and Message You can set a custom title and message text in the alert, using the `setTitle` method on the builder (pass `null` if you don’t need them). ##### Title Color and Message Color You can set a custom title and message text color in the alert, using the `setTextColor` on the builder. ##### Text Alignment You can customise alignment of the title and message. Use the `setTextGravity` method on the builder with any of the following values: ```java Gravity.START, Gravity.CENTER_HORIZONTAL, Gravity.END ``` ##### Background color You can change the background (overlay) color of the alert using the method `setBackgroundColor` on the builder with the color of your choice. ##### Dismiss on background tap This determines whether the Alert dialog is dismissed when user taps on the background. Use the method `setCancelable` with a boolean value. By default it is set to true. The user will be able to interactively swipe to dismiss the notification dialog if this field is true. ##### Dismiss automatically The alert dialog can be dismissed automatically using the method `setAutoDismissAfter(long duration)`. ##### Header / Footer You can add header and footer to the dialog. Use the method `setHeaderView` and `setFooterView` with any custom View. You can also pass the layout resource directly into the header/footer. Pass `null` to remove any existing header/footer. 1) Some examples where you can make the use of header in alert (the dollar image is in header)

```java builder.setHeaderView(R.layout.dialog_header_layout); OR builder.setHeaderView(headerView); ``` 2) Some examples where you can make the use of footer in alert

```java builder.setFooterView(R.layout.dialog_footer_layout); OR builder.setFooterView(footerView); ``` ##### Dismiss Callback You may set a callback when dialog is dismissed with the native `setOnDismissListener` on the alert object. ```java CFAlertDialog alertDialog = builder.show(); alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { // Do something here when dialog dismissed. } }); ``` ### Action Buttons You may add as many action buttons with the required styles. Use the `addButton` method on the builder. ```java builder.addButton("UPGRADE", Color.parseColor("#FFFFFF"), Color.parseColor("#429ef4"), CFAlertActionStyle.POSITIVE, CFAlertActionAlignment.CENTER, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(context, "Upgrade tapped", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }); ``` ##### Title You can set the title of action button to be added. ##### Action Style Configure the style of the action button that is to be added to alert view. Set `style` property of the above method with one of the following Action style ```java CFAlertActionStyle.DEFAULT, CFAlertActionStyle.POSITIVE, CFAlertActionStyle.NEGATIVE ``` ###### Actions Alignment Configure the alignment of the action button added to the alert view. Set `alignment` property of CFAction constructor with one of the following action types ```java CFAlertActionAlignment.START, CFAlertActionAlignment.END, CFAlertActionAlignment.CENTER, CFAlertActionAlignment.JUSTIFIED // Action Button occupies the full width ``` ##### Callback Pass an `onClickListener` to receive callbacks when the action buttons are tapped. ### Items There are 3 types of list supported by default.

##### Simple List This will show a simple list view and give a callback when any of the item is tapped. ```java CFAlertDialog.Builder builder = new CFAlertDialog.Builder(this); builder.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT); builder.setTitle("Select notification tone!"); builder.setItems(new String[]{"None", "Alert", "Delight", "Guitar", "Marbles", "Prompt"}, new OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int index) { Toast.makeText(context, "Selected:"+index, Toast.LENGTH_SHORT).show(); dialogInterface.dismiss(); } }); builder.show(); ``` ##### Single Choice This will show a list view with single choice items. It will give a callback when any of the items is selected. ```java CFAlertDialog.Builder builder = new CFAlertDialog.Builder(this); builder.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT); builder.setTitle("Select notification tone!"); builder.setSingleChoiceItems(new String[]{"None", "Alert", "Delight", "Guitar", "Marbles", "Prompt"}, 3, new OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int index) { Toast.makeText(context, "Selected:"+index, Toast.LENGTH_SHORT).show(); } }); builder.addButton("DONE", -1, -1, CFAlertActionStyle.POSITIVE, CFAlertActionAlignment.END, new OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }); builder.show(); ``` ##### Multiple choice This will show a list view with multi choice items. It will give a callback when any item is selected/unselected. ```java CFAlertDialog.Builder builder = new CFAlertDialog.Builder(this); builder.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT); builder.setMessage("Select the topping for your pizza!!!"); builder.setMultiChoiceItems(new String[]{"Spinach", "Red & Yellow pepper", "Baby corn", "Olives", "Chicken"}, new boolean[]{false, false, false, false, false}, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialogInterface, int index, boolean b) { Toast.makeText(context, "Row:"+index+" "+(b? "Selected":"Unselected"), Toast.LENGTH_SHORT).show(); } }); builder.addButton("NEXT", -1, -1, CFAlertActionStyle.POSITIVE, CFAlertActionAlignment.END, new OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }); builder.show(); ``` ## License This code is distributed under the terms and conditions of the MIT license. ================================================ FILE: build.gradle ================================================ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() maven { url "https://maven.google.com" } google() } dependencies { classpath 'com.android.tools.build:gradle:3.3.2' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() google() } } ================================================ FILE: cfalertdialog/.gitignore ================================================ /build ================================================ FILE: cfalertdialog/build.gradle ================================================ apply plugin: 'com.android.library' apply plugin: 'maven-publish' apply plugin: 'com.jfrog.bintray' apply plugin: 'com.github.dcendents.android-maven' buildscript { repositories { jcenter() maven { url "https://maven.google.com" } google() } dependencies { classpath 'com.android.tools.build:gradle:3.3.2' } } // Variables int libraryVersionCode = 12 String libraryVersion = '1.3.1' String libraryGroup = 'com.crowdfire.cfalertdialog' String gitUrl = 'https://github.com/Codigami/CFAlertDialog.git' String siteUrl = 'https://github.com/Codigami/CFAlertDialog' // Android settings android { compileSdkVersion 28 buildToolsVersion '28.0.3' defaultConfig { minSdkVersion 14 targetSdkVersion 28 versionCode libraryVersionCode versionName libraryVersion testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } // Dependancies dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) androidTestImplementation('androidx.test.espresso:espresso-core:3.1.1-alpha01', { exclude group: 'com.android.support', module: 'support-annotations' }) implementation 'androidx.appcompat:appcompat:1.1.0-alpha04' implementation 'androidx.cardview:cardview:1.0.0' testImplementation 'junit:junit:4.12' } // Local properties Properties properties = new Properties() properties.load(project.rootProject.file('bintray.properties').newDataInputStream()) group = libraryGroup version = libraryVersion // Bintray upload tasks task sourcesJar(type: Jar) { from android.sourceSets.main.java.srcDirs classifier = 'sources' } task javadoc(type: Javadoc) { source = android.sourceSets.main.java.srcDirs classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from javadoc.destinationDir } artifacts { archives javadocJar archives sourcesJar } bintray { user = properties.getProperty("bintray.user") key = properties.getProperty("bintray.apikey") configurations = ['archives'] pkg { repo = 'cfalertdialog' name = 'cfalertdialog' userOrg = 'crowdfire' licenses = ['Apache-2.0'] vcsUrl = gitUrl publish = true version{ name = libraryVersion desc = 'Development release v0.9' released = new Date() vcsTag = libraryVersion gpg { sign = true passphrase = properties.getProperty("bintray.gpg.password") } } } } install { repositories.mavenInstaller { // This generates POM.xml with proper parameters pom { project { packaging 'aar' groupId libraryGroup artifactId 'cfalertdialog' name 'CFAlertDialog' description 'A customisable alert dialog for Android' url siteUrl developers { developer { id properties.getProperty("bintray.developer.id") name properties.getProperty("bintray.developer.name") } } scm { url siteUrl connection gitUrl developerConnection gitUrl } licenses { license { name 'Apache-2.0' url 'http://www.apache.org/licenses/LICENSE-2.0.txt' distribution 'repo' } } } } } } ================================================ FILE: cfalertdialog/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/rahul/Android/SDK/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: cfalertdialog/src/androidTest/java/com/crowdfire/cfalertdialog/ExampleInstrumentedTest.java ================================================ package com.crowdfire.cfalertdialog; import android.content.Context; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Instrumentation test, which will execute on an Android device. * * @see Testing documentation */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("com.crowdfire.cfalertdialog.test", appContext.getPackageName()); } } ================================================ FILE: cfalertdialog/src/main/AndroidManifest.xml ================================================ ================================================ FILE: cfalertdialog/src/main/java/com/crowdfire/cfalertdialog/CFAlertDialog.java ================================================ package com.crowdfire.cfalertdialog; import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; import android.content.Context; import android.content.DialogInterface; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.os.Bundle; import android.os.Handler; import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; import androidx.annotation.LayoutRes; import androidx.annotation.StringRes; import androidx.annotation.StyleRes; import androidx.core.content.ContextCompat; import androidx.core.content.res.ResourcesCompat; import androidx.core.view.ViewCompat; import androidx.appcompat.app.AppCompatDialog; import androidx.cardview.widget.CardView; import android.text.TextUtils; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import com.crowdfire.cfalertdialog.utils.DeviceUtil; import com.crowdfire.cfalertdialog.utils.SwipeToHideViewListener; import com.crowdfire.cfalertdialog.views.CFPushButton; import java.util.ArrayList; import java.util.List; public class CFAlertDialog extends AppCompatDialog { // region Enums public enum CFAlertStyle { NOTIFICATION, ALERT, BOTTOM_SHEET } public enum CFAlertActionStyle{ DEFAULT, NEGATIVE, POSITIVE } public enum CFAlertActionAlignment { START, END, CENTER, JUSTIFIED } // endregion // region Properties private int style = -1; private DialogParams params; private RelativeLayout cfDialogBackground, cfDialogContainer; private LinearLayout cfDialogHeaderLinearLayout, cfDialogBodyContainer, buttonContainerLinearLayout, cfDialogFooterLinearLayout, iconTitleContainer, selectableItemsContainer; private CardView dialogCardView; private TextView dialogTitleTextView, dialogMessageTextView; private ImageView cfDialogIconImageView; private ScrollView cfDialogScrollView; // endregion // region Setup methods private CFAlertDialog(Context context) { super(context, R.style.CFDialog); } private CFAlertDialog(Context context, int theme) { super(context, theme); style = theme; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Inflate the view LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = layoutInflater.inflate(R.layout.cfalert_layout, null); supportRequestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(view); // Setup the dialog setupSubviews(view); // Set the size to adjust when keyboard shown getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); // Disable the view initially setEnabled(false); } private void setupSubviews(View view) { cfDialogBackground = ((RelativeLayout) view.findViewById(R.id.cfdialog_background)); setupBackground(); cfDialogContainer = (RelativeLayout) view.findViewById(R.id.cfdialog_container); // Card setup createCardView(); } private void setupBackground() { // Background getWindow().setBackgroundDrawableResource(android.R.color.transparent); cfDialogBackground.setBackgroundColor(params.backgroundColor); cfDialogBackground.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (params.cancelable) { dismiss(); } } }); // Dialog position adjustBackgroundGravity(); } private void createCardView() { dialogCardView = (CardView) findViewById(R.id.cfdialog_cardview); bindCardSubviews(); cfDialogScrollView.setBackgroundColor(params.dialogBackgroundColor); // Adjust the dialog width adjustDialogLayoutParams(); populateCardView(); setupCardBehaviour(); } private void bindCardSubviews() { cfDialogScrollView = dialogCardView.findViewById(R.id.cfdialog_scrollview); cfDialogBodyContainer = dialogCardView.findViewById(R.id.alert_body_container); cfDialogHeaderLinearLayout = dialogCardView.findViewById(R.id.alert_header_container); cfDialogHeaderLinearLayout.requestLayout(); cfDialogHeaderLinearLayout.setVisibility(View.GONE); dialogTitleTextView = dialogCardView.findViewById(R.id.tv_dialog_title); iconTitleContainer = dialogCardView.findViewById(R.id.icon_title_container); cfDialogIconImageView = dialogCardView.findViewById(R.id.cfdialog_icon_imageview); dialogMessageTextView = dialogCardView.findViewById(R.id.tv_dialog_content_desc); buttonContainerLinearLayout = dialogCardView.findViewById(R.id.alert_buttons_container); cfDialogFooterLinearLayout = dialogCardView.findViewById(R.id.alert_footer_container); selectableItemsContainer = dialogCardView.findViewById(R.id.alert_selection_items_container); } private void populateCardView() { // Icon if (params.iconDrawableId != -1) { setIcon(params.iconDrawableId); } else if (params.iconDrawable != null) { setIcon(params.iconDrawable); } else { setIcon(null); } // Title setTitle(params.title); // Message setMessage(params.message); // Text color if (params.textColor != -1) { setTitleColor(params.textColor); setMessageColor(params.textColor); } // Cancel setCancelable(params.cancelable); // Buttons populateButtons(params.context, params.buttons); // Text gravity setTextGravity(params.textGravity); // Selection items if (params.items != null && params.items.length > 0) { setItems(params.items, params.onItemClickListener); } else if (params.multiSelectItems != null && params.multiSelectItems.length > 0) { setMultiSelectItems(params.multiSelectItems, params.multiSelectedItems, params.onMultiChoiceClickListener); } else if (params.singleSelectItems != null && params.singleSelectItems.length > 0) { setSingleSelectItems(params.singleSelectItems, params.singleSelectedItem, params.onSingleItemClickListener); } else { selectableItemsContainer.removeAllViews(); } // Hide Body container if there is no content in the body if (params.isDialogBodyEmpty()) { cfDialogBodyContainer.setVisibility(View.GONE); } // Image/Header if (params.contentImageDrawableId != -1) { setContentImageDrawable(params.contentImageDrawableId); } else if (params.contentImageDrawable != null) { setContentImageDrawable(params.contentImageDrawable); } else if (params.headerView != null) { setHeaderView(params.headerView); } else if (params.headerViewId != -1) { setHeaderView(params.headerViewId); } // Footer if (params.footerView != null) { setFooterView(params.footerView); } else if (params.footerViewId != -1) { setFooterView(params.footerViewId); } } private void setupCardBehaviour() { // Style specific behaviour switch (params.dialogStyle) { case NOTIFICATION: // Swipe to dismiss feature for notification type alerts SwipeToHideViewListener cardSwipeListener = new SwipeToHideViewListener(dialogCardView, params.cancelable, new SwipeToHideViewListener.SwipeToHideCompletionListener() { @Override public void viewDismissed() { CFAlertDialog.super.dismiss(); } }); cfDialogScrollView.setOnTouchListener(cardSwipeListener); break; case ALERT: // Behaviour specific to Alerts break; case BOTTOM_SHEET: // Behaviour specific to Bottom sheets break; } } // endregion @Override public void show() { super.show(); // Perform the present animation startPresentAnimation(); } @Override public void dismiss() { // Disable the view when being dismissed setEnabled(false); // perform the dismiss animation startDismissAnimation(); } private void alertPresented() { setEnabled(true); // Auto dismiss if needed if (params.autoDismissDuration > 0) { Handler handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { dismiss(); } }; handler.postDelayed(runnable, params.autoDismissDuration); } } // region - Setters private void setDialogParams(DialogParams params) { this.params = params; } private void setEnabled(boolean enabled) { setViewEnabled(cfDialogBackground, enabled); } public void setBackgroundColor(int color, boolean animated){ if (animated) { int colorFrom = ((ColorDrawable)cfDialogBackground.getBackground()).getColor(); ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, color); colorAnimation.setDuration(getContext().getResources().getInteger(R.integer.cfdialog_animation_duration)); // milliseconds colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { cfDialogBackground.setBackgroundColor((int) animator.getAnimatedValue()); } }); colorAnimation.start(); } else { cfDialogBackground.setBackgroundColor(color); } } public void setDialogBackgroundColor(int color, boolean animated) { if (animated) { int colorFrom = ((ColorDrawable)dialogCardView.getBackground()).getColor(); ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, color); colorAnimation.setDuration(getContext().getResources().getInteger(R.integer.cfdialog_animation_duration)); // milliseconds colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { dialogCardView.setBackgroundColor((int) animator.getAnimatedValue()); } }); colorAnimation.start(); } else { cfDialogScrollView.setBackgroundColor(color); } } public void setCornerRadius(float radius) { this.params.dialogCornerRadius = radius; dialogCardView.setRadius(getCornerRadius()); } public void setOuterMargin(int margin) { this.params.dialogOuterMargin = margin; adjustDialogLayoutParams(); } @Override public void setTitle(CharSequence title) { if (TextUtils.isEmpty(title)) { dialogTitleTextView.setVisibility(View.GONE); if (cfDialogIconImageView.getVisibility() == View.GONE) { iconTitleContainer.setVisibility(View.GONE); } } else { dialogTitleTextView.setText(title); dialogTitleTextView.setVisibility(View.VISIBLE); iconTitleContainer.setVisibility(View.VISIBLE); } } @Override public void setTitle(int titleId) { setTitle(getContext().getString(titleId)); } public void setTitleColor (@ColorInt int color) { dialogTitleTextView.setTextColor(color); } public void setMessage(CharSequence message) { if (TextUtils.isEmpty(message)) { dialogMessageTextView.setVisibility(View.GONE); } else { dialogMessageTextView.setText(message); dialogMessageTextView.setVisibility(View.VISIBLE); } } public void setMessage(int messageId) { setMessage(getContext().getString(messageId)); } public void setMessageColor(@ColorInt int color) { dialogMessageTextView.setTextColor(color); } /** * @param dialogStyle */ public void setDialogStyle(CFAlertStyle dialogStyle) { params.dialogStyle = dialogStyle; adjustBackgroundGravity(); adjustDialogLayoutParams(); } /** * @param textGravity @see android.view.Gravity */ public void setTextGravity(int textGravity) { ((LinearLayout.LayoutParams) iconTitleContainer.getLayoutParams()).gravity = textGravity; dialogMessageTextView.setGravity(textGravity); } /** * @param headerView pass null to remove header */ public void setHeaderView(View headerView) { cfDialogHeaderLinearLayout.removeAllViews(); if (headerView != null) { cfDialogHeaderLinearLayout.setVisibility(View.VISIBLE); cfDialogHeaderLinearLayout.addView(headerView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); // Allows the header view to overlap the alert content if needed disableClipOnParents(headerView); } else { cfDialogHeaderLinearLayout.setVisibility(View.GONE); } } public void setHeaderView(@LayoutRes int headerResId) { LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = layoutInflater.inflate(headerResId, null); setHeaderView(view); } public void setIcon(@DrawableRes int iconDrawableId) { setIcon(ContextCompat.getDrawable(getContext(), iconDrawableId)); } public void setIcon(Drawable iconDrawable) { if (iconDrawable == null) { cfDialogIconImageView.setVisibility(View.GONE); if (dialogTitleTextView.getVisibility() == View.GONE) { iconTitleContainer.setVisibility(View.GONE); } } else { cfDialogIconImageView.setVisibility(View.VISIBLE); iconTitleContainer.setVisibility(View.VISIBLE); cfDialogIconImageView.setImageDrawable(iconDrawable); } } /** * @param imageDrawableId value -1 will remove image */ public void setContentImageDrawable(@DrawableRes int imageDrawableId) { setContentImageDrawable(ContextCompat.getDrawable(getContext(), imageDrawableId)); } public void setContentImageDrawable(Drawable imageDrawable) { if (imageDrawable != null) { LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); ImageView imageView = (ImageView) layoutInflater.inflate(R.layout.cfdialog_imageview_header, cfDialogHeaderLinearLayout).findViewById(R.id.cfdialog_imageview_content); imageView.setImageDrawable(imageDrawable); imageView.setTag(111); cfDialogHeaderLinearLayout.setVisibility(View.VISIBLE); } else { for (int i = 0; i < cfDialogHeaderLinearLayout.getChildCount(); i++) { View view = cfDialogHeaderLinearLayout.getChildAt(i); if (view instanceof ImageView && (int) view.getTag() == 111) { cfDialogHeaderLinearLayout.removeView(view); cfDialogHeaderLinearLayout.setVisibility(View.GONE); break; } } } } /** * @param footerView pass null to remove footer */ public void setFooterView(View footerView) { cfDialogFooterLinearLayout.removeAllViews(); if (footerView != null) { cfDialogFooterLinearLayout.addView(footerView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); cfDialogFooterLinearLayout.setVisibility(View.VISIBLE); // Allows the footer view to overlap the alert content if needed disableClipOnParents(footerView); } else { cfDialogFooterLinearLayout.setVisibility(View.GONE); } } public void setFooterView(@LayoutRes int footerResId) { LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = layoutInflater.inflate(footerResId, null); setFooterView(view); } private void setViewEnabled(ViewGroup layout, boolean enabled) { layout.setEnabled(enabled); for (int i = 0; i < layout.getChildCount(); i++) { View child = layout.getChildAt(i); if (child instanceof ViewGroup) { setViewEnabled((ViewGroup) child, enabled); } else { child.setEnabled(enabled); } } } private void disableClipOnParents(View v) { if (v.getParent() == null) { return; } if (v instanceof ViewGroup) { ((ViewGroup) v).setClipChildren(false); } if (v.getParent() instanceof View) { disableClipOnParents((View) v.getParent()); } } private void populateButtons(Context context, List buttons) { buttonContainerLinearLayout.removeAllViews(); if (buttons.size() > 0) { for (int i = 0; i < buttons.size(); i++) { View buttonView = createButton(context, buttons.get(i)); buttonContainerLinearLayout.addView(buttonView); } buttonContainerLinearLayout.setVisibility(View.VISIBLE); } else { buttonContainerLinearLayout.setVisibility(View.GONE); } } private View createButton(Context context, final CFAlertActionButton actionButton) { CFPushButton button = new CFPushButton(context, null, style != -1 ? style : R.style.CFDialog_Button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { actionButton.onClickListener.onClick(CFAlertDialog.this, 0); } }); setButtonLayout(button, actionButton); button.setText(actionButton.buttonText); setButtonColors(button, actionButton); return button; } private void setButtonLayout(View buttonView, CFAlertActionButton actionButton) { LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ; switch (actionButton.alignment) { case JUSTIFIED: buttonParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); break; case START: buttonParams.gravity = Gravity.START; break; case CENTER: buttonParams.gravity = Gravity.CENTER; break; case END: buttonParams.gravity = Gravity.END; break; } buttonView.setLayoutParams(buttonParams); int padding = ((int) buttonView.getResources().getDimension(R.dimen.cfdialog_button_padding)); buttonView.setPadding(padding, padding, padding, padding); } private void setButtonColors(CFPushButton button, CFAlertActionButton actionButton) { //Button background color if (actionButton.backgroundColor != -1) { GradientDrawable buttonDrawable = new GradientDrawable(); buttonDrawable.setColor(actionButton.backgroundColor); buttonDrawable.setCornerRadius(getContext().getResources().getDimension(R.dimen.cfdialog_button_corner_radius)); ViewCompat.setBackground(button, buttonDrawable); } else if (actionButton.backgroundDrawableId != -1) { ViewCompat.setBackground(button, ContextCompat.getDrawable(getContext(), actionButton.backgroundDrawableId)); } // Button text colors button.setTextColor(actionButton.textColor); } public void setItems(String[] items, final OnClickListener onClickListener) { if (items != null && items.length > 0) { selectableItemsContainer.removeAllViews(); selectableItemsContainer.setVisibility(View.VISIBLE); for (int i = 0; i < items.length; i++) { String item = items[i]; View view = getLayoutInflater().inflate(R.layout.cfdialog_selectable_item_layout, null); TextView itemTextView = (TextView) view.findViewById(R.id.cfdialog_selectable_item_textview); itemTextView.setText(item); final int position = i; view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onClickListener != null) { onClickListener.onClick(CFAlertDialog.this, position); } } }); selectableItemsContainer.addView(view); } } else { selectableItemsContainer.setVisibility(View.GONE); } } public void setMultiSelectItems(String[] multiSelectItems, boolean[] selectedItems, final OnMultiChoiceClickListener onMultiChoiceClickListener) { if (multiSelectItems != null && multiSelectItems.length > 0) { if (selectedItems.length != multiSelectItems.length) { throw new IllegalArgumentException("multi select items and boolean array size not equal"); } selectableItemsContainer.removeAllViews(); selectableItemsContainer.setVisibility(View.VISIBLE); for (int i = 0; i < multiSelectItems.length; i++) { String item = multiSelectItems[i]; View view = getLayoutInflater().inflate(R.layout.cfdialog_multi_select_item_layout, null); CheckBox checkBox = (CheckBox) view.findViewById(R.id.cfdialog_multi_select_item_checkbox); checkBox.setText(item); checkBox.setChecked(selectedItems[i]); final int position = i; checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (onMultiChoiceClickListener != null) { onMultiChoiceClickListener.onClick(CFAlertDialog.this, position, isChecked); } } }); selectableItemsContainer.addView(view); } } else { selectableItemsContainer.setVisibility(View.GONE); } } public void setSingleSelectItems(String[] singleSelectItems, int selectedItem, final OnClickListener onClickListener) { if (singleSelectItems != null && singleSelectItems.length > 0) { selectableItemsContainer.removeAllViews(); selectableItemsContainer.setVisibility(View.VISIBLE); RadioGroup radioGroup = (RadioGroup) getLayoutInflater().inflate(R.layout.cfdialog_single_select_item_layout, selectableItemsContainer) .findViewById(R.id.cfstage_single_select_radio_group); radioGroup.removeAllViews(); for (int i = 0; i < singleSelectItems.length; i++) { String item = singleSelectItems[i]; RadioButton radioButton = (RadioButton) getLayoutInflater().inflate(R.layout.cfdialog_single_select_radio_button_layout, null); radioButton.setText(item); radioButton.setId(i); final int position = i; if (position == selectedItem) { radioButton.setChecked(true); } radioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked && onClickListener != null) { onClickListener.onClick(CFAlertDialog.this, position); } } }); radioGroup.addView(radioButton); } } else { selectableItemsContainer.setVisibility(View.GONE); } } public void setElevation(float elevation) { dialogCardView.setCardElevation(elevation); } // endregion @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); //cfDialogFooterLinearLayout.removeAllViews(); //cfDialogHeaderLinearLayout.removeAllViews(); } // region Animation helper methods private void startPresentAnimation() { Animation presentAnimation = getPresentAnimation(params.dialogStyle); presentAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { alertPresented(); } @Override public void onAnimationRepeat(Animation animation) { } }); dialogCardView.startAnimation(presentAnimation); } private void startDismissAnimation() { // Perform the dismiss animation and after that dismiss the dialog Animation dismissAnimation = getDismissAnimation(params.dialogStyle); dismissAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { Handler handler = new Handler(); handler.post(new Runnable() { @Override public void run() { CFAlertDialog.super.dismiss(); } }); } @Override public void onAnimationRepeat(Animation animation) { } }); dialogCardView.startAnimation(dismissAnimation); } private Animation getPresentAnimation(CFAlertStyle style) { switch (style) { case NOTIFICATION: return AnimationUtils.loadAnimation(params.context, R.anim.dialog_present_top); case ALERT: return AnimationUtils.loadAnimation(params.context, R.anim.dialog_present_center); case BOTTOM_SHEET: return AnimationUtils.loadAnimation(params.context, R.anim.dialog_present_bottom); default: return AnimationUtils.loadAnimation(params.context, R.anim.dialog_present_center); } } private Animation getDismissAnimation(CFAlertStyle style) { switch (style) { case NOTIFICATION: return AnimationUtils.loadAnimation(params.context, R.anim.dialog_dismiss_top); case ALERT: return AnimationUtils.loadAnimation(params.context, R.anim.dialog_dismiss_center); case BOTTOM_SHEET: return AnimationUtils.loadAnimation(params.context, R.anim.dialog_dismiss_bottom); default: return AnimationUtils.loadAnimation(params.context, R.anim.dialog_dismiss_center); } } // endregion // region Layout helper methods private void adjustBackgroundGravity() { switch (params.dialogStyle) { case NOTIFICATION: cfDialogBackground.setGravity(Gravity.TOP); break; case ALERT: cfDialogBackground.setGravity(Gravity.CENTER_VERTICAL); break; case BOTTOM_SHEET: cfDialogBackground.setGravity(Gravity.BOTTOM); break; } } private void adjustDialogLayoutParams() { // Corner radius dialogCardView.setRadius(getCornerRadius()); // Layout params RelativeLayout.LayoutParams cardContainerLayoutParams = (RelativeLayout.LayoutParams) cfDialogContainer.getLayoutParams(); int margin = getOuterMargin(); int horizontalMargin = margin; int topMargin = margin; int bottomMargin = margin; int maxWidth = (int) getContext().getResources().getDimension(R.dimen.cfdialog_maxwidth); int screenWidth = DeviceUtil.getScreenWidth(getContext()); // Special layout properties to be added here. switch (params.dialogStyle) { case NOTIFICATION: horizontalMargin = 0; topMargin = 0; maxWidth = screenWidth; break; } if (isCustomMargin()) { maxWidth = screenWidth; // Dialog can extend till the max screen width if custom margin is provided } int width = screenWidth - (2 * horizontalMargin); width = Math.min(width, maxWidth); cardContainerLayoutParams.width = width; cardContainerLayoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); cardContainerLayoutParams.setMargins(horizontalMargin, topMargin, horizontalMargin, bottomMargin); cfDialogContainer.setLayoutParams(cardContainerLayoutParams); } private float getCornerRadius(){ float cornerRadius = getContext().getResources().getDimension(R.dimen.cfdialog_card_corner_radius); // Special layout properties to be added here. switch (params.dialogStyle) { case NOTIFICATION: cornerRadius = 0; break; } // Use the corner radius from params if provided. if (params.dialogCornerRadius != -1) { cornerRadius = params.dialogCornerRadius; } return cornerRadius; } private int getOuterMargin() { int margin = (int)getContext().getResources().getDimension(R.dimen.cfdialog_outer_margin); if (params.dialogOuterMargin != -1) { margin = params.dialogOuterMargin; } return margin; } private boolean isCustomMargin() { return params.dialogOuterMargin != -1; } // endregion public static class Builder { private DialogParams params; public Builder(Context context) { params = new DialogParams(); this.params.context = context; } public Builder(Context context, @StyleRes int theme) { params = new DialogParams(); this.params.context = context; this.params.theme = theme; } public Builder setBackgroundResource(@ColorRes int backgroundResource) { this.params.backgroundColor = ResourcesCompat.getColor(this.params.context.getResources(), backgroundResource, null); return this; } public Builder setBackgroundColor(@ColorInt int backgroundColor) { this.params.backgroundColor = backgroundColor; return this; } public Builder setDialogBackgroundResource(@ColorRes int backgroundResource) { this.params.dialogBackgroundColor = ResourcesCompat.getColor(this.params.context.getResources(), backgroundResource, null); return this; } public Builder setDialogBackgroundColor(@ColorInt int backgroundColor) { this.params.dialogBackgroundColor = backgroundColor; return this; } public Builder setCornerRadius(float cornerRadius) { this.params.dialogCornerRadius = cornerRadius; return this; } public Builder setOuterMargin(int margin) { this.params.dialogOuterMargin = margin; return this; } public Builder setMessage(CharSequence message) { this.params.message = message; return this; } public Builder setTitle(CharSequence title) { this.params.title = title; return this; } public Builder setMessage(@StringRes int messageId) { this.params.message = params.context.getString(messageId); return this; } public Builder setTitle(@StringRes int titleId) { this.params.title = params.context.getString(titleId); return this; } public Builder setTextColor(@ColorInt int color) { this.params.textColor = color; return this; } public Builder setContentImageDrawable(@DrawableRes int contentImageDrawableId) { this.params.contentImageDrawableId = contentImageDrawableId; this.params.contentImageDrawable = null; return this; } public Builder setContentImageDrawable(Drawable contentImageDrawable) { this.params.contentImageDrawable = contentImageDrawable; this.params.contentImageDrawableId = -1; return this; } public Builder setIcon(@DrawableRes int iconDrawableId) { this.params.iconDrawableId = iconDrawableId; this.params.iconDrawable = null; return this; } public Builder setIcon(Drawable iconDrawable) { this.params.iconDrawable = iconDrawable; this.params.iconDrawableId = -1; return this; } public Builder onDismissListener(OnDismissListener onDismissListener) { this.params.onDismissListener = onDismissListener; return this; } public Builder setDialogStyle(CFAlertStyle style) { this.params.dialogStyle = style; return this; } /** * @param textGravity @see android.view.Gravity */ public Builder setTextGravity(int textGravity) { this.params.textGravity = textGravity; return this; } public Builder addButton(String buttonText, @ColorInt int textColor, @ColorInt int backgroundColor, CFAlertActionStyle style, CFAlertActionAlignment alignment, OnClickListener onClickListener) { CFAlertActionButton button = new CFAlertActionButton(this.params.context, buttonText, textColor, backgroundColor, style, alignment, onClickListener); this.params.buttons.add(button); return this; } public Builder setItems(String[] items, OnClickListener onItemClickListener) { params.items = items; params.onItemClickListener = onItemClickListener; return this; } public Builder setMultiChoiceItems(String[] items, boolean[] selectedItems, OnMultiChoiceClickListener onMultiChoiceClickListener) { params.multiSelectItems = items; params.multiSelectedItems = selectedItems; params.onMultiChoiceClickListener = onMultiChoiceClickListener; return this; } public Builder setSingleChoiceItems(String[] items, int selectedItem, OnClickListener onItemClickListener) { params.singleSelectItems = items; params.singleSelectedItem = selectedItem; params.onSingleItemClickListener = onItemClickListener; return this; } public Builder setHeaderView(View headerView) { this.params.headerView = headerView; this.params.headerViewId = -1; return this; } public Builder setHeaderView(@LayoutRes int headerViewId) { this.params.headerViewId = headerViewId; this.params.headerView = null; return this; } public Builder setFooterView(View footerView) { this.params.footerView = footerView; this.params.footerViewId = -1; return this; } public Builder setFooterView(@LayoutRes int footerViewId) { this.params.footerViewId = footerViewId; this.params.footerView = null; return this; } /** * default is true * * @param cancelable */ public Builder setCancelable(boolean cancelable) { this.params.cancelable = cancelable; return this; } public Builder setAutoDismissAfter(long duration) { this.params.autoDismissDuration = duration; return this; } public CFAlertDialog create() { CFAlertDialog cfAlertDialog; if (params.theme == 0) { cfAlertDialog = new CFAlertDialog(params.context); } else { cfAlertDialog = new CFAlertDialog(params.context, params.theme); } cfAlertDialog.setOnDismissListener(params.onDismissListener); cfAlertDialog.setDialogParams(params); return cfAlertDialog; } public CFAlertDialog show() { final CFAlertDialog dialog = create(); dialog.show(); return dialog; } } private static class DialogParams { private Context context; private @ColorInt int backgroundColor = Color.parseColor("#B3000000"); private @ColorInt int dialogBackgroundColor = Color.parseColor("#FFFFFF"); private float dialogCornerRadius = -1; private int dialogOuterMargin = -1; private CharSequence message, title; private @ColorInt int textColor = -1; private int theme = R.style.CFDialog, textGravity = Gravity.LEFT, iconDrawableId = -1, contentImageDrawableId = -1; private CFAlertStyle dialogStyle = CFAlertStyle.ALERT; private View headerView, footerView; private int headerViewId = -1, footerViewId = -1; private Drawable contentImageDrawable, iconDrawable; private List buttons = new ArrayList<>(); private OnDismissListener onDismissListener; private boolean cancelable = true; private String[] multiSelectItems; private String[] items; private String[] singleSelectItems; private boolean[] multiSelectedItems; private int singleSelectedItem = -1; private OnClickListener onItemClickListener; private OnClickListener onSingleItemClickListener; private OnMultiChoiceClickListener onMultiChoiceClickListener; private long autoDismissDuration = -1; public boolean isDialogBodyEmpty() { if (!TextUtils.isEmpty(title)) return false; if (!TextUtils.isEmpty(message)) return false; if (buttons != null && buttons.size() > 0) return false; if (items != null && items.length > 0) return false; if (singleSelectItems != null && singleSelectItems.length != 0) return false; if (multiSelectItems != null && multiSelectItems.length != 0) return false; // The dialog body is empty if it doesn't contain any of the above items return true; } } private static class CFAlertActionButton { private Context context; private String buttonText; private DialogInterface.OnClickListener onClickListener; private int textColor = -1; private CFAlertActionStyle style; private CFAlertActionAlignment alignment = CFAlertActionAlignment.JUSTIFIED; private int backgroundColor = -1; private int backgroundDrawableId = -1; public CFAlertActionButton(Context context, String buttonText, @ColorInt int textColor, @ColorInt int backgroundColor, CFAlertActionStyle style, CFAlertActionAlignment alignment, OnClickListener onClickListener) { this.context = context; this.buttonText = buttonText; this.textColor = textColor; this.backgroundColor = backgroundColor; this.style = style; this.backgroundDrawableId = getBackgroundDrawable(style); this.alignment = alignment; this.onClickListener = onClickListener; // default textColor if (textColor == -1) { this.textColor = getTextColor(style); } } private @DrawableRes int getBackgroundDrawable(CFAlertActionStyle style) { @DrawableRes int backgroundDrawable = 0; switch (style) { case NEGATIVE: backgroundDrawable = R.drawable.cfdialog_negative_button_background_drawable; break; case POSITIVE: backgroundDrawable = R.drawable.cfdialog_positive_button_background_drawable; break; case DEFAULT: backgroundDrawable = R.drawable.cfdialog_default_button_background_drawable; break; } return backgroundDrawable; } private @ColorInt int getTextColor(CFAlertActionStyle style) { @ColorInt int textColor = -1; switch (style) { case NEGATIVE: textColor = ContextCompat.getColor(context, R.color.cfdialog_button_white_text_color); break; case POSITIVE: textColor = ContextCompat.getColor(context, R.color.cfdialog_button_white_text_color); break; case DEFAULT: textColor = ContextCompat.getColor(context, R.color.cfdialog_default_button_text_color); break; } return textColor; } } } ================================================ FILE: cfalertdialog/src/main/java/com/crowdfire/cfalertdialog/utils/DeviceUtil.java ================================================ package com.crowdfire.cfalertdialog.utils; import android.content.Context; import android.content.res.Resources; import android.graphics.Point; import android.util.DisplayMetrics; import android.view.Display; import android.view.WindowManager; public class DeviceUtil { public static int getScreenWidth(Context context) { Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); Point size = new Point(); display.getSize(size); return size.x; } public static int getScreenHeight(Context context) { Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); Point size = new Point(); display.getSize(size); return size.y; } /** * This method converts dp unit to equivalent pixels, depending on device density. * * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels * @return A float value to represent px equivalent to dp depending on device density */ public static int convertDpToPixel(Context context, float dp) { Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); int px = (int) dp * (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); return px; } /** * This method converts device specific pixels to density independent pixels. * * @param px A value in px (pixels) unit. Which we need to convert into db * @return A float value to represent dp equivalent to px value */ public static float convertPixelsToDp(Context context, float px) { Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); float dp = px / (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); return dp; } /** * This method converts sp unit to equivalent pixels, depending on device density. * * @param sp A value in sp (scale independent pixels) unit. Which we need to convert into pixels * @return A float value to represent px equivalent to sp depending on device scale */ public static int convertSpToPixel(Context context, float sp) { float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity; return (int) (sp * scaledDensity); } /** * This method converts device specific pixels to scale independent pixels. * * @param px A value in px (pixels) unit. Which we need to convert into db * @return A float value to represent sp equivalent to px value */ public static float convertPixelsToSp(Context context, float px) { float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity; return px / scaledDensity; } } ================================================ FILE: cfalertdialog/src/main/java/com/crowdfire/cfalertdialog/utils/SwipeToHideViewListener.java ================================================ package com.crowdfire.cfalertdialog.utils; import android.animation.Animator; import android.view.MotionEvent; import android.view.View; import android.view.ViewPropertyAnimator; /** * Created by rahul on 31/08/17. */ public class SwipeToHideViewListener implements View.OnTouchListener { private boolean isTouching; private float swipeStartX; private float swipeStartY; private float viewStartX; private float deltaX = 0; private float deltaY = 0; private boolean isSwipingHorizontal = false; private View animatingView; private boolean shouldDismissView; private SwipeToHideCompletionListener listener; private static final int SWIPE_TO_DISMISS_THRESHOLD = 150; private static final int SWIPE_TO_DISMISS_ANIMATION_DURATION = 100; public SwipeToHideViewListener(View animatingView, boolean shouldDismissView, SwipeToHideCompletionListener listener) { this.animatingView = animatingView; this.shouldDismissView = shouldDismissView; this.listener = listener; } public void setAnimatingView(View animatingView) { this.animatingView = animatingView; } public void setShouldDismissView(boolean shouldDismissView) { this.shouldDismissView = shouldDismissView; } public void setListener(SwipeToHideCompletionListener listener) { this.listener = listener; } @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: // Set Touched view as the animatingView if not set if (animatingView == null) animatingView = view; isTouching = true; startSwipe(motionEvent); break; case MotionEvent.ACTION_MOVE: if (!isTouching) break; moveSwipe(motionEvent); break; case MotionEvent.ACTION_UP: view.performClick(); case MotionEvent.ACTION_OUTSIDE: isTouching = false; isSwipingHorizontal = false; endSwipe(); break; } return isSwipingHorizontal; } private void startSwipe(MotionEvent event) { // Keep the initial swipe action position swipeStartX = event.getRawX(); swipeStartY = event.getRawY(); viewStartX = animatingView.getX(); } private void moveSwipe(MotionEvent event) { // Check if the motion is horizontal deltaX = event.getRawX() - swipeStartX; deltaY = event.getRawY() - swipeStartY; // Check Vertical Swipe if (Math.abs(deltaY) > 0 && Math.abs(deltaY) > Math.abs(deltaX)) { // Is swiping vertically return; } // Check Horizontal swipe if (Math.abs(deltaX) > 0) { animateViewHorizontally(deltaX, 0, false, null); isSwipingHorizontal = true; } } private void endSwipe() { if (shouldDismissView && Math.abs(deltaX) > SWIPE_TO_DISMISS_THRESHOLD) { // Check whether view should animate left or right float endPos = (deltaX > 0) ? animatingView.getWidth() : -animatingView.getWidth(); animateViewHorizontally(endPos, SWIPE_TO_DISMISS_ANIMATION_DURATION, true, new AnimatorCompletionListener() { @Override void onAnimationCompleted() { if (listener != null) listener.viewDismissed(); } }); } else { animateViewHorizontally(0, SWIPE_TO_DISMISS_ANIMATION_DURATION, false, null); } } private void animateViewHorizontally(float dX, int duration, boolean shouldHide, AnimatorCompletionListener listener) { float animatingDistance = viewStartX + dX; ViewPropertyAnimator animator = animatingView.animate() .x(animatingDistance) .setDuration(duration) .setListener(listener); if (shouldHide) { animator.alpha(0); } animator.start(); } private abstract class AnimatorCompletionListener implements Animator.AnimatorListener { @Override public void onAnimationStart(Animator animator) { } @Override public void onAnimationEnd(Animator animator) { onAnimationCompleted(); } @Override public void onAnimationCancel(Animator animator) { } @Override public void onAnimationRepeat(Animator animator) { } abstract void onAnimationCompleted(); } public interface SwipeToHideCompletionListener { void viewDismissed(); } } ================================================ FILE: cfalertdialog/src/main/java/com/crowdfire/cfalertdialog/utils/ViewUtil.java ================================================ package com.crowdfire.cfalertdialog.utils; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.DecelerateInterpolator; import android.view.animation.ScaleAnimation; public class ViewUtil { public static void addBounceEffect(View view) { view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return onButtonTouch(v, event); } }); } private static boolean onButtonTouch(View button, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { onButtonPressed(button); } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_OUTSIDE) { onButtonReleased(button); } return false; } private static void onButtonPressed(View button) { ScaleAnimation scaleAnimation = new ScaleAnimation(1, 0.9f, 1, 0.9f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); scaleAnimation.setInterpolator(new DecelerateInterpolator()); scaleAnimation.setDuration(100); scaleAnimation.setFillAfter(true); button.startAnimation(scaleAnimation); } private static void onButtonReleased(View button) { ScaleAnimation scaleAnimation = new ScaleAnimation(0.9f, 1f, 0.9f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); scaleAnimation.setInterpolator(new DecelerateInterpolator()); scaleAnimation.setDuration(100); scaleAnimation.setFillAfter(true); button.startAnimation(scaleAnimation); } } ================================================ FILE: cfalertdialog/src/main/java/com/crowdfire/cfalertdialog/views/CFPushButton.java ================================================ package com.crowdfire.cfalertdialog.views; import android.content.Context; import android.graphics.Typeface; import androidx.appcompat.widget.AppCompatButton; import android.util.AttributeSet; import android.view.Gravity; import com.crowdfire.cfalertdialog.utils.ViewUtil; /** * Created by rahul on 29/06/17. */ public class CFPushButton extends AppCompatButton { public CFPushButton(Context context) { this(context, null, 0); } public CFPushButton(Context context, AttributeSet attrs) { this(context,attrs, 0); } public CFPushButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initButton(context, attrs, defStyleAttr); } void initButton(Context context, AttributeSet attributeSet, int defStyleAttr) { // Set centered text alignment setGravity(Gravity.CENTER); ViewUtil.addBounceEffect(this); setTypeface(getTypeface(), Typeface.BOLD); } } ================================================ FILE: cfalertdialog/src/main/res/anim/alert_dismiss.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/alert_present.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/dialog_dismiss_bottom.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/dialog_dismiss_center.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/dialog_dismiss_top.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/dialog_present_bottom.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/dialog_present_center.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/dialog_present_top.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/interpolator_acceleration_1_5.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/interpolator_deceleration_1_5.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/interpolator_deceleration_3.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/interpolator_overshoot_1.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/anim/interpolator_overshoot_1_2.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/drawable/cfdialog_buttons_spacing.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/drawable/cfdialog_content_spacing_horizontal.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/drawable/cfdialog_content_spacing_vertical.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/drawable/cfdialog_default_button_background_drawable.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/drawable/cfdialog_negative_button_background_drawable.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/drawable/cfdialog_positive_button_background_drawable.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/layout/cfalert_layout.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/layout/cfdialog_imageview_header.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/layout/cfdialog_multi_select_item_layout.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/layout/cfdialog_selectable_item_layout.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/layout/cfdialog_single_select_item_layout.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/layout/cfdialog_single_select_radio_button_layout.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/values/colors.xml ================================================ #B3000000 #FFFFFF #000000 #434343 #0d000000 #263238 #ffffff #000000 #29c64d #80e598 #FF4B4B #ff9999 #6768d9 #999ae6 ================================================ FILE: cfalertdialog/src/main/res/values/dimen.xml ================================================ 400dp 10dp 10dp 5dp 20dp 10dp 10dp 10dp 4dp 4dp 10dp 32dp 20sp 14sp 14sp 10dp 4dp ================================================ FILE: cfalertdialog/src/main/res/values/strings.xml ================================================ CFAlertDialog Title This is a message to be displayed on the alert. ================================================ FILE: cfalertdialog/src/main/res/values/styles.xml ================================================ ================================================ FILE: cfalertdialog/src/main/res/values/values.xml ================================================ 300 200 400 500 ================================================ FILE: cfalertdialog/src/test/java/com/crowdfire/cfalertdialog/ExampleUnitTest.java ================================================ package com.crowdfire.cfalertdialog; import org.junit.Test; import static org.junit.Assert.*; /** * Example local unit test, which will execute on the development machine (host). * * @see Testing documentation */ public class ExampleUnitTest { @Test public void addition_isCorrect() throws Exception { assertEquals(4, 2 + 2); } } ================================================ FILE: cfalertdialogdemo/.gitignore ================================================ /build ================================================ FILE: cfalertdialogdemo/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 28 buildToolsVersion '28.0.3' defaultConfig { applicationId "com.crowdfireapp.cfalertdialogdemo" minSdkVersion 14 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation fileTree(include: ['*.jar'], dir: 'libs') androidTestImplementation('androidx.test.espresso:espresso-core:3.1.1-alpha01', { exclude group: 'com.android.support', module: 'support-annotations' }) implementation project(':cfalertdialog') implementation 'androidx.appcompat:appcompat:1.1.0-alpha01' implementation 'com.google.android.material:material:1.1.0-alpha01' testImplementation 'junit:junit:4.12' } ================================================ FILE: cfalertdialogdemo/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/rahul/Android/SDK/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: cfalertdialogdemo/src/androidTest/java/com/crowdfire/cfalertdialogdemo/ExampleInstrumentedTest.java ================================================ package com.crowdfire.cfalertdialogdemo; import android.content.Context; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Instrumentation test, which will execute on an Android device. * * @see Testing documentation */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("com.crowdfire.cfalertdialogdemo", appContext.getPackageName()); } } ================================================ FILE: cfalertdialogdemo/src/main/AndroidManifest.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/java/com/crowdfire/cfalertdialogdemo/StartActivity.java ================================================ package com.crowdfire.cfalertdialogdemo; import android.content.DialogInterface; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.os.Bundle; import com.google.android.material.floatingactionbutton.FloatingActionButton; import androidx.core.view.ViewCompat; import androidx.appcompat.app.AppCompatActivity; import android.view.Gravity; import android.view.View; import android.view.WindowManager; import android.widget.CheckBox; import android.widget.EditText; import android.widget.RadioButton; import android.widget.Toast; import com.crowdfire.cfalertdialog.CFAlertDialog; import com.crowdfire.cfalertdialogdemo.views.ColorSelectionView; import com.crowdfire.cfalertdialogdemo.views.SampleFooterView; import static com.crowdfire.cfalertdialog.CFAlertDialog.CFAlertActionAlignment; import static com.crowdfire.cfalertdialog.CFAlertDialog.CFAlertActionStyle; import static com.crowdfire.cfalertdialog.CFAlertDialog.OnClickListener; /** * Created by rahul on 06/07/17. */ public class StartActivity extends AppCompatActivity implements SampleFooterView.FooterActionListener { private static final int DEFAULT_BACKGROUND_COLOR = Color.parseColor("#B3000000"); private EditText titleEditText, messageEditText; private CheckBox positiveButtonCheckbox, negativeButtonCheckbox, neutralButtonCheckbox, addHeaderCheckBox, addFooterCheckBox, closesOnBackgroundTapCheckBox; private RadioButton itemsRadioButton, multiChoiceRadioButton, singleChoiceRadioButton; private RadioButton textGravityLeft, textGravityCenter, textGravityRight; private RadioButton buttonGravityLeft, buttonGravityRight, buttonGravityCenter, buttonGravityFull; private CheckBox showTitleIcon; private RadioButton topDialogGravityRadioButton, centerDialogGravityRadioButton, bottomDialogGravityRadioButton; private View selectedBackgroundColorView, selectBackgroundColorContainer; private FloatingActionButton showDialogFab; private CFAlertDialog alertDialog; private CFAlertDialog colorSelectionDialog; private ColorSelectionView colorSelectionView; private boolean headerVisibility; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start); bindViews(); showDialogFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { showCFDialog(); } }); selectBackgroundColorContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showColorSelectionAlert(); } }); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); } private void showColorSelectionAlert() { if (colorSelectionDialog == null) { colorSelectionView = new ColorSelectionView(this); colorSelectionView.setSelectedColor(DEFAULT_BACKGROUND_COLOR); colorSelectionDialog = new CFAlertDialog.Builder(this) .addButton("Done", -1, -1, CFAlertActionStyle.POSITIVE, CFAlertActionAlignment.JUSTIFIED, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Update the color preview setSelectedBackgroundColor(colorSelectionView.selectedColor); // dismiss the dialog colorSelectionDialog.dismiss(); } }) .setDialogStyle(CFAlertDialog.CFAlertStyle.BOTTOM_SHEET) .setHeaderView(colorSelectionView) .onDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialogInterface) { // Update the color preview setSelectedBackgroundColor(colorSelectionView.selectedColor); } }) .create(); } colorSelectionDialog.show(); } private void showCFDialog() { CFAlertDialog.Builder builder = new CFAlertDialog.Builder(this); // Vertical position of the dialog if (topDialogGravityRadioButton.isChecked()) { builder.setDialogStyle(CFAlertDialog.CFAlertStyle.NOTIFICATION); } if (centerDialogGravityRadioButton.isChecked()) { builder.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT); } if (bottomDialogGravityRadioButton.isChecked()) { builder.setDialogStyle(CFAlertDialog.CFAlertStyle.BOTTOM_SHEET); } // Background int alertBGColor = -1; if (colorSelectionView != null) { alertBGColor = colorSelectionView.selectedColor; builder.setBackgroundColor(alertBGColor); } // Title and message builder.setTitle(titleEditText.getText()); builder.setMessage(messageEditText.getText()); if (textGravityLeft.isChecked()) { builder.setTextGravity(Gravity.START); } else if (textGravityCenter.isChecked()) { builder.setTextGravity(Gravity.CENTER_HORIZONTAL); } else if (textGravityRight.isChecked()) { builder.setTextGravity(Gravity.END); } // Title icon if (showTitleIcon.isChecked()) { builder.setIcon(R.drawable.icon_drawable); } // Buttons if (positiveButtonCheckbox.isChecked()) { // Add a sample positive button builder.addButton("Positive", -1, -1, CFAlertActionStyle.POSITIVE, getButtonGravity(), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(StartActivity.this, "Positive", Toast.LENGTH_SHORT).show(); alertDialog.dismiss(); } }); } if (negativeButtonCheckbox.isChecked()) { // Add a sample negative button builder.addButton("Negative", -1, -1, CFAlertActionStyle.NEGATIVE, getButtonGravity(), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(StartActivity.this, "Negative", Toast.LENGTH_SHORT).show(); alertDialog.dismiss(); } }); } if (neutralButtonCheckbox.isChecked()) { // Add a sample neutral button builder.addButton("Neutral", -1, -1, CFAlertActionStyle.DEFAULT, getButtonGravity(), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(StartActivity.this, "Neutral", Toast.LENGTH_SHORT).show(); alertDialog.dismiss(); } }); } // Add Header if (addHeaderCheckBox.isChecked()) { builder.setHeaderView(R.layout.dialog_header_layout); headerVisibility = true; } // Add Footer if (addFooterCheckBox.isChecked()) { SampleFooterView footerView = new SampleFooterView(this); footerView.setSelecteBackgroundColor(alertBGColor); builder.setFooterView(footerView); } // Selection Items if (itemsRadioButton.isChecked()) { // List items builder.setItems(new String[]{"First", "Second", "Third"}, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case 0: Toast.makeText(StartActivity.this, "First", Toast.LENGTH_SHORT).show(); break; case 1: Toast.makeText(StartActivity.this, "Second", Toast.LENGTH_SHORT).show(); break; case 2: Toast.makeText(StartActivity.this, "Third", Toast.LENGTH_SHORT).show(); break; } } }); } else if (singleChoiceRadioButton.isChecked()) { // Single choice list items builder.setSingleChoiceItems(new String[]{"First", "Second", "Third"}, 1, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case 0: Toast.makeText(StartActivity.this, "First", Toast.LENGTH_SHORT).show(); break; case 1: Toast.makeText(StartActivity.this, "Second", Toast.LENGTH_SHORT).show(); break; case 2: Toast.makeText(StartActivity.this, "Third", Toast.LENGTH_SHORT).show(); break; } } }); } else if (multiChoiceRadioButton.isChecked()) { // Multi choice list items builder.setMultiChoiceItems(new String[]{"First", "Second", "Third"}, new boolean[]{true, false, false}, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { switch (which) { case 0: Toast.makeText(StartActivity.this, "First " + (isChecked ? "Checked" : "Unchecked"), Toast.LENGTH_SHORT).show(); break; case 1: Toast.makeText(StartActivity.this, "Second " + (isChecked ? "Checked" : "Unchecked"), Toast.LENGTH_SHORT).show(); break; case 2: Toast.makeText(StartActivity.this, "Third " + (isChecked ? "Checked" : "Unchecked"), Toast.LENGTH_SHORT).show(); break; } } }); } // Cancel on background tap builder.setCancelable(closesOnBackgroundTapCheckBox.isChecked()); alertDialog = builder.show(); alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { onDialogDismiss(); } }); } private CFAlertActionAlignment getButtonGravity() { if (buttonGravityLeft.isChecked()) { return CFAlertActionAlignment.START; } if (buttonGravityCenter.isChecked()) { return CFAlertActionAlignment.CENTER; } if (buttonGravityRight.isChecked()) { return CFAlertActionAlignment.END; } if (buttonGravityFull.isChecked()) { return CFAlertActionAlignment.JUSTIFIED; } return CFAlertActionAlignment.JUSTIFIED; } private void bindViews() { titleEditText = (EditText) findViewById(R.id.title_edittext); messageEditText = (EditText) findViewById(R.id.message_edittext); textGravityLeft = (RadioButton) findViewById(R.id.text_gravity_left); textGravityCenter = (RadioButton) findViewById(R.id.text_gravity_center); textGravityRight = (RadioButton) findViewById(R.id.text_gravity_right); positiveButtonCheckbox = (CheckBox) findViewById(R.id.positive_button_checkbox); negativeButtonCheckbox = (CheckBox) findViewById(R.id.negative_button_checkbox); neutralButtonCheckbox = (CheckBox) findViewById(R.id.neutral_button_checkbox); addHeaderCheckBox = (CheckBox) findViewById(R.id.add_header_checkbox); addFooterCheckBox = (CheckBox) findViewById(R.id.add_footer_checkbox); buttonGravityLeft = (RadioButton) findViewById(R.id.button_gravity_left); buttonGravityCenter = (RadioButton) findViewById(R.id.button_gravity_center); buttonGravityRight = (RadioButton) findViewById(R.id.button_gravity_right); buttonGravityFull = (RadioButton) findViewById(R.id.button_gravity_justified); itemsRadioButton = (RadioButton) findViewById(R.id.items_radio_button); multiChoiceRadioButton = (RadioButton) findViewById(R.id.multi_select_choice_items_radio_button); singleChoiceRadioButton = (RadioButton) findViewById(R.id.single_choice_items_radio_button); showTitleIcon = (CheckBox) findViewById(R.id.show_title_icon); topDialogGravityRadioButton = (RadioButton) findViewById(R.id.top_dialog_gravity_radio_button); centerDialogGravityRadioButton = (RadioButton) findViewById(R.id.center_dialog_gravity_radio_button); bottomDialogGravityRadioButton = (RadioButton) findViewById(R.id.bottom_dialog_gravity_radio_button); closesOnBackgroundTapCheckBox = ((CheckBox) findViewById(R.id.closes_on_background_tap)); selectedBackgroundColorView = findViewById(R.id.background_color_preview); setSelectedBackgroundColor(DEFAULT_BACKGROUND_COLOR); selectBackgroundColorContainer = findViewById(R.id.background_color_selection_container); showDialogFab = (FloatingActionButton) findViewById(R.id.fab); } private void setSelectedBackgroundColor(int color) { GradientDrawable previewBackground = (GradientDrawable) selectedBackgroundColorView.getBackground(); previewBackground.setColor(color); ViewCompat.setBackground(selectedBackgroundColorView, previewBackground); } @Override public void onBackgroundColorChanged(int backgroundColor) { alertDialog.setBackgroundColor(backgroundColor, true); } @Override public void onHeaderAdded() { if (alertDialog != null) { alertDialog.setHeaderView(R.layout.dialog_header_layout); } headerVisibility = true; } @Override public void onHeaderRemoved() { if (alertDialog != null) { alertDialog.setHeaderView(null); } headerVisibility = false; } private void onDialogDismiss() { headerVisibility = false; } @Override public boolean isHeaderVisible() { return headerVisibility; } } ================================================ FILE: cfalertdialogdemo/src/main/java/com/crowdfire/cfalertdialogdemo/views/ColorSelectionView.java ================================================ package com.crowdfire.cfalertdialogdemo.views; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.os.Build; import androidx.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; import android.widget.SeekBar; import com.crowdfire.cfalertdialogdemo.R; /** * Created by rahul on 10/07/17. */ public class ColorSelectionView extends LinearLayout implements SeekBar.OnSeekBarChangeListener{ // region Variables private static int COLOR_MAX_VALUE = 255; private SeekBar seekBarRed, seekBarGreen, seekBarBlue, seekBarAlpha; private View selectedColorPreview; public int selectedColor; // endregion public ColorSelectionView(Context context) { super(context); init(); } public ColorSelectionView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public ColorSelectionView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { inflate(getContext(), R.layout.color_selection_view, this); bindViews(); } private void bindViews() { selectedColorPreview = findViewById(R.id.selected_color_preview); seekBarRed = (SeekBar) findViewById(R.id.seekbar_red); seekBarRed.setMax(COLOR_MAX_VALUE); seekBarRed.setOnSeekBarChangeListener(this); seekBarBlue = (SeekBar) findViewById(R.id.seekbar_blue); seekBarBlue.setMax(COLOR_MAX_VALUE); seekBarBlue.setOnSeekBarChangeListener(this); seekBarGreen = (SeekBar) findViewById(R.id.seekbar_green); seekBarGreen.setMax(COLOR_MAX_VALUE); seekBarGreen.setOnSeekBarChangeListener(this); seekBarAlpha = (SeekBar) findViewById(R.id.seekbar_alpha); seekBarAlpha.setMax(COLOR_MAX_VALUE); seekBarAlpha.setProgress(COLOR_MAX_VALUE); seekBarAlpha.setOnSeekBarChangeListener(this); } // region SeekBar value changed listeners @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { updateSelectedColorPreview(); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } // endregion private void updateSelectedColorPreview() { // Create color with selected color values int redValue = seekBarRed.getProgress(); int greenValue = seekBarGreen.getProgress(); int blueValue = seekBarBlue.getProgress(); int alpha = seekBarAlpha.getProgress(); selectedColor = Color.argb(alpha, redValue, greenValue, blueValue); GradientDrawable previewBackground = (GradientDrawable) selectedColorPreview.getBackground(); previewBackground.setColor(selectedColor); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { selectedColorPreview.setBackground(previewBackground); } else { selectedColorPreview.setBackgroundDrawable(previewBackground); } } public void setSelectedColor(int selectedColor) { this.selectedColor = selectedColor; seekBarAlpha.setProgress(Color.alpha(selectedColor)); seekBarRed.setProgress(Color.red(selectedColor)); seekBarGreen.setProgress(Color.green(selectedColor)); seekBarBlue.setProgress(Color.blue(selectedColor)); } } ================================================ FILE: cfalertdialogdemo/src/main/java/com/crowdfire/cfalertdialogdemo/views/SampleFooterView.java ================================================ package com.crowdfire.cfalertdialogdemo.views; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import androidx.core.content.ContextCompat; import androidx.core.view.ViewCompat; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; import com.crowdfire.cfalertdialog.views.CFPushButton; import com.crowdfire.cfalertdialogdemo.R; import java.util.Random; import static com.crowdfire.cfalertdialogdemo.views.SampleFooterView.ConfigurationState.COLLAPSED; import static com.crowdfire.cfalertdialogdemo.views.SampleFooterView.ConfigurationState.EXPANDED; import static com.crowdfire.cfalertdialogdemo.views.SampleFooterView.HeaderState.HIDDEN; import static com.crowdfire.cfalertdialogdemo.views.SampleFooterView.HeaderState.SHOWN; /** * Created by rahul on 11/07/17. */ public class SampleFooterView extends LinearLayout implements View.OnClickListener { View backgroundColorPreview; CFPushButton headerToggleButton; LinearLayout configurationContainer; CFPushButton configurationToggleButton; FooterActionListener listener; public SampleFooterView(Context context) { this(context, null, 0); } public SampleFooterView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SampleFooterView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); if (context instanceof FooterActionListener) { listener = (FooterActionListener) context; } else { throw new IllegalStateException(context + " must implement" + FooterActionListener.class.getSimpleName()); } init(); } public void setSelecteBackgroundColor(int color) { ((GradientDrawable) backgroundColorPreview.getBackground()).setColor(color); } private void setupSubviews() { backgroundColorPreview = findViewById(R.id.background_color_preview); backgroundColorPreview.setOnClickListener(this); headerToggleButton = (CFPushButton) findViewById(R.id.header_toggle_button); headerToggleButton.setOnClickListener(this); configurationContainer = (LinearLayout) findViewById(R.id.configuration_container); configurationToggleButton = (CFPushButton) findViewById(R.id.configuration_toggle_button); configurationToggleButton.setOnClickListener(this); collapseConfiguration(); if (listener.isHeaderVisible()) { showHeader(); } else { hideHeader(); } } private void toggleHeaderState(HeaderState headerState) { switch (headerState) { case SHOWN: hideHeader(); break; case HIDDEN: showHeader(); break; default: break; } } private void showHeader() { headerToggleButton.setTag(SHOWN); headerToggleButton.setText("Remove Header"); ViewCompat.setBackground(headerToggleButton, ContextCompat.getDrawable(getContext(), R.drawable.remove_header_button_background)); listener.onHeaderAdded(); } private void hideHeader() { headerToggleButton.setTag(HIDDEN); headerToggleButton.setText("Add Header"); ViewCompat.setBackground(headerToggleButton, ContextCompat.getDrawable(getContext(), R.drawable.footer_button_drawable)); listener.onHeaderRemoved(); } private void changeBackgroundColor() { Random rnd = new Random(); int color = Color.argb(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)); ((GradientDrawable) backgroundColorPreview.getBackground()).setColor(color); listener.onBackgroundColorChanged(color); } private void init() { inflate(getContext(), R.layout.dialog_footer_layout, this); setupSubviews(); } private void toggleState() { switch ((ConfigurationState) configurationToggleButton.getTag()) { case EXPANDED: collapseConfiguration(); break; case COLLAPSED: expandConfiguration(); break; default: break; } } void collapseConfiguration() { configurationToggleButton.setTag(COLLAPSED); configurationToggleButton.setText("Configurations"); configurationToggleButton.setTextColor(Color.WHITE); ViewCompat.setBackground(configurationToggleButton, ContextCompat.getDrawable(getContext(), R.drawable.footer_button_drawable)); configurationContainer.setVisibility(GONE); } void expandConfiguration() { configurationToggleButton.setTag(EXPANDED); configurationToggleButton.setText("Close"); configurationToggleButton.setTextColor(ContextCompat.getColor(getContext(), R.color.close_button_text_color)); ViewCompat.setBackground(configurationToggleButton, ContextCompat.getDrawable(getContext(), R.drawable.footer_button_disabled_drawable)); configurationContainer.setVisibility(VISIBLE); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.background_color_preview: changeBackgroundColor(); break; case R.id.header_toggle_button: toggleHeaderState((HeaderState) headerToggleButton.getTag()); break; case R.id.configuration_toggle_button: toggleState(); break; } } enum ConfigurationState { COLLAPSED, EXPANDED } public enum HeaderState { SHOWN, HIDDEN } public interface FooterActionListener { void onBackgroundColorChanged(int backgroundColor); void onHeaderAdded(); void onHeaderRemoved(); boolean isHeaderVisible(); } } ================================================ FILE: cfalertdialogdemo/src/main/res/drawable/black_border.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/drawable/footer_button_disabled_drawable.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/drawable/footer_button_drawable.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/drawable/footer_or_drawable.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/drawable/icon_drawable.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/drawable/image_content_drawable.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/drawable/remove_header_button_background.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/layout/activity_start.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/layout/color_selection_view.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/layout/dialog_footer_layout.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/layout/dialog_header_layout.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/main/res/values/colors.xml ================================================ #178DD6 #167DBC #FF4081 #A0000000 #4D000000 #F6F6F6 #B8B8B8 #013356 #4A4A4A #98A4B3 #212121 #424242 #555555 #dddddd #ff4b4b ================================================ FILE: cfalertdialogdemo/src/main/res/values/dimens.xml ================================================ 16dp 20dp 34dp 17dp ================================================ FILE: cfalertdialogdemo/src/main/res/values/strings.xml ================================================ CFAlertDialogDemo Sample Button Left Center Right Left Center Right Full Width ================================================ FILE: cfalertdialogdemo/src/main/res/values/styles.xml ================================================ ================================================ FILE: cfalertdialogdemo/src/test/java/com/crowdfire/cfalertdialogdemo/ExampleUnitTest.java ================================================ package com.crowdfire.cfalertdialogdemo; import org.junit.Test; import static org.junit.Assert.*; /** * Example local unit test, which will execute on the development machine (host). * * @see Testing documentation */ public class ExampleUnitTest { @Test public void addition_isCorrect() throws Exception { assertEquals(4, 2 + 2); } } ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Apr 12 12:56:02 IST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip ================================================ FILE: gradle.properties ================================================ # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. android.enableJetifier=true android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true ================================================ FILE: gradlew ================================================ #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" ================================================ FILE: gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: settings.gradle ================================================ include ':cfalertdialogdemo', ':cfalertdialog'