diff --git a/MaterialDialogDynamic/.gitignore b/MaterialDialogDynamic/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/MaterialDialogDynamic/.gitignore @@ -0,0 +1 @@ +/build diff --git a/MaterialDialogDynamic/build.gradle b/MaterialDialogDynamic/build.gradle new file mode 100644 index 0000000..e069cc7 --- /dev/null +++ b/MaterialDialogDynamic/build.gradle @@ -0,0 +1,66 @@ +apply plugin: 'com.android.library' +apply plugin: 'maven-publish' + +android { + compileSdkVersion 31 + + defaultConfig { + minSdkVersion 19 + targetSdkVersion 31 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + namespace 'dev.shreyaspatil.MaterialDialog.dynamic' + + publishing { + singleVariant('release') { + withSourcesJar() + } + } +} + +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + from components.release + groupId = GROUP + artifactId = 'MaterialDialog-Dynamic' + version = VERSION_NAME + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation project(':MaterialDialogLibrary') + + implementation 'androidx.appcompat:appcompat:1.4.0' + implementation 'androidx.annotation:annotation:1.3.0' + + // Material Design Library + implementation 'com.google.android.material:material:1.4.0' + + // Lottie Animation Library + implementation 'com.airbnb.android:lottie:4.2.2' + + // Image Loading Library - only pulled in by consumers of this module + implementation 'com.github.bumptech.glide:glide:4.16.0' + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test:runner:1.4.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} diff --git a/MaterialDialogDynamic/proguard-rules.pro b/MaterialDialogDynamic/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/MaterialDialogDynamic/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# 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 diff --git a/MaterialDialogDynamic/src/main/AndroidManifest.xml b/MaterialDialogDynamic/src/main/AndroidManifest.xml new file mode 100644 index 0000000..cc947c5 --- /dev/null +++ b/MaterialDialogDynamic/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/AbstractDynamicDialog.java b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/AbstractDynamicDialog.java new file mode 100644 index 0000000..387924f --- /dev/null +++ b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/AbstractDynamicDialog.java @@ -0,0 +1,635 @@ +package dev.shreyaspatil.MaterialDialog.dynamic; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RawRes; +import androidx.core.content.ContextCompat; + +import com.airbnb.lottie.LottieAnimationView; +import com.airbnb.lottie.LottieCompositionFactory; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; +import com.google.android.material.button.MaterialButton; + +import java.util.ArrayList; +import java.util.List; + +import dev.shreyaspatil.MaterialDialog.AbstractDialog; +import dev.shreyaspatil.MaterialDialog.dynamic.model.ButtonStyle; +import dev.shreyaspatil.MaterialDialog.dynamic.model.DynamicDialogButton; +import dev.shreyaspatil.MaterialDialog.model.DialogButton; +import dev.shreyaspatil.MaterialDialog.model.DialogMessage; +import dev.shreyaspatil.MaterialDialog.model.DialogTitle; +import dev.shreyaspatil.MaterialDialog.model.TextAlignment; + +/** + * Base class shared by {@link DynamicMaterialDialog} and {@link DynamicBottomSheetMaterialDialog}: + * up to {@link #MAX_BUTTONS} buttons with arbitrary actions, and a header that is either a Lottie + * animation or a plain image (never both at once). Mirrors the relationship {@link AbstractDialog} + * has with {@link dev.shreyaspatil.MaterialDialog.MaterialDialog}/ + * {@link dev.shreyaspatil.MaterialDialog.BottomSheetMaterialDialog} in the core library. + *

+ * This class lives in a separate module/artifact from the core {@code MaterialDialogLibrary} so + * that the core 2-button API is untouched, and so the image-loading dependency it needs is only + * pulled in by consumers who use it. + */ +@SuppressWarnings("unused") +public abstract class AbstractDynamicDialog extends AbstractDialog { + + /** + * Maximum number of buttons a dynamic dialog supports. + */ + public static final int MAX_BUTTONS = 4; + + /** + * Sentinel value meaning no image source has been set. + */ + public static final int NO_IMAGE = -111; + + // Note: mAnimationResId/mAnimationFile/mAnimationUrl are deliberately NOT reused here even + // though AbstractDialog declares protected fields with those exact names - this subclass + // ignores the parent's (unused, dummy-valued) fields entirely and keeps its own state below, + // named distinctly to avoid shadowing confusion. + private final List mButtons; + private final int mDynamicAnimationResId; + private final String mDynamicAnimationFile; + private final String mDynamicAnimationUrl; + private final String mAnimationJson; + private final int mImageResId; + private final Bitmap mImageBitmap; + private final Drawable mImageDrawable; + private final String mImageUrl; + + private ImageView mImageView; + + protected AbstractDynamicDialog(@NonNull Activity activity, + @NonNull DialogTitle title, + @NonNull DialogMessage message, + boolean cancelable, + @NonNull List buttons, + @RawRes int animationResId, + @Nullable String animationFile, + @Nullable String animationUrl, + @Nullable String animationJson, + @DrawableRes int imageResId, + @Nullable Bitmap imageBitmap, + @Nullable Drawable imageDrawable, + @Nullable String imageUrl) { + // The positive/negative-button and animation params on AbstractDialog are unused here - + // this subclass overrides createView() entirely and keeps its own state instead. + super(activity, title, message, cancelable, null, null, AbstractDialog.NO_ANIMATION, null, null); + + if (buttons.size() > MAX_BUTTONS) { + throw new IllegalArgumentException( + "Dynamic dialogs support a maximum of " + MAX_BUTTONS + " buttons, but " + buttons.size() + " were provided."); + } + + this.mButtons = buttons; + this.mDynamicAnimationResId = animationResId; + this.mDynamicAnimationFile = animationFile; + this.mDynamicAnimationUrl = animationUrl; + this.mAnimationJson = animationJson; + this.mImageResId = imageResId; + this.mImageBitmap = imageBitmap; + this.mImageDrawable = imageDrawable; + this.mImageUrl = imageUrl; + } + + @SuppressLint("WrongConstant") + @Override + protected View createView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) { + final View dialogView = inflater.inflate(R.layout.layout_dynamic_alert_dialog, container, false); + + // Initialize Views + TextView mTitleView = dialogView.findViewById(R.id.textView_title); + TextView mMessageView = dialogView.findViewById(R.id.textView_message); + View mHeaderContainer = dialogView.findViewById(R.id.header_container); + mAnimationView = dialogView.findViewById(R.id.animation_view); + mImageView = dialogView.findViewById(R.id.image_view); + ProgressBar mImageProgress = dialogView.findViewById(R.id.image_progress); + LinearLayout mButtonContainer = dialogView.findViewById(R.id.button_container); + MaterialButton[] mButtonViews = new MaterialButton[]{ + dialogView.findViewById(R.id.button_1), + dialogView.findViewById(R.id.button_2), + dialogView.findViewById(R.id.button_3), + dialogView.findViewById(R.id.button_4) + }; + + // Set Title + if (title != null) { + mTitleView.setVisibility(View.VISIBLE); + mTitleView.setText(title.getText()); + mTitleView.setTextAlignment(title.getTextAlignment().getAlignment()); + } else { + mTitleView.setVisibility(View.GONE); + } + + // Set Message + if (message != null) { + mMessageView.setVisibility(View.VISIBLE); + mMessageView.setText(message.getText()); + mMessageView.setTextAlignment(message.getTextAlignment().getAlignment()); + } else { + mMessageView.setVisibility(View.GONE); + } + + // Set Buttons + int buttonCount = mButtons.size(); + mButtonContainer.setOrientation(buttonCount <= 2 ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL); + + for (int i = 0; i < mButtonViews.length; i++) { + MaterialButton buttonView = mButtonViews[i]; + if (i < buttonCount) { + DialogButton button = mButtons.get(i); + + buttonView.setVisibility(View.VISIBLE); + buttonView.setText(button.getTitle()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && button.getIcon() != NO_ICON) { + buttonView.setIcon(ContextCompat.getDrawable(mActivity, button.getIcon())); + } + + final int which = i; + buttonView.setOnClickListener(view -> + button.getOnClickListener().onClick(AbstractDynamicDialog.this, which) + ); + + LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) buttonView.getLayoutParams(); + if (buttonCount <= 2) { + params.width = buttonCount == 1 ? ViewGroup.LayoutParams.MATCH_PARENT : 0; + params.weight = buttonCount == 1 ? 0f : 0.5f; + } else { + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.weight = 0f; + } + buttonView.setLayoutParams(params); + } else { + buttonView.setVisibility(View.GONE); + } + } + + // Set Header: image and animation are mutually exclusive - image wins if both are set. + boolean hasImage = mImageResId != NO_IMAGE || mImageBitmap != null || mImageDrawable != null || mImageUrl != null; + boolean hasAnimation = mAnimationJson != null || mDynamicAnimationResId != NO_ANIMATION || mDynamicAnimationFile != null || mDynamicAnimationUrl != null; + + int orientation = mActivity.getResources().getConfiguration().orientation; + if (orientation == Configuration.ORIENTATION_LANDSCAPE || (!hasImage && !hasAnimation)) { + mHeaderContainer.setVisibility(View.GONE); + } else { + mHeaderContainer.setVisibility(View.VISIBLE); + + if (hasImage) { + mImageView.setVisibility(View.VISIBLE); + mAnimationView.setVisibility(View.GONE); + + if (mImageResId != NO_IMAGE) { + mImageView.setImageResource(mImageResId); + } else if (mImageBitmap != null) { + mImageView.setImageBitmap(mImageBitmap); + } else if (mImageDrawable != null) { + mImageView.setImageDrawable(mImageDrawable); + } else { + mImageProgress.setVisibility(View.VISIBLE); + Glide.with(mActivity) + .load(mImageUrl) + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + mImageProgress.setVisibility(View.GONE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + mImageProgress.setVisibility(View.GONE); + return false; + } + }) + .into(mImageView); + } + } else { + mAnimationView.setVisibility(View.VISIBLE); + mImageView.setVisibility(View.GONE); + + if (mAnimationJson != null) { + LottieCompositionFactory.fromJsonString(mAnimationJson, null) + .addListener(mAnimationView::setComposition) + .addFailureListener(Throwable::printStackTrace); + } else if (mDynamicAnimationResId != NO_ANIMATION) { + mAnimationView.setAnimation(mDynamicAnimationResId); + } else if (mDynamicAnimationFile != null) { + mAnimationView.setAnimation(mDynamicAnimationFile); + } else { + mAnimationView.setAnimationFromUrl(mDynamicAnimationUrl); + } + mAnimationView.playAnimation(); + } + } + + // Apply Styles + TypedArray a = mActivity.getTheme().obtainStyledAttributes(R.styleable.MaterialDialog); + + try { + // Set Dialog Background + dialogView.setBackgroundColor( + a.getColor(R.styleable.MaterialDialog_material_dialog_background, + mActivity.getResources().getColor(R.color.material_dialog_background))); + + // Set Title Text Color + mTitleView.setTextColor( + a.getColor(R.styleable.MaterialDialog_material_dialog_title_text_color, + mActivity.getResources().getColor(R.color.material_dialog_title_text_color))); + + // Set Message Text Color + mMessageView.setTextColor( + a.getColor(R.styleable.MaterialDialog_material_dialog_message_text_color, + mActivity.getResources().getColor((R.color.material_dialog_message_text_color)))); + + // Set Primary (index 0) Button Text/Icon Tint + ColorStateList mPrimaryButtonTint = a.getColorStateList( + R.styleable.MaterialDialog_material_dialog_positive_button_text_color); + + if (mPrimaryButtonTint == null) { + mPrimaryButtonTint = ContextCompat.getColorStateList( + mActivity.getApplicationContext(), + R.color.material_dialog_positive_button_text_color); + } + + // Set Secondary (index 1-3) Button Text/Icon Tint + ColorStateList mSecondaryButtonTint = a.getColorStateList( + R.styleable.MaterialDialog_material_dialog_negative_button_text_color); + + if (mSecondaryButtonTint == null) { + mSecondaryButtonTint = ContextCompat.getColorStateList( + mActivity.getApplicationContext(), + R.color.material_dialog_negative_button_text_color); + } + + // Set Primary Button Background Tint + ColorStateList mBackgroundTint = a.getColorStateList( + R.styleable.MaterialDialog_material_dialog_positive_button_color); + + if (mBackgroundTint == null) { + mBackgroundTint = ContextCompat.getColorStateList( + mActivity.getApplicationContext(), + R.color.material_dialog_positive_button_color); + } + + for (int i = 0; i < buttonCount; i++) { + MaterialButton buttonView = mButtonViews[i]; + + // A button's style is explicit if it's a DynamicDialogButton; otherwise it + // defaults to FILLED. + DialogButton button = mButtons.get(i); + ButtonStyle style = button instanceof DynamicDialogButton + ? ((DynamicDialogButton) button).getStyle() + : ButtonStyle.FILLED; + + if (style == ButtonStyle.FILLED) { + buttonView.setTextColor(mPrimaryButtonTint); + buttonView.setIconTint(mPrimaryButtonTint); + buttonView.setBackgroundTintList(mBackgroundTint); + buttonView.setStrokeWidth(0); + } else { + buttonView.setTextColor(mSecondaryButtonTint); + buttonView.setIconTint(mSecondaryButtonTint); + if (mBackgroundTint != null) { + buttonView.setRippleColor(mBackgroundTint.withAlpha(75)); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + a.recycle(); + } + + return dialogView; + } + + /** + * @return {@link ImageView} from the Dialog. + */ + public ImageView getImageView() { + return mImageView; + } + + /** + * Builder shared by {@link DynamicMaterialDialog.Builder} and + * {@link DynamicBottomSheetMaterialDialog.Builder}. + *

+ * This does not extend {@link AbstractDialog.Builder} on purpose: that class exposes the + * core library's 2-button/Lottie-only {@code setPositiveButton}/{@code setNegativeButton}/ + * {@code setAnimation} API, which would leak onto this dynamic API and defeat the point of + * keeping the two separate. + */ + public static abstract class Builder { + protected final Activity activity; + protected DialogTitle title; + protected DialogMessage message; + protected boolean isCancelable; + protected final List buttons = new ArrayList<>(); + protected int animationResId = AbstractDialog.NO_ANIMATION; + protected String animationFile; + protected String animationUrl; + protected String animationJson; + protected int imageResId = NO_IMAGE; + protected Bitmap imageBitmap; + protected Drawable imageDrawable; + protected String imageUrl; + + /** + * @param activity where the dynamic dialog is to be built. + */ + public Builder(@NonNull Activity activity) { + this.activity = activity; + } + + /** + * @param title Sets the Title of the dialog with the default alignment as center. + * @return this, for chaining. + */ + @NonNull + public Builder setTitle(@NonNull String title) { + return setTitle(title, TextAlignment.CENTER); + } + + /** + * @param title Sets the Title of the dialog. + * @param alignment Sets the Alignment for the title. + * @return this, for chaining. + */ + @NonNull + public Builder setTitle(@NonNull String title, @NonNull TextAlignment alignment) { + this.title = new DialogTitle(title, alignment); + return this; + } + + /** + * @param message Sets the plain text Message of the dialog with the default alignment as center. + * @return this, for chaining. + */ + @NonNull + public Builder setMessage(@NonNull String message) { + return setMessage(message, TextAlignment.CENTER); + } + + /** + * @param message Sets the plain text Message of the dialog. + * @param alignment Sets the Alignment for the message. + * @return this, for chaining. + */ + @NonNull + public Builder setMessage(@NonNull String message, @NonNull TextAlignment alignment) { + this.message = DialogMessage.text(message, alignment); + return this; + } + + /** + * @param isCancelable Sets cancelable property of the dialog. + * @return this, for chaining. + */ + @NonNull + public Builder setCancelable(boolean isCancelable) { + this.isCancelable = isCancelable; + return this; + } + + /** + * Adds a button to the dialog without icon, styled {@link ButtonStyle#FILLED} by default - + * use {@link #addButton(String, ButtonStyle, AbstractDialog.OnClickListener)} to make it + * {@link ButtonStyle#OUTLINED} instead. At most {@link #MAX_BUTTONS} buttons can be added. + * + * @param name sets the name/label of button. + * @param onClickListener interface for callback event on click of button. The {@code which} + * argument is the button's 0-based position among the buttons added. + * @return this, for chaining. + */ + @NonNull + public Builder addButton(@NonNull String name, @NonNull AbstractDialog.OnClickListener onClickListener) { + return addButton(name, NO_ICON, onClickListener); + } + + /** + * Adds a button to the dialog with icon, styled {@link ButtonStyle#FILLED} by default - + * use {@link #addButton(String, int, ButtonStyle, AbstractDialog.OnClickListener)} to make + * it {@link ButtonStyle#OUTLINED} instead. At most {@link #MAX_BUTTONS} buttons can be added. + * + * @param name sets the name/label of button. + * @param icon sets the resource icon for button. + * @param onClickListener interface for callback event on click of button. The {@code which} + * argument is the button's 0-based position among the buttons added. + * @return this, for chaining. + */ + @NonNull + public Builder addButton(@NonNull String name, int icon, @NonNull AbstractDialog.OnClickListener onClickListener) { + return addButton(new DialogButton(name, icon, onClickListener)); + } + + /** + * Adds a button to the dialog. At most {@link #MAX_BUTTONS} buttons can be added. + * + * @param button the button to add. + * @return this, for chaining. + */ + @NonNull + public Builder addButton(@NonNull DialogButton button) { + if (buttons.size() >= MAX_BUTTONS) { + throw new IllegalArgumentException( + "Dynamic dialogs support a maximum of " + MAX_BUTTONS + " buttons."); + } + buttons.add(button); + return this; + } + + /** + * Adds a button to the dialog without icon, with an explicit visual style. Every button + * defaults to {@link ButtonStyle#FILLED} unless it's given an explicit + * {@link ButtonStyle#OUTLINED} style here - style isn't derived from the button's + * position, so any number of buttons in the list can be filled or outlined independently. + * + * @param name sets the name/label of button. + * @param style the button's visual style. + * @param onClickListener interface for callback event on click of button. The {@code which} + * argument is the button's 0-based position among the buttons added. + * @return this, for chaining. + */ + @NonNull + public Builder addButton(@NonNull String name, @NonNull ButtonStyle style, @NonNull AbstractDialog.OnClickListener onClickListener) { + return addButton(new DynamicDialogButton(name, style, onClickListener)); + } + + /** + * Adds a button to the dialog with icon, with an explicit visual style. Every button + * defaults to {@link ButtonStyle#FILLED} unless it's given an explicit + * {@link ButtonStyle#OUTLINED} style here - style isn't derived from the button's + * position, so any number of buttons in the list can be filled or outlined independently. + * + * @param name sets the name/label of button. + * @param icon sets the resource icon for button. + * @param style the button's visual style. + * @param onClickListener interface for callback event on click of button. The {@code which} + * argument is the button's 0-based position among the buttons added. + * @return this, for chaining. + */ + @NonNull + public Builder addButton(@NonNull String name, int icon, @NonNull ButtonStyle style, @NonNull AbstractDialog.OnClickListener onClickListener) { + return addButton(new DynamicDialogButton(name, icon, style, onClickListener)); + } + + /** + * Replaces the buttons of the dialog wholesale - useful when the list of buttons is built + * dynamically (e.g. from a backend-provided configuration). + * + * @param buttons the buttons to set, in display order. Must not exceed {@link #MAX_BUTTONS}. + * @return this, for chaining. + */ + @NonNull + public Builder setButtons(@NonNull List buttons) { + if (buttons.size() > MAX_BUTTONS) { + throw new IllegalArgumentException( + "Dynamic dialogs support a maximum of " + MAX_BUTTONS + " buttons, but " + buttons.size() + " were provided."); + } + this.buttons.clear(); + this.buttons.addAll(buttons); + return this; + } + + /** + * It sets the resource json to the {@link LottieAnimationView}. Mutually exclusive with + * {@code setImage*}/{@code setImageUrl} - if an image source is also set, the image wins. + * + * @param animationResId sets the resource to {@link LottieAnimationView}. + * @return this, for chaining. + */ + @NonNull + public Builder setAnimation(@RawRes int animationResId) { + this.animationResId = animationResId; + return this; + } + + /** + * It sets the json file to the {@link LottieAnimationView} from assets. Mutually exclusive + * with {@code setImage*}/{@code setImageUrl} - if an image source is also set, the image wins. + * + * @param fileName sets the file from assets to {@link LottieAnimationView}. + * @return this, for chaining. + */ + @NonNull + public Builder setAnimation(@NonNull String fileName) { + this.animationFile = fileName; + return this; + } + + /** + * It sets the json animation to the {@link LottieAnimationView} by loading it from a URL. + * Mutually exclusive with {@code setImage*}/{@code setImageUrl} - if an image source is + * also set, the image wins. + * + * @param url URL of the Lottie JSON animation to load into {@link LottieAnimationView}. + * @return this, for chaining. + */ + @NonNull + public Builder setAnimationUrl(@NonNull String url) { + this.animationUrl = url; + return this; + } + + /** + * Sets a raw Lottie JSON string - e.g. one the app already fetched from a backend - as the + * animation source for {@link LottieAnimationView}. Takes priority over + * {@link #setAnimation(int)}/{@link #setAnimation(String)}/{@link #setAnimationUrl(String)} + * if more than one is set. Mutually exclusive with {@code setImage*}/{@code setImageUrl} - + * if an image source is also set, the image wins. + * + * @param json raw Lottie animation JSON content. + * @return this, for chaining. + */ + @NonNull + public Builder setAnimationJson(@NonNull String json) { + this.animationJson = json; + return this; + } + + /** + * Sets a drawable resource as the header image. Mutually exclusive with the Lottie + * animation sources - if this (or another image source) is set, the image wins over any + * animation that's also configured. + * + * @param resId drawable resource id to show as the header image. + * @return this, for chaining. + */ + @NonNull + public Builder setImage(@DrawableRes int resId) { + this.imageResId = resId; + return this; + } + + /** + * Sets a {@link Bitmap} as the header image. Mutually exclusive with the Lottie animation + * sources - if this (or another image source) is set, the image wins over any animation + * that's also configured. + * + * @param bitmap bitmap to show as the header image. + * @return this, for chaining. + */ + @NonNull + public Builder setImage(@NonNull Bitmap bitmap) { + this.imageBitmap = bitmap; + return this; + } + + /** + * Sets a {@link Drawable} as the header image. Mutually exclusive with the Lottie + * animation sources - if this (or another image source) is set, the image wins over any + * animation that's also configured. + * + * @param drawable drawable to show as the header image. + * @return this, for chaining. + */ + @NonNull + public Builder setImage(@NonNull Drawable drawable) { + this.imageDrawable = drawable; + return this; + } + + /** + * Loads the header image from a URL (e.g. one uploaded to a backend). Mutually exclusive + * with the Lottie animation sources - if this (or another image source) is set, the image + * wins over any animation that's also configured. + * + * @param url URL of the image to load into the header. + * @return this, for chaining. + */ + @NonNull + public Builder setImageUrl(@NonNull String url) { + this.imageUrl = url; + return this; + } + + /** + * Builds the dialog. + */ + @NonNull + public abstract D build(); + } +} diff --git a/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/DynamicBottomSheetMaterialDialog.java b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/DynamicBottomSheetMaterialDialog.java new file mode 100644 index 0000000..9ce5339 --- /dev/null +++ b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/DynamicBottomSheetMaterialDialog.java @@ -0,0 +1,138 @@ +package dev.shreyaspatil.MaterialDialog.dynamic; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Outline; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewOutlineProvider; +import android.widget.FrameLayout; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RawRes; + +import com.google.android.material.bottomsheet.BottomSheetBehavior; + +import java.util.List; + +import dev.shreyaspatil.MaterialDialog.model.DialogButton; +import dev.shreyaspatil.MaterialDialog.model.DialogMessage; +import dev.shreyaspatil.MaterialDialog.model.DialogTitle; + +/** + * A {@link dev.shreyaspatil.MaterialDialog.BottomSheetMaterialDialog} variant whose content can + * be driven dynamically (e.g. from a backend-provided configuration): up to {@link #MAX_BUTTONS} + * buttons with arbitrary actions, and a header that is either a Lottie animation or a plain image + * (never both at once). + *

+ * Use {@link DynamicBottomSheetMaterialDialog.Builder} to create a new instance. + */ +@SuppressWarnings("unused") +public final class DynamicBottomSheetMaterialDialog extends AbstractDynamicDialog { + + private DynamicBottomSheetMaterialDialog(@NonNull Activity activity, + @NonNull DialogTitle title, + @NonNull DialogMessage message, + boolean cancelable, + @NonNull List buttons, + @RawRes int animationResId, + @Nullable String animationFile, + @Nullable String animationUrl, + @Nullable String animationJson, + @DrawableRes int imageResId, + @Nullable Bitmap imageBitmap, + @Nullable Drawable imageDrawable, + @Nullable String imageUrl) { + super(activity, title, message, cancelable, buttons, animationResId, animationFile, animationUrl, + animationJson, imageResId, imageBitmap, imageDrawable, imageUrl); + + // Init Dialog, Create Bottom Sheet Dialog + mDialog = new BottomSheetDialog(mActivity); + + LayoutInflater inflater = mActivity.getLayoutInflater(); + + View dialogView = createView(inflater, null); + mDialog.setContentView(dialogView); + + // Set Cancelable property + mDialog.setCancelable(mCancelable); + + // Clip header/content to round corners + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + dialogView.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + float radius = mActivity.getResources().getDimension(R.dimen.radiusTop); + outline.setRoundRect(0, 0, view.getWidth(), view.getHeight() + (int) radius, radius); + } + }); + dialogView.setClipToOutline(true); + } else { + dialogView.findViewById(R.id.relative_layout_dialog).setPadding( + 0, (int) mActivity.getResources().getDimension(R.dimen.paddingTop), 0, 0); + } + + // Expand Bottom Sheet after showing. + mDialog.setOnShowListener(dialog -> { + BottomSheetDialog d = (BottomSheetDialog) dialog; + + FrameLayout bottomSheet = d.findViewById(com.google.android.material.R.id.design_bottom_sheet); + + if (bottomSheet != null) { + BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED); + } + }); + } + + @Override + protected View createView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) { + return super.createView(inflater, container); + } + + /** + * Builder for {@link DynamicBottomSheetMaterialDialog}. + */ + public static class Builder extends AbstractDynamicDialog.Builder { + /** + * @param activity where Dynamic BottomSheet Material Dialog is to be built. + */ + public Builder(@NonNull Activity activity) { + super(activity); + } + + /** + * Builds the {@link DynamicBottomSheetMaterialDialog}. + */ + @NonNull + @Override + public DynamicBottomSheetMaterialDialog build() { + return new DynamicBottomSheetMaterialDialog( + activity, + title, + message, + isCancelable, + buttons, + animationResId, + animationFile, + animationUrl, + animationJson, + imageResId, + imageBitmap, + imageDrawable, + imageUrl + ); + } + } + + static class BottomSheetDialog extends com.google.android.material.bottomsheet.BottomSheetDialog { + BottomSheetDialog(@NonNull Context context) { + super(context, R.style.BottomSheetDialogTheme); + } + } +} diff --git a/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/DynamicMaterialDialog.java b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/DynamicMaterialDialog.java new file mode 100644 index 0000000..1a86504 --- /dev/null +++ b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/DynamicMaterialDialog.java @@ -0,0 +1,98 @@ +package dev.shreyaspatil.MaterialDialog.dynamic; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RawRes; +import androidx.appcompat.app.AlertDialog; + +import java.util.List; + +import dev.shreyaspatil.MaterialDialog.model.DialogButton; +import dev.shreyaspatil.MaterialDialog.model.DialogMessage; +import dev.shreyaspatil.MaterialDialog.model.DialogTitle; + +/** + * A {@link dev.shreyaspatil.MaterialDialog.MaterialDialog} variant whose content can be driven + * dynamically (e.g. from a backend-provided configuration): up to {@link #MAX_BUTTONS} buttons + * with arbitrary actions, and a header that is either a Lottie animation or a plain image + * (never both at once). + *

+ * Use {@link Builder} to create a new instance. + */ +@SuppressWarnings("unused") +public final class DynamicMaterialDialog extends AbstractDynamicDialog { + + private DynamicMaterialDialog(@NonNull Activity activity, + @NonNull DialogTitle title, + @NonNull DialogMessage message, + boolean cancelable, + @NonNull List buttons, + @RawRes int animationResId, + @Nullable String animationFile, + @Nullable String animationUrl, + @Nullable String animationJson, + @DrawableRes int imageResId, + @Nullable Bitmap imageBitmap, + @Nullable Drawable imageDrawable, + @Nullable String imageUrl) { + super(activity, title, message, cancelable, buttons, animationResId, animationFile, animationUrl, + animationJson, imageResId, imageBitmap, imageDrawable, imageUrl); + + // Init Dialog + final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); + + LayoutInflater inflater = mActivity.getLayoutInflater(); + + View dialogView = createView(inflater, null); + + builder.setView(dialogView); + + // Set Cancelable property + builder.setCancelable(mCancelable); + + // Create and show dialog + mDialog = builder.create(); + } + + /** + * Builder for {@link DynamicMaterialDialog}. + */ + public static class Builder extends AbstractDynamicDialog.Builder { + /** + * @param activity where Dynamic Material Dialog is to be built. + */ + public Builder(@NonNull Activity activity) { + super(activity); + } + + /** + * Builds the {@link DynamicMaterialDialog}. + */ + @NonNull + @Override + public DynamicMaterialDialog build() { + return new DynamicMaterialDialog( + activity, + title, + message, + isCancelable, + buttons, + animationResId, + animationFile, + animationUrl, + animationJson, + imageResId, + imageBitmap, + imageDrawable, + imageUrl + ); + } + } +} diff --git a/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/model/ButtonStyle.java b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/model/ButtonStyle.java new file mode 100644 index 0000000..462a0c7 --- /dev/null +++ b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/model/ButtonStyle.java @@ -0,0 +1,17 @@ +package dev.shreyaspatil.MaterialDialog.dynamic.model; + +/** + * Visual style of a button in a dynamic dialog. A button without an explicit style defaults to + * {@link #FILLED}. + */ +public enum ButtonStyle { + /** + * Filled/highlighted look. The default when no style is specified. + */ + FILLED, + + /** + * Outlined look - a lower-emphasis action. + */ + OUTLINED +} diff --git a/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/model/DynamicDialogButton.java b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/model/DynamicDialogButton.java new file mode 100644 index 0000000..739ca02 --- /dev/null +++ b/MaterialDialogDynamic/src/main/java/dev/shreyaspatil/MaterialDialog/dynamic/model/DynamicDialogButton.java @@ -0,0 +1,34 @@ +package dev.shreyaspatil.MaterialDialog.dynamic.model; + +import androidx.annotation.NonNull; + +import dev.shreyaspatil.MaterialDialog.AbstractDialog; +import dev.shreyaspatil.MaterialDialog.model.DialogButton; + +/** + * A {@link DialogButton} whose visual style ({@link ButtonStyle#FILLED} vs + * {@link ButtonStyle#OUTLINED}) is set explicitly rather than defaulting to filled. Useful when + * the button list is configured dynamically (e.g. from a backend) and some buttons should be + * lower-emphasis than others. + *

+ * A plain {@link DialogButton} still works everywhere a {@link DynamicDialogButton} does - it + * just falls back to the default style ({@link ButtonStyle#FILLED}). + */ +public class DynamicDialogButton extends DialogButton { + + private final ButtonStyle style; + + public DynamicDialogButton(@NonNull String title, int icon, @NonNull ButtonStyle style, @NonNull AbstractDialog.OnClickListener onClickListener) { + super(title, icon, onClickListener); + this.style = style; + } + + public DynamicDialogButton(@NonNull String title, @NonNull ButtonStyle style, @NonNull AbstractDialog.OnClickListener onClickListener) { + this(title, AbstractDialog.NO_ICON, style, onClickListener); + } + + @NonNull + public ButtonStyle getStyle() { + return style; + } +} diff --git a/MaterialDialogDynamic/src/main/res/layout-land/layout_dynamic_alert_dialog.xml b/MaterialDialogDynamic/src/main/res/layout-land/layout_dynamic_alert_dialog.xml new file mode 100644 index 0000000..e6bc536 --- /dev/null +++ b/MaterialDialogDynamic/src/main/res/layout-land/layout_dynamic_alert_dialog.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MaterialDialogDynamic/src/main/res/layout/layout_dynamic_alert_dialog.xml b/MaterialDialogDynamic/src/main/res/layout/layout_dynamic_alert_dialog.xml new file mode 100644 index 0000000..079204a --- /dev/null +++ b/MaterialDialogDynamic/src/main/res/layout/layout_dynamic_alert_dialog.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MaterialDialogLibrary/build.gradle b/MaterialDialogLibrary/build.gradle index f828b23..20876b9 100644 --- a/MaterialDialogLibrary/build.gradle +++ b/MaterialDialogLibrary/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'com.android.library' -apply plugin: 'com.vanniktech.maven.publish' +apply plugin: 'maven-publish' android { compileSdkVersion 31 @@ -22,7 +22,26 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + namespace 'dev.shreyaspatil.MaterialDialog' + publishing { + singleVariant('release') { + withSourcesJar() + } + } +} + +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + from components.release + groupId = GROUP + artifactId = POM_ARTIFACT_ID + version = VERSION_NAME + } + } + } } dependencies { diff --git a/MaterialDialogLibrary/src/main/AndroidManifest.xml b/MaterialDialogLibrary/src/main/AndroidManifest.xml index 8117570..cc947c5 100644 --- a/MaterialDialogLibrary/src/main/AndroidManifest.xml +++ b/MaterialDialogLibrary/src/main/AndroidManifest.xml @@ -1 +1 @@ - + diff --git a/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/AbstractDialog.java b/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/AbstractDialog.java index 9ab90fd..f2729b7 100644 --- a/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/AbstractDialog.java +++ b/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/AbstractDialog.java @@ -48,6 +48,7 @@ public abstract class AbstractDialog implements DialogInterface { protected DialogButton mNegativeButton; protected int mAnimationResId; protected String mAnimationFile; + protected String mAnimationUrl; protected LottieAnimationView mAnimationView; protected TextAlignment mTitleTextAlignment; @@ -64,7 +65,8 @@ protected AbstractDialog(@NonNull Activity mActivity, @NonNull DialogButton mPositiveButton, @NonNull DialogButton mNegativeButton, @RawRes int mAnimationResId, - @NonNull String mAnimationFile) { + @NonNull String mAnimationFile, + @NonNull String mAnimationUrl) { this.mActivity = mActivity; this.title = title; this.message = message; @@ -73,6 +75,7 @@ protected AbstractDialog(@NonNull Activity mActivity, this.mNegativeButton = mNegativeButton; this.mAnimationResId = mAnimationResId; this.mAnimationFile = mAnimationFile; + this.mAnimationUrl = mAnimationUrl; } @SuppressLint("WrongConstant") @@ -119,7 +122,7 @@ protected View createView(@NonNull LayoutInflater inflater, @Nullable ViewGroup mPositiveButton.getOnClickListener().onClick(AbstractDialog.this, BUTTON_POSITIVE) ); } else { - mPositiveButtonView.setVisibility(View.INVISIBLE); + mPositiveButtonView.setVisibility(View.GONE); } // Set Negative Button @@ -134,7 +137,7 @@ protected View createView(@NonNull LayoutInflater inflater, @Nullable ViewGroup mNegativeButton.getOnClickListener().onClick(AbstractDialog.this, BUTTON_NEGATIVE) ); } else { - mNegativeButtonView.setVisibility(View.INVISIBLE); + mNegativeButtonView.setVisibility(View.GONE); } // If Orientation is Horizontal, Hide AnimationView @@ -154,6 +157,12 @@ protected View createView(@NonNull LayoutInflater inflater, @Nullable ViewGroup mAnimationView.setAnimation(mAnimationFile); mAnimationView.playAnimation(); + // Set Animation from URL + } else if (mAnimationUrl != null) { + mAnimationView.setVisibility(View.VISIBLE); + mAnimationView.setAnimationFromUrl(mAnimationUrl); + mAnimationView.playAnimation(); + } else { mAnimationView.setVisibility(View.GONE); } @@ -332,6 +341,7 @@ public static abstract class Builder { protected DialogButton negativeButton; protected int animationResId = NO_ANIMATION; protected String animationFile; + protected String animationUrl; /** * @param activity where Material Dialog is to be built. @@ -486,6 +496,18 @@ public Builder setAnimation(@NonNull String fileName) { return this; } + /** + * It sets the json animation to the {@link com.airbnb.lottie.LottieAnimationView} by loading it from a URL. + * + * @param url URL of the Lottie JSON animation to load into {@link com.airbnb.lottie.LottieAnimationView}. + * @return this, for chaining. + */ + @NonNull + public Builder setAnimationUrl(@NonNull String url) { + this.animationUrl = url; + return this; + } + /** * Builds the dialog. */ diff --git a/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/BottomSheetMaterialDialog.java b/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/BottomSheetMaterialDialog.java index e70081a..d18dc13 100644 --- a/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/BottomSheetMaterialDialog.java +++ b/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/BottomSheetMaterialDialog.java @@ -35,8 +35,9 @@ private BottomSheetMaterialDialog(@NonNull final Activity mActivity, @NonNull DialogButton mPositiveButton, @NonNull DialogButton mNegativeButton, @RawRes int mAnimationResId, - @NonNull String mAnimationFile) { - super(mActivity, title, message, mCancelable, mPositiveButton, mNegativeButton, mAnimationResId, mAnimationFile); + @NonNull String mAnimationFile, + @NonNull String mAnimationUrl) { + super(mActivity, title, message, mCancelable, mPositiveButton, mNegativeButton, mAnimationResId, mAnimationFile, mAnimationUrl); // Init Dialog, Create Bottom Sheet Dialog mDialog = new BottomSheetDialog(mActivity); @@ -105,7 +106,8 @@ public BottomSheetMaterialDialog build() { positiveButton, negativeButton, animationResId, - animationFile + animationFile, + animationUrl ); } } diff --git a/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/MaterialDialog.java b/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/MaterialDialog.java index 2ada97f..4ae558a 100644 --- a/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/MaterialDialog.java +++ b/MaterialDialogLibrary/src/main/java/dev/shreyaspatil/MaterialDialog/MaterialDialog.java @@ -27,8 +27,9 @@ private MaterialDialog(@NonNull final Activity mActivity, @NonNull DialogButton mPositiveButton, @NonNull DialogButton mNegativeButton, @RawRes int mAnimationResId, - @NonNull String mAnimationFile) { - super(mActivity, title, message, mCancelable, mPositiveButton, mNegativeButton, mAnimationResId, mAnimationFile); + @NonNull String mAnimationFile, + @NonNull String mAnimationUrl) { + super(mActivity, title, message, mCancelable, mPositiveButton, mNegativeButton, mAnimationResId, mAnimationFile, mAnimationUrl); // Init Dialog final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); @@ -71,7 +72,8 @@ public MaterialDialog build() { positiveButton, negativeButton, animationResId, - animationFile + animationFile, + animationUrl ); } } diff --git a/MaterialDialogLibrary/src/main/res/layout/layout_alert_dialog.xml b/MaterialDialogLibrary/src/main/res/layout/layout_alert_dialog.xml index 49b40dd..7b38248 100644 --- a/MaterialDialogLibrary/src/main/res/layout/layout_alert_dialog.xml +++ b/MaterialDialogLibrary/src/main/res/layout/layout_alert_dialog.xml @@ -63,7 +63,7 @@ + xmlns:tools="http://schemas.android.com/tools"> + + { + Toast.makeText(getApplicationContext(), "Share (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }) + .addButton("Edit", (dialogInterface, which) -> { + Toast.makeText(getApplicationContext(), "Edit (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }) + .addButton("Delete", R.drawable.ic_delete, (dialogInterface, which) -> { + Toast.makeText(getApplicationContext(), "Deleted! (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }) + .addButton("Cancel", R.drawable.ic_close, (dialogInterface, which) -> { + Toast.makeText(getApplicationContext(), "Cancelled! (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }) + .setAnimationJson(ANIMATION_JSON) + .build(); + + // Image Header Dynamic Material Dialog + mImageHeaderDialog = new DynamicMaterialDialog.Builder(this) + .setTitle("New photo") + .setMessage("This dialog loads its header image from a URL, provided by a backend.") + .setCancelable(false) + .addButton("Ok", (dialogInterface, which) -> dialogInterface.dismiss()) + .addButton("Cancel", (dialogInterface, which) -> dialogInterface.dismiss()) + .setImageUrl(IMAGE_URL) + .build(); + + // Multi-Action Dynamic BottomSheet Material Dialog (4 buttons, vertical stack) + mMultiActionBottomSheetDialog = new DynamicBottomSheetMaterialDialog.Builder(this) + .setTitle("Share file") + .setMessage("Choose how you'd like to share this file.") + .setCancelable(true) + .addButton("Share", R.drawable.ic_delete, (dialogInterface, which) -> { + Toast.makeText(getApplicationContext(), "Share (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }) + .addButton("Edit", (dialogInterface, which) -> { + Toast.makeText(getApplicationContext(), "Edit (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }) + .addButton("Delete", R.drawable.ic_delete, (dialogInterface, which) -> { + Toast.makeText(getApplicationContext(), "Deleted! (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }) + .addButton("Cancel", R.drawable.ic_close, (dialogInterface, which) -> { + Toast.makeText(getApplicationContext(), "Cancelled! (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }) + .build(); + + // Image Header Dynamic BottomSheet Material Dialog + mImageHeaderBottomSheetDialog = new DynamicBottomSheetMaterialDialog.Builder(this) + .setTitle("New photo") + .setMessage("This dialog loads its header image from a URL, provided by a backend.") + .setCancelable(false) + .addButton("Ok", (dialogInterface, which) -> dialogInterface.dismiss()) + .addButton("Cancel", (dialogInterface, which) -> dialogInterface.dismiss()) + .setImageUrl(IMAGE_URL) + .build(); + + // Backend-Configured Buttons Dialog - buttons built as a List, e.g. from a + // backend response, and set on the Builder in one call via setButtons(...). Every button + // defaults to FILLED - "Approve" is explicitly OUTLINED via DynamicDialogButton so "Reject" + // (explicitly FILLED) and "Ask later" (defaulted FILLED) both stand out as the main actions. + AbstractDialog.OnClickListener backendAction = (dialogInterface, which) -> { + Toast.makeText(getApplicationContext(), "Backend action (" + which + ")", Toast.LENGTH_SHORT).show(); + dialogInterface.dismiss(); + }; + mBackendButtonsDialog = new DynamicMaterialDialog.Builder(this) + .setTitle("Approve request?") + .setMessage("This button list was configured dynamically, e.g. from a backend response.") + .setCancelable(true) + .setButtons(Arrays.asList( + new DynamicDialogButton("Approve", ButtonStyle.OUTLINED, backendAction), + new DynamicDialogButton("Reject", ButtonStyle.FILLED, backendAction), + new DialogButton("Ask later", DynamicMaterialDialog.NO_ICON, backendAction) + )) + .build(); + + // Single Button Dynamic BottomSheet Material Dialog + mSingleButtonBottomSheetDialog = new DynamicBottomSheetMaterialDialog.Builder(this) + .setTitle("Got it?") + .setMessage("A single full-width button.") + .setCancelable(true) + .addButton("Ok", (dialogInterface, which) -> dialogInterface.dismiss()) + .build(); + + // Raw Animation Dynamic Material Dialog - setAnimation(@RawRes int) + mRawAnimationDialog = new DynamicMaterialDialog.Builder(this) + .setTitle("Delete?") + .setMessage("This dialog's animation is loaded from a raw resource.") + .setCancelable(false) + .addButton("Delete", R.drawable.ic_delete, (dialogInterface, which) -> dialogInterface.dismiss()) + .addButton("Cancel", R.drawable.ic_close, (dialogInterface, which) -> dialogInterface.dismiss()) + .setAnimation(R.raw.delete_anim) + .build(); + + // Asset Animation Dynamic BottomSheet Material Dialog - setAnimation(String fileName) + mAssetAnimationBottomSheetDialog = new DynamicBottomSheetMaterialDialog.Builder(this) + .setTitle("Delete?") + .setMessage("This dialog's animation is loaded from an assets file.") + .setCancelable(false) + .addButton("Delete", R.drawable.ic_delete, (dialogInterface, which) -> dialogInterface.dismiss()) + .addButton("Cancel", R.drawable.ic_close, (dialogInterface, which) -> dialogInterface.dismiss()) + .setAnimation("delete_anim.json") + .build(); + + // URL Animation Dynamic Material Dialog - setAnimationUrl(String) + mUrlAnimationDialog = new DynamicMaterialDialog.Builder(this) + .setTitle("Delete?") + .setMessage("This dialog's animation is loaded from a URL.") + .setCancelable(false) + .addButton("Delete", R.drawable.ic_delete, (dialogInterface, which) -> dialogInterface.dismiss()) + .addButton("Cancel", R.drawable.ic_close, (dialogInterface, which) -> dialogInterface.dismiss()) + .setAnimationUrl(ANIMATION_URL) + .build(); + + // Drawable Image Header Dynamic BottomSheet Material Dialog - setImage(@DrawableRes int) + mDrawableImageBottomSheetDialog = new DynamicBottomSheetMaterialDialog.Builder(this) + .setTitle("New photo") + .setMessage("This dialog's header image is a drawable resource.") + .setCancelable(false) + .addButton("Ok", (dialogInterface, which) -> dialogInterface.dismiss()) + .addButton("Cancel", (dialogInterface, which) -> dialogInterface.dismiss()) + .setImage(R.drawable.ic_launcher_background) + .build(); + + // Bitmap Image Header Dynamic Material Dialog - setImage(Bitmap) + // Generated in-memory here to stand in for a Bitmap an app might decode from disk/network - + // BitmapFactory.decodeResource() only works on raster (PNG/JPEG) resources, not vector + // drawables or adaptive-icon XML, so it's not a fit for this demo's drawable resources. + Bitmap headerBitmap = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888); + new Canvas(headerBitmap).drawColor(0xFF1E88E5); + mBitmapImageDialog = new DynamicMaterialDialog.Builder(this) + .setTitle("New photo") + .setMessage("This dialog's header image is a Bitmap, e.g. decoded from disk or network.") + .setCancelable(false) + .addButton("Ok", (dialogInterface, which) -> dialogInterface.dismiss()) + .addButton("Cancel", (dialogInterface, which) -> dialogInterface.dismiss()) + .setImage(headerBitmap) + .build(); + + // Drawable Object Image Header Dynamic BottomSheet Material Dialog - setImage(Drawable) + Drawable headerDrawable = ContextCompat.getDrawable(this, R.drawable.ic_launcher_foreground); + mDrawableObjectImageBottomSheetDialog = new DynamicBottomSheetMaterialDialog.Builder(this) + .setTitle("New photo") + .setMessage("This dialog's header image is a Drawable object.") + .setCancelable(false) + .addButton("Ok", (dialogInterface, which) -> dialogInterface.dismiss()) + .addButton("Cancel", (dialogInterface, which) -> dialogInterface.dismiss()) + .setImage(headerDrawable) + .build(); + mButtonSimpleDialog.setOnClickListener(this); mButtonBottomSheetDialog.setOnClickListener(this); mButtonAnimatedDialog.setOnClickListener(this); mButtonAnimatedBottomSheetDialog.setOnClickListener(this); + mButtonUrlAnimatedDialog.setOnClickListener(this); + mButtonMultiActionDialog.setOnClickListener(this); + mButtonImageDialog.setOnClickListener(this); + mButtonMultiActionBottomSheetDialog.setOnClickListener(this); + mButtonImageBottomSheetDialog.setOnClickListener(this); + mButtonBackendButtonsDialog.setOnClickListener(this); + mButtonSingleButtonBottomSheetDialog.setOnClickListener(this); + mButtonRawAnimationDialog.setOnClickListener(this); + mButtonAssetAnimationBottomSheetDialog.setOnClickListener(this); + mButtonUrlAnimationDialog.setOnClickListener(this); + mButtonDrawableImageBottomSheetDialog.setOnClickListener(this); + mButtonBitmapImageDialog.setOnClickListener(this); + mButtonDrawableObjectImageBottomSheetDialog.setOnClickListener(this); } @SuppressLint("NonConstantResourceId") @@ -145,6 +388,58 @@ public void onClick(View view) { case R.id.button_animated_bottomsheet_dialog: mAnimatedBottomSheetDialog.show(); break; + + case R.id.button_url_animated_dialog: + mUrlAnimatedDialog.show(); + break; + + case R.id.button_multi_action_dialog: + mMultiActionDialog.show(); + break; + + case R.id.button_image_dialog: + mImageHeaderDialog.show(); + break; + + case R.id.button_multi_action_bottomsheet_dialog: + mMultiActionBottomSheetDialog.show(); + break; + + case R.id.button_image_bottomsheet_dialog: + mImageHeaderBottomSheetDialog.show(); + break; + + case R.id.button_backend_buttons_dialog: + mBackendButtonsDialog.show(); + break; + + case R.id.button_single_button_bottomsheet_dialog: + mSingleButtonBottomSheetDialog.show(); + break; + + case R.id.button_raw_animation_dialog: + mRawAnimationDialog.show(); + break; + + case R.id.button_asset_animation_bottomsheet_dialog: + mAssetAnimationBottomSheetDialog.show(); + break; + + case R.id.button_url_animation_dialog: + mUrlAnimationDialog.show(); + break; + + case R.id.button_drawable_image_bottomsheet_dialog: + mDrawableImageBottomSheetDialog.show(); + break; + + case R.id.button_bitmap_image_dialog: + mBitmapImageDialog.show(); + break; + + case R.id.button_drawable_object_image_bottomsheet_dialog: + mDrawableObjectImageBottomSheetDialog.show(); + break; } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 46cf47e..80c2792 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -5,48 +5,171 @@ android:layout_height="match_parent" tools:context="dev.shreyaspatil.MaterialDialogExample.MainActivity"> - + android:layout_height="match_parent"> - - - + android:orientation="vertical" + android:padding="16dp"> - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/raw/delete_anim.json b/app/src/main/res/raw/delete_anim.json new file mode 100644 index 0000000..30a1612 --- /dev/null +++ b/app/src/main/res/raw/delete_anim.json @@ -0,0 +1 @@ +{"v":"5.2.1","fr":60,"ip":0,"op":382,"w":411,"h":162,"nm":"*delete 1_v6 (one file at a time) 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":315,"s":[250,77.144,0],"e":[250,69.144,0],"to":[0,-1.33333337306976,0],"ti":[0,1.33333337306976,0]},{"t":321}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-16.75,-12.25],[-90.5,1.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.037],"y":[1.028]},"o":{"x":[1],"y":[0]},"n":["0p037_1p028_1_0"],"t":316.217,"s":[0],"e":[100]},{"t":325}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.259],"y":[1]},"o":{"x":[0.883],"y":[0]},"n":["0p259_1_0p883_0"],"t":309,"s":[0],"e":[100]},{"t":323.615234375}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0_1_0p333_0"],"t":311,"s":[0],"e":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0p667_1_1_0"],"t":317.42,"s":[5],"e":[2]},{"t":322.47265625}],"ix":5},"lc":3,"lj":3,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":308,"op":325,"st":255,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":240,"s":[76,36.144,0],"e":[76,34.144,0],"to":[0,-0.33333334326744,0],"ti":[0,0.33333334326744,0]},{"t":246}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[92.5,40.25],[178.5,18.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.037],"y":[1.028]},"o":{"x":[1],"y":[0]},"n":["0p037_1p028_1_0"],"t":243.217,"s":[0],"e":[100]},{"t":252}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.259],"y":[1]},"o":{"x":[0.883],"y":[0]},"n":["0p259_1_0p883_0"],"t":236,"s":[0],"e":[100]},{"t":250.615234375}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0_1_0p333_0"],"t":238,"s":[0],"e":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0p667_1_1_0"],"t":244.42,"s":[5],"e":[2]},{"t":249.47265625}],"ix":5},"lc":3,"lj":3,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":233,"op":258,"st":154,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":166,"s":[171,53.144,0],"e":[171,54.144,0],"to":[0,0.16666667163372,0],"ti":[0,-0.16666667163372,0]},{"t":172}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-2.5,0.25],[78.5,29.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.037],"y":[1.028]},"o":{"x":[1],"y":[0]},"n":["0p037_1p028_1_0"],"t":169.217,"s":[0],"e":[100]},{"t":178}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.259],"y":[1]},"o":{"x":[0.883],"y":[0]},"n":["0p259_1_0p883_0"],"t":162,"s":[0],"e":[100]},{"t":176.615234375}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0_1_0p333_0"],"t":164,"s":[0],"e":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0p667_1_1_0"],"t":170.42,"s":[5],"e":[2]},{"t":175.47265625}],"ix":5},"lc":3,"lj":3,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":158,"op":177,"st":80,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":90,"s":[250,84.144,0],"e":[250,82.144,0],"to":[0,-0.33333334326744,0],"ti":[0,0.33333334326744,0]},{"t":96}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-89.5,15.25],[-13.5,-11.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.037],"y":[1.028]},"o":{"x":[1],"y":[0]},"n":["0p037_1p028_1_0"],"t":91.217,"s":[0],"e":[100]},{"t":100}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.259],"y":[1]},"o":{"x":[0.883],"y":[0]},"n":["0p259_1_0p883_0"],"t":84,"s":[0],"e":[100]},{"t":98.615234375}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0_1_0p333_0"],"t":86,"s":[0],"e":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0p667_1_1_0"],"t":92.42,"s":[5],"e":[2]},{"t":97.47265625}],"ix":5},"lc":3,"lj":3,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":83,"op":100,"st":30,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":12,"s":[335,64.144,0],"e":[335,62.144,0],"to":[0,-0.33333334326744,0],"ti":[0,0.33333334326744,0]},{"t":18}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-172.5,-26.75],[-101.5,11.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.037],"y":[1.028]},"o":{"x":[1],"y":[0]},"n":["0p037_1p028_1_0"],"t":15.217,"s":[0],"e":[100]},{"t":24}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.259],"y":[1]},"o":{"x":[0.883],"y":[0]},"n":["0p259_1_0p883_0"],"t":8,"s":[0],"e":[100]},{"t":22.615234375}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0_1_0p333_0"],"t":10,"s":[0],"e":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0p667_1_1_0"],"t":16.42,"s":[5],"e":[2]},{"t":21.47265625}],"ix":5},"lc":3,"lj":3,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":7,"op":22,"st":-25,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":27,"s":[204.5,120.5,0],"e":[204.5,152.5,0],"to":[0,5.33333349227905,0],"ti":[0,-5.33333349227905,0]},{"t":94}],"ix":2},"a":{"a":0,"k":[350.021,85.415,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-4.588,0.996],[0,0],[0.996,4.588],[0,0],[0,0],[1.002,-0.897],[0,0],[0.366,1.749],[0,0],[0,0]],"o":[[0.996,4.588],[0,0],[4.588,-0.996],[0,0],[0,0],[0.791,0.905],[0,0],[-1.331,1.192],[0,0],[0,0],[0,0]],"v":[[178.304,-79.142],[188.562,-72.589],[209.943,-77.31],[216.497,-87.569],[213.997,-98.925],[205.933,-97.487],[205.735,-94.227],[193.955,-83.682],[190.135,-84.935],[188.169,-94.32],[175.453,-92.052]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.956862747669,0.560784339905,0.694117665291,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.232,"y":0},"n":"0p833_0p833_0p232_0","t":318,"s":[195.612,-96.089],"e":[204.612,-54.089],"to":[1.5,7],"ti":[0,0]},{"t":358}],"ix":2},"a":{"a":0,"k":[195.512,-95.543],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":324,"s":[0],"e":[23]},{"t":346}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":328,"s":[100],"e":[0]},{"t":342}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"pink-bottom","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-1.698,-0.557],[0,0],[-0.26,-0.297],[0,0],[0,0],[4.59,-1.036],[0,0],[-0.996,-4.588]],"o":[[0,0],[0,0],[-0.366,-1.749],[0,0],[0.42,0.138],[0,0],[0,0],[-1.541,-4.898],[0,0],[-4.588,0.996],[0,0]],"v":[[175.453,-92.052],[188.169,-94.32],[186.893,-100.409],[189.889,-103.09],[204.91,-98.161],[205.933,-97.487],[213.997,-98.925],[211.794,-108.929],[201.496,-115.485],[180.136,-110.782],[173.582,-100.524]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.956862747669,0.560784339905,0.694117665291,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.232,"y":0},"n":"0_1_0p232_0","t":317,"s":[193.898,-96.145],"e":[193.898,-87.145],"to":[0,1.5],"ti":[0,-1.5]},{"t":363}],"ix":2},"a":{"a":0,"k":[193.883,-95.926],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":333,"s":[100],"e":[0]},{"t":347}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"pink-top","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.118,"y":0},"n":"0_1_0p118_0","t":294,"s":[343.625,271],"e":[343.625,-0.105],"to":[0,-45.1841011047363],"ti":[0,28.8098964691162]},{"i":{"x":0.735,"y":0.145},"o":{"x":0.407,"y":0},"n":"0p735_0p145_0p407_0","t":319,"s":[343.625,-0.105],"e":[343.625,3.233],"to":[0,-2.11750984191895],"ti":[0,1.01433336734772]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.921,"y":0.412},"n":"0p833_0p833_0p921_0p412","t":328,"s":[343.625,3.233],"e":[343.625,70.818],"to":[0,-12.7862358093262],"ti":[0,-9.45729160308838]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":348,"s":[343.625,70.818],"e":[343.625,226.141],"to":[0,4.14847373962402],"ti":[0,0]},{"t":372}],"ix":2},"a":{"a":0,"k":[195.427,-93.217],"ix":1},"s":{"a":0,"k":[183,183],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":320,"s":[0],"e":[18]},{"t":353}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":294,"s":[0],"e":[100]},{"t":305}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"pink","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[6.116,0.489],[-0.489,6.116],[-6.116,-0.489],[-0.534,-0.154],[0,0],[0,0],[0,0],[-8.637,-0.696],[0,0],[-0.696,8.637],[0,0]],"o":[[0,0],[-0.489,6.116],[-6.116,-0.489],[0.489,-6.116],[0.537,0.038],[0,0],[0,0],[0,0],[-0.696,8.637],[0,0],[8.637,0.696],[0,0],[0,0]],"v":[[494.812,91.385],[494.021,101.404],[482.008,111.637],[471.774,99.624],[483.788,89.391],[485.418,89.668],[485.427,89.551],[452.375,83.094],[450.485,107.671],[465.1,124.735],[505.394,127.834],[522.459,113.219],[523.714,97.031]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917647063732,0.262745112181,0.207843139768,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":234,"s":[488,82],"e":[488,82],"to":[0,0],"ti":[0,0]},{"i":{"x":0.612,"y":0.775},"o":{"x":0.333,"y":0},"n":"0p612_0p775_0p333_0","t":250,"s":[488,82],"e":[474.977,110.19],"to":[0,0],"ti":[0.01015185378492,-4.91906404495239]},{"i":{"x":0.667,"y":1},"o":{"x":0.414,"y":0.444},"n":"0p667_1_0p414_0p444","t":272,"s":[474.977,110.19],"e":[487.939,111.338],"to":[-0.01736182533205,8.4126443862915],"ti":[0,0]},{"t":293}],"ix":2},"a":{"a":0,"k":[487.939,84.338],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":245,"s":[0],"e":[9.975]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":266,"s":[9.975],"e":[21]},{"t":286}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.842],"y":[1]},"o":{"x":[0.189],"y":[0]},"n":["0p842_1_0p189_0"],"t":254,"s":[100],"e":[0]},{"t":268}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"R-bottom","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-8.637,-0.696],[0,0],[-0.101,-9.477],[0,0],[0,0],[0,0],[0,0],[-0.084,1.425],[0,0],[1.447,0.132],[0,0],[0.084,-1.425],[0,0]],"o":[[0,0],[0.696,-8.637],[0,0],[8.662,0.626],[0,0],[0,0],[0,0],[0,0],[1.447,0.132],[0,0],[0.059,-1.355],[0,0],[-1.447,-0.132],[0,0],[0,0]],"v":[[452.375,73.594],[453.584,57.876],[470.649,43.262],[510.896,46.382],[525.58,63.472],[523.714,87.531],[494.812,81.885],[495.497,73.205],[501.427,73.666],[504.227,71.26],[504.92,62.74],[502.467,59.962],[489.698,58.946],[486.897,61.352],[485.427,80.051]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917647063732,0.262745112181,0.207843139768,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":234,"s":[488.392,88.1],"e":[488.392,88.1],"to":[0,0],"ti":[0,0]},{"i":{"x":0.19,"y":0},"o":{"x":0.167,"y":0.167},"n":"0p19_0_0p167_0p167","t":245,"s":[488.392,88.1],"e":[488.392,87.204],"to":[0,-1.09112739562988],"ti":[0,1.9465696811676]},{"i":{"x":0.564,"y":1},"o":{"x":0.241,"y":0.075},"n":"0p564_1_0p241_0p075","t":262,"s":[488.392,87.204],"e":[488.392,80.356],"to":[0,-0.35584533214569],"ti":[0,0.19946503639221]},{"t":282}],"ix":2},"a":{"a":0,"k":[488.392,80.356],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":234,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":258,"s":[100],"e":[0]},{"t":272}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"R-top","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.118,"y":0},"n":"0_1_0p118_0","t":221,"s":[354.371,179],"e":[354.371,-3.898],"to":[0,-30.482931137085],"ti":[0,29.275390625]},{"i":{"x":0.735,"y":0.234},"o":{"x":0.407,"y":0},"n":"0p735_0p234_0p407_0","t":247,"s":[354.371,-3.898],"e":[354.371,-0.579],"to":[0,-2.10441112518311],"ti":[0,1.03862333297729]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.921,"y":0.219},"n":"0p833_0p833_0p921_0p219","t":255,"s":[354.371,-0.579],"e":[354.371,192.054],"to":[0,-13.4101247787476],"ti":[0,0]},{"t":284}],"ix":2},"a":{"a":0,"k":[487.991,86.765],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":243.639,"s":[-28],"e":[0]},{"t":303}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":221,"s":[0],"e":[100]},{"t":235}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"red","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.185,-0.472],[0,0],[0.472,2.185],[-2.185,0.472],[0,0],[-0.472,-2.185]],"o":[[0,0],[-2.185,0.472],[-0.472,-2.185],[0,0],[2.185,-0.472],[0.472,2.185]],"v":[[408.261,79.042],[371.922,88.388],[367.071,85.477],[369.981,80.625],[406.32,71.279],[411.172,74.19]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.472,2.185],[-2.186,0.472],[0,0],[-0.472,-2.185],[1.897,-0.586],[0,0]],"o":[[-0.472,-2.185],[0,0],[2.185,-0.472],[0.586,1.897],[0,0],[-2.186,0.472]],"v":[[363.311,71.333],[366.222,66.481],[402.561,57.135],[407.412,60.046],[404.501,64.898],[368.163,74.244]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[7.762,-1.941],[0,0],[-2.343,-7.588],[0,0],[0,0]],"o":[[-2.055,-7.474],[0,0],[-7.762,1.941],[0,0],[0,0],[0,0]],"v":[[416.704,53.376],[399.09,43.105],[362.751,52.451],[352.48,70.066],[358.525,93.568],[423.472,79.69]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.645,"y":0},"n":"0_1_0p645_0","t":168,"s":[390.914,90.531],"e":[388.914,87.531],"to":[-0.33333334326744,-0.5],"ti":[0.33333334326744,0.5]},{"t":207}],"ix":2},"a":{"a":0,"k":[388.914,87.531],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":180,"s":[100],"e":[0]},{"t":194}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B-top","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.299,-0.761],[0,0],[0.472,2.185],[-2.185,0.472],[0,0],[-0.472,-2.185]],"o":[[0,0],[-2.185,0.472],[-0.472,-2.185],[0,0],[2.186,-0.472],[0.586,1.897]],"v":[[395.416,105.568],[377.304,110.097],[372.452,107.186],[375.363,102.334],[393.475,97.805],[398.327,100.716]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-7.588,2.343],[0,0],[2.343,7.588]],"o":[[0,0],[0,0],[1.941,7.762],[0,0],[7.762,-1.941],[0,0]],"v":[[425.208,86.967],[360.26,100.844],[363.562,113.681],[381.177,123.952],[417.515,114.606],[427.786,96.991]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.827},"o":{"x":0.232,"y":0},"n":"0p833_0p827_0p232_0","t":168,"s":[395.113,87.676],"e":[390.113,127.676],"to":[-0.83333331346512,6.66666650772095],"ti":[0,0]},{"t":208}],"ix":2},"a":{"a":0,"k":[395.113,92.676],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":168,"s":[0],"e":[-16]},{"t":207}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":187,"s":[100],"e":[0]},{"t":201}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"B-bottom","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.118,"y":0},"n":"0_1_0p118_0","t":148,"s":[354.371,179],"e":[354.371,-3.898],"to":[0,-30.482931137085],"ti":[0,29.275390625]},{"i":{"x":0.735,"y":0.33},"o":{"x":0.407,"y":0},"n":"0p735_0p33_0p407_0","t":174,"s":[354.371,-3.898],"e":[354.371,-0.579],"to":[0,-2.10441112518311],"ti":[0,1.03862333297729]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.921,"y":0.448},"n":"0p833_0p833_0p921_0p448","t":181,"s":[354.371,-0.579],"e":[354.371,84.701],"to":[0,-13.4101247787476],"ti":[0,-9.47378826141357]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":208,"s":[354.371,84.701],"e":[354.371,240.348],"to":[0,10.2075395584106],"ti":[0,0]},{"t":218}],"ix":2},"a":{"a":0,"k":[391.371,84.348],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":172.639,"s":[34],"e":[0]},{"t":236}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":150,"s":[0],"e":[100]},{"t":160}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"blue","np":2,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.015,4.149],[-4.149,-0.015],[0.015,-4.149],[4.149,0.015]],"o":[[0.015,-4.149],[4.149,0.015],[-0.015,4.149],[-4.149,-0.015]],"v":[[278.882,70.529],[286.421,63.044],[293.906,70.582],[286.368,78.068]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.719,0.224],[0,0],[0.151,-8.069],[0,0],[0,0],[0,0],[-6.172,0.186],[0,0],[-0.186,-6.172],[0,0],[0,0],[0,0]],"o":[[0,0],[-8.069,-0.151],[0,0],[0,0],[0,0],[0.164,-6.245],[0,0],[6.245,0.164],[0,0],[0,0],[0,0],[-0.199,-7.996]],"v":[[317.79,48.592],[280.888,48.585],[266.332,62.934],[266.327,86.9],[272.489,86.555],[272.531,66.396],[284.021,54.875],[313.627,54.937],[325.147,66.428],[325.154,83.604],[332.135,83.213],[332.139,63.149]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[1.315,-2.465],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[-1.282,-2.656]],"v":[[306.466,73.23],[300.963,84.959],[317.718,84.02],[312.711,73.395]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921571374,0.658823549747,0.32549020648,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.232,"y":0},"n":"0_1_0p232_0","t":94,"s":[299.484,88.078],"e":[299.484,86.078],"to":[0,-0.33333334326744],"ti":[0,0.33333334326744]},{"t":133}],"ix":2},"a":{"a":0,"k":[299.484,86.078],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":115,"s":[100],"e":[0]},{"t":129}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"G-top","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0.555,-0.846],[0.073,0.35],[0,0],[0,0],[0,0],[0,0],[0.97,0.219],[0,0],[0.437,-0.82],[0,0],[0.086,2.174],[0,0],[0,0],[0,0],[-8.069,-0.151],[0,0],[-0.151,8.069],[0,0]],"o":[[0,0],[-0.132,1.123],[-0.073,-0.35],[0,0],[0,0],[0,0],[0,0],[-0.513,-1.063],[0,0],[-0.78,0.272],[0,0],[-1.137,-1.956],[0,0],[0,0],[0,0],[-0.151,8.069],[0,0],[8.069,0.151],[0,0],[0,0]],"v":[[325.154,92.77],[325.158,105.55],[324.617,108.22],[324.472,107.52],[317.718,93.187],[300.963,94.126],[293.551,109.923],[287.562,96.919],[285.185,95.01],[283.231,95.12],[281.317,96.754],[274.479,111.327],[272.469,105.168],[272.489,95.722],[266.327,96.067],[266.324,109.002],[280.673,123.558],[317.575,123.566],[332.131,109.217],[332.135,92.379]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921571374,0.658823549747,0.32549020648,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.829},"o":{"x":0.232,"y":0},"n":"0p833_0p829_0p232_0","t":94,"s":[298.027,85.203],"e":[302.027,126.203],"to":[0.66666668653488,6.83333349227905],"ti":[0,0]},{"t":134}],"ix":2},"a":{"a":0,"k":[298.027,93.203],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":93,"s":[0],"e":[23]},{"t":133}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":107,"s":[100],"e":[0]},{"t":121}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"G-bottom","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.118,"y":0},"n":"0_1_0p118_0","t":76,"s":[343.625,179],"e":[343.625,15.895],"to":[0,-27.184103012085],"ti":[0,28.8098964691162]},{"i":{"x":0.735,"y":0.145},"o":{"x":0.407,"y":0},"n":"0p735_0p145_0p407_0","t":101,"s":[343.625,15.895],"e":[343.625,19.233],"to":[0,-2.11750984191895],"ti":[0,1.01433336734772]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.921,"y":0.495},"n":"0p833_0p833_0p921_0p495","t":110,"s":[343.625,19.233],"e":[343.625,86.818],"to":[0,-12.7862358093262],"ti":[0,-9.45729160308838]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":134,"s":[343.625,86.818],"e":[343.625,242.141],"to":[0,4.14847373962402],"ti":[0,0]},{"t":158}],"ix":2},"a":{"a":0,"k":[297.625,87.141],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":100,"s":[-19],"e":[0]},{"t":165}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":73,"s":[0],"e":[100]},{"t":83}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"green","np":2,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-7.207,0.858],[0,0],[0.857,7.207]],"o":[[0,0],[0,0],[0,0],[0.857,7.207],[0,0],[7.207,-0.858],[0,0]],"v":[[249.423,87.922],[178.573,86.486],[179.305,92.639],[181.181,107.728],[196.013,119.168],[239.327,113.721],[250.767,98.888]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.992156863213,0.792156875134,0.250980407,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.232,"y":0},"n":"0p833_0p833_0p232_0","t":14,"s":[211.4,81.541],"e":[211.4,125.541],"to":[0,7.33333349227905],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p833_1_0p167_0p167","t":54,"s":[211.4,125.541],"e":[211.4,81.541],"to":[0,0],"ti":[0,7.33333349227905]},{"t":115}],"ix":2},"a":{"a":0,"k":[213.398,89.535],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14,"s":[0],"e":[-14]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":53,"s":[-14],"e":[0]},{"t":115}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":41,"s":[100],"e":[0]},{"t":55}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Y-bottom","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-6.533,0.697],[-0.697,-6.533],[0,0],[0,0],[-1.089,-7.58],[0,0],[0,0]],"o":[[-1.07,-6.302],[6.302,-1.07],[0,0],[0,0],[7.509,-0.787],[0,0],[0,0],[0,0]],"v":[[174.616,60.811],[184.726,47.578],[197.96,57.687],[198.28,59.036],[231.156,54.644],[246.22,66.456],[247.609,77.786],[176.759,76.35]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.992156863213,0.792156875134,0.250980407,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.232,"y":0},"n":"0_1_0p232_0","t":14,"s":[210.742,81.18],"e":[210.742,78.18],"to":[0,-0.5],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":53,"s":[210.742,78.18],"e":[210.742,81.18],"to":[0,0],"ti":[0,-0.5]},{"t":115}],"ix":2},"a":{"a":0,"k":[210.742,78.18],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":29,"s":[100],"e":[0]},{"t":43}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Y-top","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.118,"y":0},"n":"0_1_0p118_0","t":0,"s":[341.398,179],"e":[341.398,21.665],"to":[0,-26.2224674224854],"ti":[0,29.3056640625]},{"i":{"x":0.735,"y":0.166},"o":{"x":0.407,"y":0},"n":"0p735_0p166_0p407_0","t":20,"s":[341.398,21.665],"e":[341.398,26.857],"to":[0,-2.10361814498901],"ti":[0,1.04014849662781]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.921,"y":0.468},"n":"0p833_0p833_0p921_0p468","t":32,"s":[341.398,26.857],"e":[341.398,88.89],"to":[0,-13.4502382278442],"ti":[0,-9.47482299804688]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":53,"s":[341.398,88.89],"e":[341.398,239.536],"to":[0,10.2075395584106],"ti":[0,0]},{"t":67}],"ix":2},"a":{"a":0,"k":[211.398,84.166],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":23.639,"s":[28],"e":[0]},{"t":87}],"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":-3,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":7,"s":[100],"e":[0]},{"t":109}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"yellow","np":2,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":400,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"BACKGROUND","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[205.5,81,0],"ix":2},"a":{"a":0,"k":[183.707,-97.04,0],"ix":1},"s":{"a":0,"k":[153.919,153.919,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[50.385,-129.971],[50.385,-96.654],[133.718,-103.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[50.385,-52.432],[142.218,-84.04],[50.385,-75.193]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[172.201,-44.873],[172.052,-63.206],[161.211,-44.873]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[205.337,-44.873],[195.385,-61.873],[194.812,-44.873]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[317.218,-74.888],[222.218,-84.04],[317.218,-51.342]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ind":5,"ty":"sh","ix":6,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[317.218,-130.746],[239.718,-103.873],[317.218,-96.575]],"c":true},"ix":2},"nm":"Path 6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":6,"ty":"sh","ix":7,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[240.192,-149.54],[220.718,-112.54],[274.204,-149.54]],"c":true},"ix":2},"nm":"Path 7","mn":"ADBE Vector Shape - Group","hd":false},{"ind":7,"ty":"sh","ix":8,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[194.781,-149.54],[196.718,-121.206],[212.489,-149.54]],"c":true},"ix":2},"nm":"Path 8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":8,"ty":"sh","ix":9,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[153.969,-149.54],[170.385,-120.206],[171.852,-149.54]],"c":true},"ix":2},"nm":"Path 9","mn":"ADBE Vector Shape - Group","hd":false},{"ind":9,"ty":"sh","ix":10,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[90.233,-149.54],[143.718,-112.54],[124.245,-149.54]],"c":true},"ix":2},"nm":"Path 10","mn":"ADBE Vector Shape - Group","hd":false},{"ind":10,"ty":"sh","ix":11,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[277.654,-44.54],[208.218,-76.04],[246.903,-44.54]],"c":true},"ix":2},"nm":"Path 11","mn":"ADBE Vector Shape - Group","hd":false},{"ind":11,"ty":"sh","ix":12,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[86.783,-44.54],[156.218,-76.04],[117.534,-44.54]],"c":true},"ix":2},"nm":"Path 12","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333337307,0.933333337307,0.933333337307,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":13,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[317.218,-44.54],[50.195,-44.54],[50.195,-149.133],[317.218,-149.133]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.960784316063,0.960784316063,0.960784316063,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[183.676,-97.296],"ix":2},"a":{"a":0,"k":[183.676,-97.296],"ix":1},"s":{"a":0,"k":[113,113],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[{"tm":221,"cm":"0","dr":0},{"tm":381,"cm":"1","dr":0}]} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 21498aa..5b145f9 100644 --- a/build.gradle +++ b/build.gradle @@ -6,8 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.4' - classpath 'com.vanniktech:gradle-maven-publish-plugin:0.18.0' + classpath 'com.android.tools.build:gradle:8.0.0' } } diff --git a/gradle.properties b/gradle.properties index ba49c34..1e13ee2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ android.enableJetifier=true # Maven Publish Details GROUP=dev.shreyaspatil.MaterialDialog POM_ARTIFACT_ID=MaterialDialog -VERSION_NAME=2.2.3 +VERSION_NAME=2.3.0 POM_NAME=MaterialDialog-Android POM_DESCRIPTION=Android Library to implement animated, beautiful, stylish Material Dialog in android apps easily. POM_INCEPTION_YEAR=2021 @@ -33,4 +33,7 @@ POM_LICENCE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt POM_LICENCE_DIST=https://github.com/PatilShreyas/MaterialDialog-Android/blob/master/LICENSE POM_DEVELOPER_ID=patilshreyas POM_DEVELOPER_NAME=Shreyas Patil -POM_DEVELOPER_URL=https://github.com/patilshreyas/ \ No newline at end of file +POM_DEVELOPER_URL=https://github.com/patilshreyas/ +android.nonTransitiveRClass=false +android.defaults.buildfeatures.buildconfig=true +android.nonFinalResIds=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a66dd2d..0377cae 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sat Jan 08 10:47:24 IST 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..efde7bf --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +jdk: + - openjdk17 diff --git a/settings.gradle b/settings.gradle index 1037ce9..e325957 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':MaterialDialogLibrary' +include ':app', ':MaterialDialogLibrary', ':MaterialDialogDynamic'