diff --git a/CHANGELOG.md b/CHANGELOG.md index c04098c..c804ba2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Change Log All notable changes to this project will be documented in this file. +## 7.0.0 - 27/01/2021 +* Added support in Dialog. + ## 6.2.1 - 03/09/2020 * Updated negative margin to fix overshoot on Samsung S10 diff --git a/alerter/build.gradle b/alerter/build.gradle index 96a589e..34c0cf5 100644 --- a/alerter/build.gradle +++ b/alerter/build.gradle @@ -14,7 +14,7 @@ apply from: rootProject.file('quality.gradle') final String GROUP_ID = "com.tapadoo.android" -final String VERSION = "6.2.1" +final String VERSION = "7.0.0" final String DESCRIPTION = "An Android Alerting Library" final String GITHUB_URL = "https://github.com/Tapadoo/Alerter" @@ -124,9 +124,9 @@ configurations { } dependencies { - implementation "androidx.appcompat:appcompat:1.1.0" - implementation "androidx.annotation:annotation:1.1.0" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "androidx.annotation:annotation:1.1.0" + implementation "androidx.appcompat:appcompat:1.2.0" // Local Unit Tests - in src/test testImplementation 'junit:junit:4.12' diff --git a/alerter/src/main/java/com/tapadoo/alerter/Alerter.kt b/alerter/src/main/java/com/tapadoo/alerter/Alerter.kt index 6d85787..95ea9e9 100644 --- a/alerter/src/main/java/com/tapadoo/alerter/Alerter.kt +++ b/alerter/src/main/java/com/tapadoo/alerter/Alerter.kt @@ -1,6 +1,7 @@ package com.tapadoo.alerter import android.app.Activity +import android.app.Dialog import android.graphics.Bitmap import android.graphics.ColorFilter import android.graphics.PorterDuff @@ -8,10 +9,12 @@ import android.graphics.Typeface import android.graphics.drawable.Drawable import android.media.RingtoneManager import android.net.Uri +import android.os.Looper import android.view.View import android.view.ViewGroup import android.view.animation.AnimationUtils import androidx.annotation.* +import androidx.appcompat.app.AppCompatDialog import androidx.core.content.ContextCompat import androidx.core.view.ViewCompat import java.lang.ref.WeakReference @@ -32,22 +35,6 @@ class Alerter private constructor() { */ private var alert: Alert? = null - /** - * Get the enclosing Decor View - * - * @return The Decor View of the Activity the Alerter was called from - */ - private val activityDecorView: ViewGroup? - get() { - var decorView: ViewGroup? = null - - activityWeakReference?.get()?.let { - decorView = it.window.decorView as ViewGroup - } - - return decorView - } - /** * Shows the Alert, after it's built * @@ -55,10 +42,9 @@ class Alerter private constructor() { */ fun show(): Alert? { //This will get the Activity Window's DecorView - activityWeakReference?.get()?.let { - it.runOnUiThread { - //Add the new Alert to the View Hierarchy - activityDecorView?.addView(alert) + decorView?.get()?.let { + android.os.Handler(Looper.getMainLooper()).post { + it.addView(alert) } } @@ -204,8 +190,8 @@ class Alerter private constructor() { * @return This Alerter */ fun setBackgroundColorRes(@ColorRes colorResId: Int): Alerter { - activityWeakReference?.get()?.let { - alert?.setAlertBackgroundColor(ContextCompat.getColor(it, colorResId)) + decorView?.get()?.let { + alert?.setAlertBackgroundColor(ContextCompat.getColor(it.context.applicationContext, colorResId)) } return this @@ -607,6 +593,7 @@ class Alerter private constructor() { return this } + /** * Disable touch events outside of the Alert * @@ -721,67 +708,78 @@ class Alerter private constructor() { return alert?.layoutContainer } - /** - * Creates a weak reference to the calling Activity - * - * @param activity The calling Activity - */ - private fun setActivity(activity: Activity) { - activityWeakReference = WeakReference(activity) - } - companion object { - private var activityWeakReference: WeakReference? = null + private var decorView: WeakReference? = null /** - * Creates the Alert, and maintains a reference to the calling Activity + * Creates the Alert * * @param activity The calling Activity * @return This Alerter */ @JvmStatic - fun create(activity: Activity?): Alerter { - return create(activity, R.layout.alerter_alert_default_layout) + @JvmOverloads + fun create(activity: Activity, layoutId: Int = R.layout.alerter_alert_default_layout): Alerter { + return create(activity = activity, dialog = null, layoutId = layoutId) + } + + /** + * Creates the Alert + * + * @param dialog The calling Dialog + * @return This Alerter + */ + @JvmStatic + @JvmOverloads + fun create(dialog: Dialog, layoutId: Int = R.layout.alerter_alert_default_layout): Alerter { + return create(activity = null, dialog = dialog, layoutId = layoutId) } /** - * Creates the Alert with custom view, and maintains a reference to the calling Activity + * Creates the Alert with custom view, and maintains a reference to the calling Activity or Dialog's + * DecorView * * @param activity The calling Activity + * @param dialog The calling Dialog * @param layoutId Custom view layout res id * @return This Alerter */ @JvmStatic - fun create(activity: Activity?, @LayoutRes layoutId: Int): Alerter { - requireNotNull(activity) { "Activity cannot be null!" } - + private fun create(activity: Activity? = null, dialog: Dialog? = null, @LayoutRes layoutId: Int): Alerter { val alerter = Alerter() //Hide current Alert, if one is active - clearCurrent(activity) - - alerter.setActivity(activity) - alerter.alert = Alert(activity, layoutId) + clearCurrent(activity, dialog) + + alerter.alert = dialog?.window?.let { + decorView = WeakReference(it.decorView as ViewGroup) + Alert(context = it.decorView.context, layoutId = layoutId) + } ?: run { + activity?.window?.let { + decorView = WeakReference(it.decorView as ViewGroup) + Alert(context = it.decorView.context, layoutId = layoutId) + } + } return alerter } /** - * Cleans up the currently showing alert view, if one is present + * Cleans up the currently showing alert view, if one is present. Either pass + * the calling Activity, or the calling Dialog * * @param activity The current Activity + * @param dialog The current Dialog */ @JvmStatic - fun clearCurrent(activity: Activity?) { - (activity?.window?.decorView as? ViewGroup)?.let { - //Find all Alert Views in Parent layout - for (i in 0..it.childCount) { - val childView = if (it.getChildAt(i) is Alert) it.getChildAt(i) as Alert else null - if (childView != null && childView.windowToken != null) { - ViewCompat.animate(childView).alpha(0f).withEndAction(getRemoveViewRunnable(childView)) - } - } + fun clearCurrent(activity: Activity?, dialog: Dialog?) { + dialog?.let { + it.window?.decorView as? ViewGroup + } ?: kotlin.run { + activity?.window?.decorView as? ViewGroup + }?.also { + removeAlertFromParent(it) } } @@ -790,8 +788,18 @@ class Alerter private constructor() { */ @JvmStatic fun hide() { - activityWeakReference?.get()?.let { - clearCurrent(it) + decorView?.get()?.let { + removeAlertFromParent(it) + } + } + + private fun removeAlertFromParent(decorView: ViewGroup) { + //Find all Alert Views in Parent layout + for (i in 0..decorView.childCount) { + val childView = if (decorView.getChildAt(i) is Alert) decorView.getChildAt(i) as Alert else null + if (childView != null && childView.windowToken != null) { + ViewCompat.animate(childView).alpha(0f).withEndAction(getRemoveViewRunnable(childView)) + } } } @@ -805,7 +813,7 @@ class Alerter private constructor() { get() { var isShowing = false - activityWeakReference?.get()?.let { + decorView?.get()?.let { isShowing = it.findViewById(R.id.llAlertBackground) != null } diff --git a/app/build.gradle b/app/build.gradle index 99a8775..5f2f7d0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,6 +48,6 @@ android { dependencies { implementation project(':alerter') - implementation "com.google.android.material:material:1.0.0" + implementation 'com.google.android.material:material:1.2.1' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" } \ No newline at end of file diff --git a/app/src/main/java/com/tapadoo/alerter/demo/CustomBottomSheetDialogFragment.kt b/app/src/main/java/com/tapadoo/alerter/demo/CustomBottomSheetDialogFragment.kt new file mode 100644 index 0000000..e49cf92 --- /dev/null +++ b/app/src/main/java/com/tapadoo/alerter/demo/CustomBottomSheetDialogFragment.kt @@ -0,0 +1,67 @@ +package com.tapadoo.alerter.demo + +import android.app.Dialog +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.tapadoo.alerter.Alerter +import kotlinx.android.synthetic.main.layout_modal_bottom_sheet.btnAlertColoured +import kotlinx.android.synthetic.main.layout_modal_bottom_sheet.btnAlertCustomIcon +import kotlinx.android.synthetic.main.layout_modal_bottom_sheet.btnAlertDefault + +class CustomBottomSheetDialogFragment : BottomSheetDialogFragment() { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.layout_modal_bottom_sheet, container, false) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + + btnAlertDefault.setOnClickListener { + //handle click event + showAlertDefault(dialog) + } + btnAlertColoured.setOnClickListener { + //handle click event + showAlertColoured(dialog) + } + btnAlertCustomIcon.setOnClickListener { + //handle click event + showAlertWithIcon(dialog) + } + } + + private fun showAlertDefault(view: Dialog?) { + view?.let { + Alerter.create(dialog = it) + .setTitle(R.string.title_activity_example) + .setText("Alert text...") + .show() + } + } + + private fun showAlertColoured(view: Dialog?) { + view?.let { + Alerter.create(dialog = it) + .setTitle("Alert Title") + .setText("Alert text...") + .setBackgroundColorRes(R.color.colorAccent) + .show() + } + } + + private fun showAlertWithIcon(view: Dialog?) { + view?.let { + Alerter.create(dialog = it) + .setText("Alert text...") + .setIcon(R.drawable.alerter_ic_mail_outline) + .setIconColorFilter(0) // Optional - Removes white tint + .setIconSize(R.dimen.custom_icon_size) // Optional - default is 38dp + .show() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tapadoo/alerter/demo/KotlinDemoActivity.kt b/app/src/main/java/com/tapadoo/alerter/demo/KotlinDemoActivity.kt index 224bd3b..77fec85 100644 --- a/app/src/main/java/com/tapadoo/alerter/demo/KotlinDemoActivity.kt +++ b/app/src/main/java/com/tapadoo/alerter/demo/KotlinDemoActivity.kt @@ -175,7 +175,7 @@ class KotlinDemoActivity : AppCompatActivity() { } private fun showAlertWithCustomLayout() { - Alerter.create(this@KotlinDemoActivity, R.layout.custom_layout) + Alerter.create(this@KotlinDemoActivity, R.layout.custom_layout) .setBackgroundColorRes(R.color.colorAccent) .also { alerter -> val tvCustomView = alerter.getLayoutContainer()?.tvCustomLayout @@ -203,35 +203,35 @@ class KotlinDemoActivity : AppCompatActivity() { private fun showAlertWithRightIcon() { Alerter.create(this@KotlinDemoActivity) - .setText("Alert text...") - .setIcon(R.drawable.alerter_ic_mail_outline) - .setIconColorFilter(0) // Optional - Removes white tint - .setIconSize(R.dimen.custom_icon_size) // Optional - default is 38dp - .setRightIcon(R.drawable.alerter_ic_face) - .showRightIcon(true) - .setRightIconSize(R.dimen.custom_icon_size) // Optional - default is 38dp - .show() + .setText("Alert text...") + .setIcon(R.drawable.alerter_ic_mail_outline) + .setIconColorFilter(0) // Optional - Removes white tint + .setIconSize(R.dimen.custom_icon_size) // Optional - default is 38dp + .setRightIcon(R.drawable.alerter_ic_face) + .showRightIcon(true) + .setRightIconSize(R.dimen.custom_icon_size) // Optional - default is 38dp + .show() } private fun showAlertWithOnlyRightIcon() { Alerter.create(this@KotlinDemoActivity) - .setText("Alert text...") - .showIcon(false) - .setRightIcon(R.drawable.alerter_ic_face) - .showRightIcon(true) - .show() + .setText("Alert text...") + .showIcon(false) + .setRightIcon(R.drawable.alerter_ic_face) + .showRightIcon(true) + .show() } private fun showAlertRightIconOnTop() { Alerter.create(this) - .setText("The alert scales to accommodate larger bodies of text." + - "The alert scales to accommodate larger bodies of text. " + - "The alert scales to accommodate larger bodies of text.") - .showIcon(false) - .setRightIcon(R.drawable.alerter_ic_face) - .setRightIconPosition(Gravity.TOP) // Optional - default is center - .showRightIcon(true) - .show() + .setText("The alert scales to accommodate larger bodies of text." + + "The alert scales to accommodate larger bodies of text. " + + "The alert scales to accommodate larger bodies of text.") + .showIcon(false) + .setRightIcon(R.drawable.alerter_ic_face) + .setRightIconPosition(Gravity.TOP) // Optional - default is center + .showRightIcon(true) + .show() } private fun setupOnClickListeners() { @@ -318,5 +318,11 @@ class KotlinDemoActivity : AppCompatActivity() { btnRightIconOnTop.setOnClickListener { showAlertRightIconOnTop() } + + btnBottomSheetModal.setOnClickListener { + CustomBottomSheetDialogFragment().apply { + show(supportFragmentManager, CustomBottomSheetDialogFragment::class.java.canonicalName) + } + } } } diff --git a/app/src/main/res/layout/content_example.xml b/app/src/main/res/layout/content_example.xml index a31c614..0926a27 100644 --- a/app/src/main/res/layout/content_example.xml +++ b/app/src/main/res/layout/content_example.xml @@ -169,5 +169,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/right_icon_on_top" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_modal_bottom_sheet.xml b/app/src/main/res/layout/layout_modal_bottom_sheet.xml new file mode 100644 index 0000000..286bc2f --- /dev/null +++ b/app/src/main/res/layout/layout_modal_bottom_sheet.xml @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4a255d6..81789a1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,4 +23,6 @@ With Right Icon With Only Right Icon Right icon on top + + Modal Bottom Sheet diff --git a/build.gradle b/build.gradle index f4294a1..b863bbd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ buildscript { ext { - compileSdkVersion = 29 + compileSdkVersion = 30 minSdkVersion = 14 - targetSdkVersion = 29 + targetSdkVersion = 30 - kotlin_version = '1.3.50' + kotlin_version = '1.4.21' - buildToolsVersion = '29.0.2' + buildToolsVersion = '30.0.3' sourceCompatibilityVersion = JavaVersion.VERSION_1_8 targetCompatibilityVersion = JavaVersion.VERSION_1_8 @@ -23,7 +23,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:4.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.17" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9770186..02888ca 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Sep 18 09:18:06 IST 2019 +#Thu Jan 28 11:18:06 GMT 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip diff --git a/quality.gradle b/quality.gradle index 2d65432..22c6e1d 100644 --- a/quality.gradle +++ b/quality.gradle @@ -1,6 +1,5 @@ //noinspection GrPackage apply plugin: 'checkstyle' -apply plugin: 'findbugs' apply plugin: 'pmd' final String QUALITY_DIR = "quality" @@ -40,35 +39,6 @@ task checkstyle(type: Checkstyle) { classpath = files() } -/* - * Find Bugs - a program which uses static analysis to look for bugs in Java code. - */ -task findbugs(type: FindBugs) { - ignoreFailures = false - effort = "max" - reportLevel = "high" - excludeFilter = new File("${project.rootDir}/${QUALITY_DIR}/findbugs/findbugs-filter.xml") - classes = files("${project.buildDir}/intermediates/classes") - - source SOURCE - include INCLUDE_JAVA - exclude EXCLUDE_GENERATED - - reports { - xml.enabled = false - html.enabled = true - - xml { - destination new File("$project.buildDir/reports/findbugs/findbugs.xml") - } - html { - destination new File("$project.buildDir/reports/findbugs/findbugs.html") - } - } - - classpath = files() -} - /* * Programming Mistake Detector - a source code analyzer. It finds common programming flaws. */