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 
[](https://bintray.com/crowdfire/cfalertdialog/cfalertdialog)
[  ](https://bintray.com/crowdfire/cfalertdialog/cfalertdialog/_latestVersion)
[]()
[](https://android-arsenal.com/details/1/6252)
[]()
[](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'