From 26421aa428c669f4123fca7094fff0e1d90b5387 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 30 Aug 2017 12:13:38 -0400 Subject: fix/mediapicker (#50) * Bring all glide request managers to one instance * Switch to test implementation * Check if parent is null for searchview * Ensure open close runs on ui thread * Make glide contract internal * Update changelog * Update version Update changelog for previous prs --- sample/src/main/res/xml/kau_changelog.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sample/src/main/res/xml') diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml index 87611f8..6f76f66 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -9,8 +9,10 @@ - - + + + + -- cgit v1.2.3 From 66e7d9505e0baffaf17877c1800939a2e0b936d6 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 23 Sep 2017 15:14:12 -0400 Subject: v3.4.1 (#63) * Check browser intent before launching (#54) * Update changelog * fix/misc (#55) * Add kapt plugin * Fix kau vector * Debug lintRelease * Revert debug * Update dependencies * Check context finishing state before showing dialog (#61) * Keep copy of shared pref rather than application context (#60) * Keep copy of shared pref rather than application context * Add back preference name * Add resolver checks (#62) Squashed commit of the following: commit 7fe57d4ab1dbfe8bfb4d4a15bd0fbf636da491fa Author: Allan Wang Date: Sat Sep 23 15:25:18 2017 -0400 Add missing quote commit ffc3ac99248c2250a7f14ef709f37d787cbe0d83 Author: Allan Wang Date: Sat Sep 23 15:20:54 2017 -0400 Update changelog Update gradle Update version name --- build.gradle | 2 +- .../kotlin/ca/allanwang/kau/email/EmailBuilder.kt | 6 ++- .../main/kotlin/ca/allanwang/kau/kpref/KPref.kt | 17 +++----- .../kotlin/ca/allanwang/kau/utils/ContextUtils.kt | 48 ++++++++++++++++------ .../src/main/res-public/values/strings_commons.xml | 2 +- core/src/main/res/values/strings.xml | 4 -- docs/Changelog.md | 5 +++ gradle.properties | 8 ++-- mediapicker/build.gradle | 1 + sample/src/main/res/drawable/kau.xml | 4 +- sample/src/main/res/xml/kau_changelog.xml | 7 ++++ 11 files changed, 66 insertions(+), 38 deletions(-) delete mode 100644 core/src/main/res/values/strings.xml (limited to 'sample/src/main/res/xml') diff --git a/build.gradle b/build.gradle index 19f3436..20d17ca 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { maven { url 'https://maven.fabric.io/public' } } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0-beta3' + classpath 'com.android.tools.build:gradle:3.0.0-beta6' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN}" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' classpath 'com.github.triplet.gradle:play-publisher:1.2.0' diff --git a/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt b/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt index 88a0945..8c6acff 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt @@ -13,6 +13,7 @@ import ca.allanwang.kau.logging.KL import ca.allanwang.kau.utils.installerPackageName import ca.allanwang.kau.utils.isAppInstalled import ca.allanwang.kau.utils.string +import ca.allanwang.kau.utils.toast /** @@ -76,7 +77,10 @@ class EmailBuilder(val email: String, val subject: String) { emailBuilder.append("\n").append(footer) intent.putExtra(Intent.EXTRA_TEXT, emailBuilder.toString()) - context.startActivity(Intent.createChooser(intent, context.resources.getString(R.string.kau_send_via))) + if (intent.resolveActivity(context.packageManager) != null) + context.startActivity(Intent.createChooser(intent, context.resources.getString(R.string.kau_send_via))) + else + context.toast("Cannot resolve email activity", log = true) } } diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt index be16c7c..fbb8c7d 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt @@ -3,6 +3,7 @@ package ca.allanwang.kau.kpref import android.content.Context import android.content.SharedPreferences import ca.allanwang.kau.kotlin.ILazyResettable +import ca.allanwang.kau.logging.KL /** * Created by Allan Wang on 2017-06-07. @@ -22,15 +23,13 @@ import ca.allanwang.kau.kotlin.ILazyResettable */ open class KPref { - lateinit private var c: Context - lateinit internal var PREFERENCE_NAME: String - private var initialized = false + lateinit var PREFERENCE_NAME: String + lateinit var sp: SharedPreferences fun initialize(c: Context, preferenceName: String) { - if (initialized) throw KPrefException("KPref object $preferenceName has already been initialized; please only do so once") - initialized = true - this.c = c.applicationContext PREFERENCE_NAME = preferenceName + sp = c.applicationContext.getSharedPreferences(preferenceName, Context.MODE_PRIVATE) + KL.d("Shared Preference $preferenceName has been initialized") val toDelete = deleteKeys() if (toDelete.isNotEmpty()) { val edit = sp.edit() @@ -39,12 +38,6 @@ open class KPref { } } - //todo hide this - val sp: SharedPreferences by lazy { - if (!initialized) throw KPrefException("KPref object has not yet been initialized; please initialize it with a context and preference name") - c.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE) - } - internal val prefMap: MutableMap> = mutableMapOf() fun reset() { diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt index d561c8a..a72c7dd 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt @@ -77,7 +77,11 @@ fun Context.startActivitySlideOut(clazz: Class, clearStack: Boolea fun Context.startPlayStoreLink(@StringRes packageIdRes: Int) = startPlayStoreLink(string(packageIdRes)) fun Context.startPlayStoreLink(packageId: String) { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageId"))) + val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageId")) + if (intent.resolveActivity(packageManager) != null) + startActivity(intent) + else + toast("Cannot resolve play store", log = true) } /** @@ -87,22 +91,24 @@ fun Context.startPlayStoreLink(packageId: String) { fun Context.startLink(vararg url: String?) { val link = url.firstOrNull { !it.isNullOrBlank() } ?: return val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(link)) - startActivity(browserIntent) + if (browserIntent.resolveActivity(packageManager) != null) + startActivity(browserIntent) + else + toast("Cannot resolve browser", log = true) } -fun Context.startLink(@StringRes url: Int) { - val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(string(url))) - startActivity(browserIntent) -} +fun Context.startLink(@StringRes url: Int) = startLink(string(url)) //Toast helpers -inline fun View.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG) = context.toast(id, duration) +inline fun View.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = context.toast(id, duration, log) + +inline fun Context.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = toast(this.string(id), duration, log) -inline fun Context.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG) = toast(this.string(id), duration) +inline fun View.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = context.toast(text, duration, log) -inline fun View.toast(text: String, duration: Int = Toast.LENGTH_LONG) = context.toast(text, duration) -inline fun Context.toast(text: String, duration: Int = Toast.LENGTH_LONG) { +inline fun Context.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) { Toast.makeText(this, text, duration).show() + if (log) KL.i("Toast: $text") } //Resource retrievers @@ -163,6 +169,10 @@ fun Context.resolveString(@AttrRes attr: Int, fallback: String = ""): String { inline fun Context.materialDialog(action: MaterialDialog.Builder.() -> Unit): MaterialDialog { val builder = MaterialDialog.Builder(this) builder.action() + if (isFinishing) { + KL.d("Material Dialog triggered from finishing context; did not show") + return builder.build() + } return builder.show() } @@ -192,9 +202,21 @@ fun Context.copyToClipboard(text: String?, label: String = "Copied Text", showTo } fun Context.shareText(text: String?) { - if (text == null) return toast(R.string.kau_text_is_null) + if (text == null) return toast("Share text is null") val intent = Intent(Intent.ACTION_SEND) intent.type = "text/plain" intent.putExtra(Intent.EXTRA_TEXT, text) - startActivity(Intent.createChooser(intent, string(R.string.kau_share))) -} \ No newline at end of file + val chooserIntent = Intent.createChooser(intent, string(R.string.kau_share)) + if (chooserIntent.resolveActivity(packageManager) != null) + startActivity(chooserIntent) + else + toast("Cannot resolve activity to share text", log = true) +} + +/** + * Check if given context is finishing. + * This is a wrapper to check if it's both an activity and finishing + * As of now, it is only checked when tied to an activity + */ +inline val Context.isFinishing: Boolean + get() = (this as? Activity)?.isFinishing ?: false \ No newline at end of file diff --git a/core/src/main/res-public/values/strings_commons.xml b/core/src/main/res-public/values/strings_commons.xml index d236021..6bea9a6 100644 --- a/core/src/main/res-public/values/strings_commons.xml +++ b/core/src/main/res-public/values/strings_commons.xml @@ -38,7 +38,7 @@ Most resources are verbatim and x represents a formatted item No No Results Found None - @android:string/ok + OK Play Store Rate Report A Bug diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml deleted file mode 100644 index d8b2993..0000000 --- a/core/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Text is null - \ No newline at end of file diff --git a/docs/Changelog.md b/docs/Changelog.md index aa37c4d..70a61ee 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -1,11 +1,16 @@ # Changelog +## v3.4.1 +* Validate context before showing dialogs +* Add intent resolver checks prior to all executions. + ## v3.4.0 * Update to gradle 4.x; api and implementation rather than compile * Update dependencies * :searchview: Ensure reveals are called on the UI thread * :searchview: Check that searchview has a parent before checking card state * :mediapicker: Reuse request manager from activity +* :kpref-activity: Add bounds to text item ## v3.3.2 * :kpref-activity: Add visibility toggle to Core contract. Items can override this to show/hide given preferences based on boolean callbacks. diff --git a/gradle.properties b/gradle.properties index 9a1177d..32ea648 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,18 +21,18 @@ CORE_MIN_SDK=19 MIN_SDK=21 TARGET_SDK=26 BUILD_TOOLS=26.0.1 -ANDROID_SUPPORT_LIBS=26.0.1 +ANDROID_SUPPORT_LIBS=26.1.0 -VERSION_NAME=3.4.0 +VERSION_NAME=3.4.2 -KOTLIN=1.1.4-2 +KOTLIN=1.1.4-3 ABOUT_LIBRARIES=5.9.7 ANKO=0.10.1 BLURRY=2.1.1 CONSTRAINT_LAYOUT=1.1.0-beta1 FAST_ADAPTER=2.6.3 FAST_ADAPTER_COMMONS=2.6.3 -GLIDE=4.0.0 +GLIDE=4.1.1 ICONICS=2.9.3 IICON_GOOGLE=3.0.1.1 MATERIAL_DIALOG=0.9.4.7 diff --git a/mediapicker/build.gradle b/mediapicker/build.gradle index eff6a77..0f90f7b 100644 --- a/mediapicker/build.gradle +++ b/mediapicker/build.gradle @@ -1,6 +1,7 @@ ext.kauSubModuleMinSdk = project.CORE_MIN_SDK apply from: '../android-lib.gradle' +apply plugin: 'kotlin-kapt' dependencies { implementation project(':core-ui') diff --git a/sample/src/main/res/drawable/kau.xml b/sample/src/main/res/drawable/kau.xml index b0a7be8..47612e0 100644 --- a/sample/src/main/res/drawable/kau.xml +++ b/sample/src/main/res/drawable/kau.xml @@ -8,11 +8,11 @@ + android:pathData="M42.8336 42.7538l19-42.75 31.67656 57H57.0836zM0 0.08894h27L0 28.6213z" /> + android:pathData="M28.5 0.0038 H57l-57 57v-26.882z" /> --> + + + + + + + -- cgit v1.2.3 From cd41bb2917425599fca5d786ea62a2c3253dda70 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 24 Sep 2017 14:26:09 -0400 Subject: Fix bundle NPE for activity creation Update changelog --- .../kotlin/ca/allanwang/kau/utils/ActivityUtils.kt | 6 +++--- .../kotlin/ca/allanwang/kau/utils/ContextUtils.kt | 20 +++++++++++--------- core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt | 20 ++++++++++++++++---- sample/src/main/res/xml/kau_changelog.xml | 2 +- 4 files changed, 31 insertions(+), 17 deletions(-) (limited to 'sample/src/main/res/xml') diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt index 5631e70..33bdc62 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt @@ -32,9 +32,9 @@ fun Activity.startActivityForResult( bundle: Bundle? = null, intentBuilder: Intent.() -> Unit = {}) { val intent = Intent(this, clazz) - val fullBundle = if (transition && buildIsLollipopAndUp) - ActivityOptions.makeSceneTransitionAnimation(this).toBundle() - else Bundle() + val fullBundle = Bundle() + if (transition && buildIsLollipopAndUp) + fullBundle.with(ActivityOptions.makeSceneTransitionAnimation(this).toBundle()) if (bundle != null) fullBundle.putAll(bundle) intent.intentBuilder() startActivityForResult(intent, requestCode, if (fullBundle.isEmpty) null else fullBundle) diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt index a72c7dd..0664dc6 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt @@ -43,9 +43,9 @@ fun Context.startActivity( intentBuilder: Intent.() -> Unit = {}) { val intent = Intent(this, clazz) if (clearStack) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) - val fullBundle = if (transition && this is Activity && buildIsLollipopAndUp) - ActivityOptions.makeSceneTransitionAnimation(this).toBundle() - else Bundle() + val fullBundle = Bundle() + if (transition && this is Activity && buildIsLollipopAndUp) + fullBundle.with(ActivityOptions.makeSceneTransitionAnimation(this).toBundle()) if (transition && this !is Activity) KL.d("Cannot make scene transition when context is not an instance of an Activity") if (bundle != null) fullBundle.putAll(bundle) intent.intentBuilder() @@ -57,9 +57,10 @@ fun Context.startActivity( * Bring in activity from the right */ fun Context.startActivitySlideIn(clazz: Class, clearStack: Boolean = false, intentBuilder: Intent.() -> Unit = {}, bundleBuilder: Bundle.() -> Unit = {}) { - val bundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle() - bundle.bundleBuilder() - startActivity(clazz, clearStack, intentBuilder = intentBuilder, bundle = bundle) + val fullBundle = Bundle() + fullBundle.with(ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle()) + fullBundle.bundleBuilder() + startActivity(clazz, clearStack, intentBuilder = intentBuilder, bundle = if (fullBundle.isEmpty) null else fullBundle) } /** @@ -69,9 +70,10 @@ fun Context.startActivitySlideIn(clazz: Class, clearStack: Boolean * Consequently, the stack will be cleared by default */ fun Context.startActivitySlideOut(clazz: Class, clearStack: Boolean = true, intentBuilder: Intent.() -> Unit = {}, bundleBuilder: Bundle.() -> Unit = {}) { - val bundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_fade_in, R.anim.kau_slide_out_right_top).toBundle() - bundle.bundleBuilder() - startActivity(clazz, clearStack, intentBuilder = intentBuilder, bundle = bundle) + val fullBundle = Bundle() + fullBundle.with(ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_fade_in, R.anim.kau_slide_out_right_top).toBundle()) + fullBundle.bundleBuilder() + startActivity(clazz, clearStack, intentBuilder = intentBuilder, bundle = if (fullBundle.isEmpty) null else fullBundle) } fun Context.startPlayStoreLink(@StringRes packageIdRes: Int) = startPlayStoreLink(string(packageIdRes)) diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt index 50a3c29..954bedc 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt @@ -6,6 +6,7 @@ import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable +import android.os.Bundle import android.os.Handler import android.os.Looper import android.support.annotation.IntRange @@ -53,14 +54,16 @@ annotation class KauUtils * Converts minute value to string * Whole hours and days will be converted as such, otherwise it will default to x minutes */ -@KauUtils fun Context.minuteToText(minutes: Long): String = with(minutes) { +@KauUtils +fun Context.minuteToText(minutes: Long): String = with(minutes) { if (this < 0L) string(R.string.kau_none) else if (this % 1440L == 0L) plural(R.plurals.kau_x_days, this / 1440L) else if (this % 60L == 0L) plural(R.plurals.kau_x_hours, this / 60L) else plural(R.plurals.kau_x_minutes, this) } -@KauUtils fun Number.round(@IntRange(from = 1L) decimalCount: Int): String { +@KauUtils +fun Number.round(@IntRange(from = 1L) decimalCount: Int): String { val expression = StringBuilder().append("#.") (1..decimalCount).forEach { expression.append("#") } val formatter = DecimalFormat(expression.toString()) @@ -72,7 +75,8 @@ annotation class KauUtils * Extracts the bitmap of a drawable, and applies a scale if given * For solid colors, a 1 x 1 pixel will be generated */ -@KauUtils fun Drawable.toBitmap(scaling: Float = 1f, config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap { +@KauUtils +fun Drawable.toBitmap(scaling: Float = 1f, config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap { if (this is BitmapDrawable && bitmap != null) { if (scaling == 1f) return bitmap val width = (bitmap.width * scaling).toInt() @@ -122,4 +126,12 @@ class KauException(message: String) : RuntimeException(message) fun String.withMaxLength(n: Int): String = if (length <= n) this - else substring(0, n-1) + KAU_ELLIPSIS \ No newline at end of file + else substring(0, n - 1) + KAU_ELLIPSIS + +/** + * Similar to [Bundle.putAll], but checks for a null insert and returns the parent bundle + */ +fun Bundle.with(bundle: Bundle?): Bundle { + if (bundle != null) putAll(bundle) + return this +} \ No newline at end of file diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml index 8476660..53dfe99 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -9,7 +9,7 @@ - + -- cgit v1.2.3 From 1a509b896aa670da4ab3e2f039140ad7608387e9 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 24 Sep 2017 16:41:13 -0400 Subject: Feature/kpref time picker (#64) * Init kpref time builder and open up other builders * Enable self refresh * Add readme * Update changelog * Update readme --- core/README.md | 4 +- core/src/main/res/values/ids.xml | 1 + docs/Changelog.md | 1 + kpref-activity/README.md | 2 + .../ca/allanwang/kau/kpref/activity/KPrefBinder.kt | 8 +++ .../kau/kpref/activity/items/KPrefColorPicker.kt | 2 +- .../kau/kpref/activity/items/KPrefPlainText.kt | 2 +- .../kau/kpref/activity/items/KPrefSubItems.kt | 2 +- .../kau/kpref/activity/items/KPrefText.kt | 2 +- .../kau/kpref/activity/items/KPrefTimePicker.kt | 64 ++++++++++++++++++++++ .../kotlin/ca/allanwang/kau/sample/KPrefSample.kt | 3 + .../kotlin/ca/allanwang/kau/sample/MainActivity.kt | 31 ++++++----- sample/src/main/res/values/strings.xml | 3 + sample/src/main/res/xml/kau_changelog.xml | 8 ++- 14 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt (limited to 'sample/src/main/res/xml') diff --git a/core/README.md b/core/README.md index 4cb68d0..39899dd 100644 --- a/core/README.md +++ b/core/README.md @@ -178,7 +178,7 @@ KAU's swipe is a Kotlin rewrite, along with support for all directions and weakl # Debounce Debouncing is a means of throttling a function so that it is called no more than once in a given instance of time. -An example where you'd like this behaviour is the searchview; you want to deliver search results quickly, +An example where you'd like this behaviour is the searchview: you want to deliver search results quickly, but you don't want to update your response with each new character. Instead, you can wait until a user finishes their query, then search for the results. @@ -210,7 +210,7 @@ Include your email and subject, along with other optional configurations such as ## Extension Functions > "[Extensions](https://kotlinlang.org/docs/reference/extensions.html) provide the ability to extend a class with new functionality without having to inherit from the class" -Note that since KAU depends on [ANKO](https://github.com/Kotlin/anko), all of the extensions in its core package is also in KAU. +
Note that since KAU depends on [ANKO](https://github.com/Kotlin/anko), all of the extensions in its core package is also in KAU. KAU's vast collection of extensions is one of its strongest features. There are too many to explain here, but you may check out the [utils package](https://github.com/AllanWang/KAU/tree/master/core/src/main/kotlin/ca/allanwang/kau/utils) diff --git a/core/src/main/res/values/ids.xml b/core/src/main/res/values/ids.xml index c4912e2..28ff9d9 100644 --- a/core/src/main/res/values/ids.xml +++ b/core/src/main/res/values/ids.xml @@ -14,6 +14,7 @@ + diff --git a/docs/Changelog.md b/docs/Changelog.md index 70a61ee..6c5bb11 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,6 +3,7 @@ ## v3.4.1 * Validate context before showing dialogs * Add intent resolver checks prior to all executions. +* Fix bundle NPE when starting activity ## v3.4.0 * Update to gradle 4.x; api and implementation rather than compile diff --git a/kpref-activity/README.md b/kpref-activity/README.md index a9aac89..69d4892 100644 --- a/kpref-activity/README.md +++ b/kpref-activity/README.md @@ -30,6 +30,7 @@ Contract | Mandatory | Optional | Description `KPrefSeekbarContract` | `NA` | `min` `max` `increments` `toText` `textViewConfigs` | Addtional configurations for a seekbar, as well as text to be displayed on the side. `KPrefSubItemsContract` | `itemBuilder` | `NA` | Contains a new list for the adapter to load when clicked `KPrefTextContract` | `NA` | `textGetter` | Additional configurations for the text item +`KPrefTimeContract` | `NA` | `use24HourFormat` | Additional configurations for time picker The kpref items are as followed: @@ -41,6 +42,7 @@ Item | Implements | Description `header` | `CoreContract` | Header; just a title that isn't clickable `text` | `CoreContract` `BaseContract` `KPrefTextContract` | Text item; displays the kpref as a String on the right; does not have click implementation by default `plainText` | `CoreContract` `BaseContract` | Plain text item; like `text` but does not deal with any preferences directly, so it doesn't need a getter or setter +`timePicker` | `CoreContract` `BaseContract` `KPrefTextContract`, `KPrefTimeContract` | Extension ot `text` that will open and save a time picker This can be used to display text or deal with preference that are completely handed within the click event (eg a dialog). `subItems` | `CoreContract` `KPrefSubItemsContract` | Sub items; contains a new page for the activity to load when clicked diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt index 35821fd..637af03 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt @@ -101,6 +101,14 @@ class KPrefAdapterBuilder(val globalOptions: GlobalOptions) { = list.add(KPrefSeekbar(KPrefSeekbar.KPrefSeekbarBuilder(globalOptions, title, getter, setter) .apply { builder() })) + @KPrefMarker + fun timePicker(@StringRes title: Int, + getter: (() -> Int), + setter: ((value: Int) -> Unit), + builder: KPrefTimePicker.KPrefTimeContract.() -> Unit = {}) + = list.add(KPrefTimePicker(KPrefTimePicker.KPrefTimeBuilder(globalOptions, title, getter, setter) + .apply { builder() })) + @KPrefMarker val list: MutableList = mutableListOf() } \ No newline at end of file diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt index 315d67b..1950589 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt @@ -14,7 +14,7 @@ import ca.allanwang.kau.kpref.activity.R * ColorPicker preference * When a color is successfully selected in the dialog, it will be saved as an int */ -open class KPrefColorPicker(val builder: KPrefColorContract) : KPrefItemBase(builder) { +open class KPrefColorPicker(open val builder: KPrefColorContract) : KPrefItemBase(builder) { override fun onPostBindView(viewHolder: ViewHolder, textColor: Int?, accentColor: Int?) { super.onPostBindView(viewHolder, textColor, accentColor) diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt index b83df69..d2e49d8 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt @@ -12,7 +12,7 @@ import ca.allanwang.kau.kpref.activity.R * and when the preference is completely handled by the click * */ -open class KPrefPlainText(val builder: KPrefPlainTextBuilder) : KPrefItemBase(builder) { +open class KPrefPlainText(open val builder: KPrefPlainTextBuilder) : KPrefItemBase(builder) { override fun defaultOnClick(itemView: View, innerContent: View?): Boolean { //nothing diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt index 1bf0ffc..7c2979c 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt @@ -12,7 +12,7 @@ import ca.allanwang.kau.kpref.activity.R * When clicked, will navigate to a new set of preferences and add the old list to a stack * */ -open class KPrefSubItems(val builder: KPrefSubItemsContract) : KPrefItemCore(builder) { +open class KPrefSubItems(open val builder: KPrefSubItemsContract) : KPrefItemCore(builder) { override fun onClick(itemView: View, innerContent: View?): Boolean { builder.globalOptions.showNextPrefs(builder.titleRes, builder.itemBuilder) diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt index 45c9a5d..29dd007 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt @@ -14,7 +14,7 @@ import ca.allanwang.kau.utils.toast * This is still a generic preference * */ -open class KPrefText(val builder: KPrefTextContract) : KPrefItemBase(builder) { +open class KPrefText(open val builder: KPrefTextContract) : KPrefItemBase(builder) { /** * Automatically reload on set diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt new file mode 100644 index 0000000..d4f854b --- /dev/null +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt @@ -0,0 +1,64 @@ +package ca.allanwang.kau.kpref.activity.items + +import android.app.TimePickerDialog +import android.view.View +import android.widget.TimePicker +import ca.allanwang.kau.kpref.activity.GlobalOptions +import ca.allanwang.kau.kpref.activity.R +import java.util.* + +/** + * Created by Allan Wang on 2017-06-14. + * + * Text preference + * Holds a textview to display data on the right + * This is still a generic preference + * + */ +open class KPrefTimePicker(override val builder: KPrefTimeContract) : KPrefText(builder) { + + interface KPrefTimeContract : KPrefText.KPrefTextContract { + var use24HourFormat: Boolean + } + + /** + * Default implementation of [KPrefTimeContract] + */ + class KPrefTimeBuilder( + globalOptions: GlobalOptions, + titleRes: Int, + getter: () -> Int, + setter: (value: Int) -> Unit + ) : KPrefTimeContract, BaseContract by BaseBuilder(globalOptions, titleRes, getter, setter), TimePickerDialog.OnTimeSetListener { + + override var use24HourFormat: Boolean = false + + override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int) { + setter((hourOfDay to minute).mergeTime) + reloadSelf() + } + + override var textGetter: (Int) -> String? = { + val (hour, min) = it.splitTime + if (use24HourFormat) + String.format(Locale.CANADA, "%d:%02d", hour, min) + else + String.format(Locale.CANADA, "%d:%02d %s", hour % 12, min, if (hour >= 12) "PM" else "AM") + } + + override var onClick: ((itemView: View, innerContent: View?, item: KPrefItemBase) -> Boolean)? = { itemView, _, item -> + val (hour, min) = item.pref.splitTime + TimePickerDialog(itemView.context, this, hour, min, use24HourFormat).show() + true + } + + private val Int.splitTime: Pair + get() = Pair(this / 100, this % 100) + + private val Pair.mergeTime: Int + get() = first * 100 + second + } + + override fun getType(): Int = R.id.kau_item_pref_time_picker + +} \ No newline at end of file diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt index 9adabed..0c243e4 100644 --- a/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt +++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt @@ -17,4 +17,7 @@ object KPrefSample : KPref() { var check3: Boolean by kpref("check3", false) var text: String by kpref("text", "empty") var seekbar: Int by kpref("seekbar", 20) + var time12: Int by kpref("time_12", 315) + var time24: Int by kpref("time_24", 2220) + } \ No newline at end of file diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt index 1528970..ca75ebb 100644 --- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt +++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt @@ -107,8 +107,7 @@ class MainActivity : KPrefActivity() { checkbox(R.string.checkbox_3, { KPrefSample.check3 }, { KPrefSample.check3 = it }) { descRes = R.string.desc_dependent enabler = { KPrefSample.check2 } - onDisabledClick = { - itemView, _, _ -> + onDisabledClick = { itemView, _, _ -> itemView.context.toast("I am still disabled") true } @@ -140,8 +139,7 @@ class MainActivity : KPrefActivity() { text(R.string.text, { KPrefSample.text }, { KPrefSample.text = it }) { descRes = R.string.text_desc - onClick = { - itemView, _, item -> + onClick = { itemView, _, item -> itemView.context.materialDialog { title("Type Text") input("Type here", item.pref, { _, input -> item.pref = input.toString() }) @@ -193,17 +191,25 @@ class MainActivity : KPrefActivity() { textGetter = { string(R.string.kau_lorem_ipsum) } } + timePicker(R.string.time, { KPrefSample.time12 }, { KPrefSample.time12 = it }) { + descRes = R.string.time_desc_12 + use24HourFormat = false + } + + timePicker(R.string.time, { KPrefSample.time24 }, { KPrefSample.time24 = it }) { + descRes = R.string.time_desc_24 + use24HourFormat = true + } + } fun subPrefs(): KPrefAdapterBuilder.() -> Unit = { text(R.string.text, { KPrefSample.text }, { KPrefSample.text = it }) { descRes = R.string.text_desc - onClick = { - itemView, _, item -> + onClick = { itemView, _, item -> itemView.context.materialDialog { title("Type Text") - input("Type here", item.pref, { - _, input -> + input("Type here", item.pref, { _, input -> item.pref = input.toString() reloadSelf() }) @@ -237,21 +243,18 @@ class MainActivity : KPrefActivity() { menuInflater.inflate(R.menu.menu_main, menu) if (searchView == null) searchView = bindSearchView(menu, R.id.action_search) { - textCallback = { - query, searchView -> + textCallback = { query, searchView -> val items = wordBank.filter { it.contains(query) }.sorted().map { SearchItem(it) } searchView.results = items } - searchCallback = { - query, _ -> + searchCallback = { query, _ -> toast("Enter pressed for $query") true } textDebounceInterval = 0 noResultsFound = R.string.kau_no_results_found shouldClearOnClose = false - onItemClick = { - _, _, content, searchView -> + onItemClick = { _, _, content, searchView -> toast(content) searchView.revealClose() } diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml index a887ad3..1e3361e 100644 --- a/sample/src/main/res/values/strings.xml +++ b/sample/src/main/res/values/strings.xml @@ -15,6 +15,9 @@ Text Pref Saves the text Seekbar + Time Pref + AM PM version + 24h version Sub Item Pref Press this to view the next subset of preferences your.email@here.com diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml index 53dfe99..a33edbd 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -7,9 +7,11 @@ --> - - - + + + + + -- cgit v1.2.3 From a0b35316f7bb6014ebbd3e18be870e860b30ea71 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Fri, 13 Oct 2017 23:40:39 -0400 Subject: Prepare new version (#85) --- gradle.properties | 2 +- sample/src/main/res/xml/kau_changelog.xml | 101 +++++++++++++++--------------- 2 files changed, 53 insertions(+), 50 deletions(-) (limited to 'sample/src/main/res/xml') diff --git a/gradle.properties b/gradle.properties index 9a45266..e64203d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,7 @@ TARGET_SDK=26 BUILD_TOOLS=26.0.2 ANDROID_SUPPORT_LIBS=26.1.0 -VERSION_NAME=3.4.3 +VERSION_NAME=3.4.4 KOTLIN=1.1.51 ABOUT_LIBRARIES=5.9.7 diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml index 7f421f8..a4978b3 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -2,20 +2,23 @@ - - - - - - - - - - - + + + + + + + + + + + + + + @@ -23,16 +26,16 @@ - + - - - + + + - - + + @@ -40,29 +43,29 @@ - - + + - - - + + + - - + + - - - + + + - - + + @@ -75,32 +78,32 @@ - - - + + + - - - + + + - - - + + + - - - - + + + + @@ -115,7 +118,7 @@ - + @@ -124,7 +127,7 @@ - + @@ -132,7 +135,7 @@ - + @@ -141,20 +144,20 @@ - + - + - + -- cgit v1.2.3