From a0377be622f21b4c6a7d8828505c1e95efab1254 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 7 Apr 2018 20:23:17 -0400 Subject: Update/android studio 3.1 (#146) * Update dependencies * Add default invalid id value * Extend appcompat views only * Update migration * Remove setTextIfValid * Remove nosibling warning * Add deprecation warnings to fragment view binding * Bring back glide 4.6.1 * Use proper distribution type setter --- .travis.yml | 2 +- .../ca/allanwang/kau/about/AboutActivityBase.kt | 13 +-- .../ca/allanwang/kau/about/CollapsibleTextView.kt | 3 +- .../ca/allanwang/kau/adapters/AdapterUtils.kt | 17 +++- .../kotlin/ca/allanwang/kau/iitems/CardIItem.kt | 13 +-- .../kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt | 3 +- .../kotlin/ca/allanwang/kau/iitems/KauIItem.kt | 2 + build.gradle | 4 +- .../main/groovy/ca/allanwang/kau/Versions.groovy | 18 +++-- .../allanwang/kau/colorpicker/ColorPickerDialog.kt | 3 +- .../main/kotlin/ca/allanwang/kau/kotlin/Utils.kt | 6 ++ .../kotlin/ca/allanwang/kau/utils/ContextUtils.kt | 15 ++-- .../kotlin/ca/allanwang/kau/utils/Kotterknife.kt | 89 ++++++++++++++++----- .../kotlin/ca/allanwang/kau/utils/ViewUtils.kt | 5 -- dependencies.gradle | 28 ------- docs/Changelog.md | 7 ++ docs/Migration.md | 7 ++ gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 72 ++++++++++------- gradlew.bat | 14 +--- .../kau/kpref/activity/items/KPrefItemCore.kt | 6 +- .../src/main/res/layout/kau_pref_core.xml | 7 +- mediapicker/build.gradle | 1 + .../kau/mediapicker/MediaPickerActivityBase.kt | 6 +- sample/src/main/res/xml/kau_changelog.xml | 9 +++ .../ca/allanwang/kau/searchview/SearchView.kt | 6 +- 27 files changed, 222 insertions(+), 137 deletions(-) create mode 100644 core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt delete mode 100644 dependencies.gradle diff --git a/.travis.yml b/.travis.yml index d248bd9..a5086d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ env: global: - ANDROID_API=27 - EMULATOR_API=24 - - ANDROID_BUILD_TOOLS=27.0.2 + - ANDROID_BUILD_TOOLS=27.0.3 android: components: - tools diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt index 7a14d95..dddb0b9 100644 --- a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt +++ b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt @@ -15,6 +15,7 @@ import ca.allanwang.kau.internal.KauBaseActivity import ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout import ca.allanwang.kau.ui.widgets.InkPageIndicator import ca.allanwang.kau.utils.AnimHolder +import ca.allanwang.kau.utils.INVALID_ID import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.dimenPixelSize import com.mikepenz.aboutlibraries.Libs @@ -57,7 +58,7 @@ abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilde val panels: List by lazy { val defaultPanels = mutableListOf(AboutPanelMain(), AboutPanelLibs()) - if (configs.faqXmlRes != -1) defaultPanels.add(AboutPanelFaqs()) + if (configs.faqXmlRes != INVALID_ID) defaultPanels.add(AboutPanelFaqs()) defaultPanels } @@ -86,23 +87,23 @@ abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilde } class Configs : ThemableIItemColors by ThemableIItemColorsDelegate() { - var cutoutTextRes: Int = -1 + var cutoutTextRes: Int = INVALID_ID var cutoutText: String? = null - var cutoutDrawableRes: Int = -1 + var cutoutDrawableRes: Int = INVALID_ID var cutoutDrawable: Drawable? = null var cutoutForeground: Int? = null var libPageTitleRes: Int = R.string.kau_about_libraries_intro var libPageTitle: String? = null set(value) { field = value - libPageTitleRes = -1 //reset res so we don't use our default + libPageTitleRes = INVALID_ID //reset res so we don't use our default } - var faqXmlRes: Int = -1 + var faqXmlRes: Int = INVALID_ID var faqPageTitleRes: Int = R.string.kau_about_faq_intro var faqPageTitle: String? = null set(value) { field = value - faqPageTitleRes = -1 //reset res so we don't use our default + faqPageTitleRes = INVALID_ID //reset res so we don't use our default } /** * Whether new lines should be included diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt b/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt index 036f16c..59ab39a 100644 --- a/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt +++ b/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt @@ -2,6 +2,7 @@ package ca.allanwang.kau.about import android.content.Context import android.content.res.Configuration +import android.support.v7.widget.AppCompatTextView import android.util.AttributeSet import android.widget.TextView import ca.allanwang.kau.ui.views.CollapsibleView @@ -13,7 +14,7 @@ import ca.allanwang.kau.ui.views.CollapsibleViewDelegate */ class CollapsibleTextView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : TextView(context, attrs, defStyleAttr), CollapsibleView by CollapsibleViewDelegate() { +) : AppCompatTextView(context, attrs, defStyleAttr), CollapsibleView by CollapsibleViewDelegate() { init { initCollapsible(this) diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt index 2f25d8c..b754cb4 100644 --- a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt +++ b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt @@ -1,9 +1,10 @@ package ca.allanwang.kau.adapters -import android.view.View import com.mikepenz.fastadapter.FastAdapter import com.mikepenz.fastadapter.IAdapter +import com.mikepenz.fastadapter.IAdapterExtension import com.mikepenz.fastadapter.IItem +import com.mikepenz.fastadapter.select.SelectExtension /** * Created by Allan Wang on 2017-11-08. @@ -13,4 +14,16 @@ import com.mikepenz.fastadapter.IItem * Add kotlin's generic syntax to better support out types */ fun > fastAdapter(vararg adapter: IAdapter) = - FastAdapter.with>(adapter.toList())!! \ No newline at end of file + FastAdapter.with>(adapter.toList())!! + +inline fun , Item : IItem<*, *>> FastAdapter.getExtension(): T? = + getExtension(T::class.java) + +/** + * Returns selection size, or -1 if selection is disabled + */ +inline val > IAdapter.selectionSize: Int + get() = fastAdapter.getExtension, Item>()?.selections?.size ?: -1 + +inline val > IAdapter.selectedItems: Set + get() = fastAdapter.getExtension, Item>()?.selectedItems ?: emptySet() diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt index 6ce81a3..9fd5512 100644 --- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt +++ b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt @@ -56,17 +56,17 @@ class CardIItem( class Config { var title: String? = null - var titleRes: Int = -1 + var titleRes: Int = INVALID_ID var desc: String? = null - var descRes: Int = -1 + var descRes: Int = INVALID_ID var button: String? = null - var buttonRes: Int = -1 + var buttonRes: Int = INVALID_ID var buttonClick: (() -> Unit)? = null var cardClick: (() -> Unit)? = null var image: Drawable? = null var imageIIcon: IIcon? = null var imageIIconColor: Int = Color.WHITE - var imageRes: Int = -1 + var imageRes: Int = INVALID_ID } override fun bindView(holder: ViewHolder, payloads: MutableList) { @@ -81,8 +81,9 @@ class CardIItem( holder.bottomRow.visible() holder.button.text = buttonText } - val icon = if (imageRes > 0) drawable(imageRes) - else imageIIcon?.toDrawable(this@context, sizeDp = 24, color = imageIIconColor) ?: image + val icon = drawable(imageRes) { + imageIIcon?.toDrawable(this@context, sizeDp = 24, color = imageIIconColor) ?: image + } if (icon != null) holder.icon.visible().setImageDrawable(icon) } with(holder) { diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt index 8367e7c..67e7d30 100644 --- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt +++ b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt @@ -7,6 +7,7 @@ import android.widget.TextView import ca.allanwang.kau.adapter.R import ca.allanwang.kau.adapters.ThemableIItem import ca.allanwang.kau.adapters.ThemableIItemDelegate +import ca.allanwang.kau.utils.INVALID_ID import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.string @@ -17,7 +18,7 @@ import ca.allanwang.kau.utils.string * Contains only one text view */ class HeaderIItem( - text: String? = null, var textRes: Int = -1 + text: String? = null, var textRes: Int = INVALID_ID ) : KauIItem( R.layout.kau_iitem_header, { ViewHolder(it) }, R.id.kau_item_header_big_margin_top ), ThemableIItem by ThemableIItemDelegate() { diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt index c01dea4..196959c 100644 --- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt +++ b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt @@ -1,5 +1,6 @@ package ca.allanwang.kau.iitems +import android.annotation.SuppressLint import android.support.annotation.LayoutRes import android.support.v7.widget.RecyclerView import android.view.View @@ -18,6 +19,7 @@ open class KauIItem( private val viewHolder: (v: View) -> VH, private val type: Int = layoutRes ) : AbstractItem() where Item : IItem<*, *>, Item : IClickable<*> { + @SuppressLint("ResourceType") final override fun getType(): Int = type final override fun getViewHolder(v: View): VH = viewHolder(v) final override fun getLayoutRes(): Int = layoutRes diff --git a/build.gradle b/build.gradle index 341dcd1..3ddfb9c 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,8 @@ buildscript { classpath kauPlugin.dexCount classpath kauPlugin.gitVersion } + + wrapper.setDistributionType(Wrapper.DistributionType.ALL) } apply plugin: "ca.allanwang.kau" @@ -40,4 +42,4 @@ subprojects { jcenter() maven { url "https://jitpack.io" } } -} \ No newline at end of file +} diff --git a/buildSrc/src/main/groovy/ca/allanwang/kau/Versions.groovy b/buildSrc/src/main/groovy/ca/allanwang/kau/Versions.groovy index e34de9c..0e4c29a 100644 --- a/buildSrc/src/main/groovy/ca/allanwang/kau/Versions.groovy +++ b/buildSrc/src/main/groovy/ca/allanwang/kau/Versions.groovy @@ -5,20 +5,22 @@ class Versions { static def minSdk = 21 static def targetSdk = 27 - static def buildTools = '27.0.2' - static def supportLibs = '27.1.0' + static def buildTools = '27.0.3' + static def supportLibs = '27.1.1' - static def kotlin = '1.2.30' + static def kotlin = '1.2.31' - static def aboutLibraries = '6.0.6' + static def aboutLibraries = '6.0.8' static def anko = '0.10.4' static def blurry = '2.1.1' - static def constraintLayout = '1.1.0-beta5' - static def fastAdapter = '3.2.4' + + // https://dl.google.com/dl/android/maven2/com/android/support/constraint/group-index.xml + static def constraintLayout = '1.1.0-beta6' + static def fastAdapter = '3.2.5' static def fastAdapterCommons = fastAdapter static def glide = '4.6.1' - static def iconics = '3.0.2' + static def iconics = '3.0.3' static def iconicsGoogle = '3.0.1.2' static def iconicsMaterial = '2.2.0.4' static def iconicsCommunity = '2.0.46.1' @@ -29,7 +31,7 @@ class Versions { static def junit = '4.12' static def testRunner = '1.0.1' - static def gradlePlugin = '3.0.1' + static def gradlePlugin = '3.1.0' static def mavenPlugin = '2.0' static def playPublishPlugin = '1.2.0' static def dexCountPlugin = '0.8.2' diff --git a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt index ccebb71..b264e58 100644 --- a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt +++ b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt @@ -4,13 +4,14 @@ import android.content.Context import android.graphics.Color import android.support.annotation.DimenRes import android.support.annotation.StringRes +import ca.allanwang.kau.utils.INVALID_ID import ca.allanwang.kau.utils.string import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.Theme class ColorBuilder : ColorContract { override var title: String? = null - override var titleRes: Int = -1 + override var titleRes: Int = INVALID_ID override var allowCustom: Boolean = true override var allowCustomAlpha: Boolean = false override var isAccent: Boolean = false diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt new file mode 100644 index 0000000..db28914 --- /dev/null +++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt @@ -0,0 +1,6 @@ +package ca.allanwang.kau.kotlin + +/** + * Created by Allan Wang on 07/04/18. + */ +inline fun javaClass(): Class = T::class.java \ No newline at end of file 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 67da3f9..fdee4d8 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt @@ -93,24 +93,29 @@ inline fun Context.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: B if (log) KL.i { "Toast: $text" } } +const val INVALID_ID = 0 + //Resource retrievers inline fun Context.string(@StringRes id: Int): String = getString(id) -inline fun Context.string(@StringRes id: Int, fallback: String?): String? = if (id > 0) string(id) else fallback +inline fun Context.string(@StringRes id: Int, fallback: String?): String? = if (id != INVALID_ID) string(id) else fallback +inline fun Context.string(@StringRes id: Int, fallback: () -> String?): String? = if (id != INVALID_ID) string(id) else fallback() inline fun Context.color(@ColorRes id: Int): Int = ContextCompat.getColor(this, id) inline fun Context.boolean(@BoolRes id: Int): Boolean = resources.getBoolean(id) inline fun Context.integer(@IntegerRes id: Int): Int = resources.getInteger(id) inline fun Context.dimen(@DimenRes id: Int): Float = resources.getDimension(id) inline fun Context.dimenPixelSize(@DimenRes id: Int): Int = resources.getDimensionPixelSize(id) -inline fun Context.drawable(@DrawableRes id: Int): Drawable = ContextCompat.getDrawable(this, id) ?: throw KauException("Drawable with id $id not found") -inline fun Context.drawable(@DrawableRes id: Int, fallback: Drawable?): Drawable? = if (id > 0) drawable(id) else fallback +inline fun Context.drawable(@DrawableRes id: Int): Drawable = ContextCompat.getDrawable(this, id) + ?: throw KauException("Drawable with id $id not found") + +inline fun Context.drawable(@DrawableRes id: Int, fallback: Drawable?): Drawable? = if (id != INVALID_ID) drawable(id) else fallback +inline fun Context.drawable(@DrawableRes id: Int, fallback: () -> Drawable?): Drawable? = if (id != INVALID_ID) drawable(id) else fallback() inline fun Context.interpolator(@InterpolatorRes id: Int) = AnimationUtils.loadInterpolator(this, id)!! inline fun Context.animation(@AnimRes id: Int) = AnimationUtils.loadAnimation(this, id)!! /** * Returns plural form of res. The quantity is also passed to the formatter as an int */ -inline fun Context.plural(@PluralsRes id: Int, quantity: Number) - = resources.getQuantityString(id, quantity.toInt(), quantity.toInt())!! +inline fun Context.plural(@PluralsRes id: Int, quantity: Number) = resources.getQuantityString(id, quantity.toInt(), quantity.toInt())!! //Attr retrievers fun Context.resolveColor(@AttrRes attr: Int, fallback: Int = 0): Int { diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt index f3c08bd..b0448d1 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt @@ -30,15 +30,27 @@ fun Activity.bindView(id: Int) fun Dialog.bindView(id: Int) : ReadOnlyProperty = required(id, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindViewResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindViewResettable(id)"), + DeprecationLevel.WARNING) fun DialogFragment.bindView(id: Int) : ReadOnlyProperty = required(id, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindViewResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindViewResettable(id)"), + DeprecationLevel.WARNING) fun SupportDialogFragment.bindView(id: Int) : ReadOnlyProperty = required(id, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindViewResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindViewResettable(id)"), + DeprecationLevel.WARNING) fun Fragment.bindView(id: Int) : ReadOnlyProperty = required(id, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindViewResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindViewResettable(id)"), + DeprecationLevel.WARNING) fun SupportFragment.bindView(id: Int) : ReadOnlyProperty = required(id, viewFinder) @@ -54,15 +66,27 @@ fun Activity.bindOptionalView(id: Int) fun Dialog.bindOptionalView(id: Int) : ReadOnlyProperty = optional(id, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindOptionalViewResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindOptionalViewResettable(id)"), + DeprecationLevel.WARNING) fun DialogFragment.bindOptionalView(id: Int) : ReadOnlyProperty = optional(id, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindOptionalViewResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindOptionalViewResettable(id)"), + DeprecationLevel.WARNING) fun SupportDialogFragment.bindOptionalView(id: Int) : ReadOnlyProperty = optional(id, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindOptionalViewResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindOptionalViewResettable(id)"), + DeprecationLevel.WARNING) fun Fragment.bindOptionalView(id: Int) : ReadOnlyProperty = optional(id, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindOptionalViewResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindOptionalViewResettable(id)"), + DeprecationLevel.WARNING) fun SupportFragment.bindOptionalView(id: Int) : ReadOnlyProperty = optional(id, viewFinder) @@ -78,15 +102,27 @@ fun Activity.bindViews(vararg ids: Int) fun Dialog.bindViews(vararg ids: Int) : ReadOnlyProperty> = required(ids, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindViewsResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindViewsResettable(*ids)"), + DeprecationLevel.WARNING) fun DialogFragment.bindViews(vararg ids: Int) : ReadOnlyProperty> = required(ids, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindViewsResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindViewsResettable(*ids)"), + DeprecationLevel.WARNING) fun SupportDialogFragment.bindViews(vararg ids: Int) : ReadOnlyProperty> = required(ids, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindViewsResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindViewsResettable(*ids)"), + DeprecationLevel.WARNING) fun Fragment.bindViews(vararg ids: Int) : ReadOnlyProperty> = required(ids, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindViewsResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindViewsResettable(*ids)"), + DeprecationLevel.WARNING) fun SupportFragment.bindViews(vararg ids: Int) : ReadOnlyProperty> = required(ids, viewFinder) @@ -102,15 +138,27 @@ fun Activity.bindOptionalViews(vararg ids: Int) fun Dialog.bindOptionalViews(vararg ids: Int) : ReadOnlyProperty> = optional(ids, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindOptionalViewsResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindOptionalViewsResettable(*ids)"), + DeprecationLevel.WARNING) fun DialogFragment.bindOptionalViews(vararg ids: Int) : ReadOnlyProperty> = optional(ids, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindOptionalViewsResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindOptionalViewsResettable(*ids)"), + DeprecationLevel.WARNING) fun SupportDialogFragment.bindOptionalViews(vararg ids: Int) : ReadOnlyProperty> = optional(ids, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindOptionalViewsResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindOptionalViewsResettable(*ids)"), + DeprecationLevel.WARNING) fun Fragment.bindOptionalViews(vararg ids: Int) : ReadOnlyProperty> = optional(ids, viewFinder) +@Deprecated("Fragments operate on a different lifecycle. Consider using bindOptionalViewsResettable and resetting using KotterKnife.reset(this)", + ReplaceWith("bindOptionalViewsResettable(*ids)"), + DeprecationLevel.WARNING) fun SupportFragment.bindOptionalViews(vararg ids: Int) : ReadOnlyProperty> = optional(ids, viewFinder) @@ -137,17 +185,19 @@ private inline val ViewHolder.viewFinder: ViewHolder.(Int) -> View? private fun viewNotFound(id: Int, desc: KProperty<*>): Nothing = throw IllegalStateException("View ID $id for '${desc.name}' not found.") -private fun required(id: Int, finder: T.(Int) -> View?) - = Lazy { t: T, desc -> (t.finder(id) as V?)?.apply { } ?: viewNotFound(id, desc) } +private fun required(id: Int, finder: T.(Int) -> View?) = Lazy { t: T, desc -> + (t.finder(id) as V?)?.apply { } ?: viewNotFound(id, desc) +} -private fun optional(id: Int, finder: T.(Int) -> View?) - = Lazy { t: T, _ -> t.finder(id) as V? } +private fun optional(id: Int, finder: T.(Int) -> View?) = Lazy { t: T, _ -> t.finder(id) as V? } -private fun required(ids: IntArray, finder: T.(Int) -> View?) - = Lazy { t: T, desc -> ids.map { t.finder(it) as V? ?: viewNotFound(it, desc) } } +private fun required(ids: IntArray, finder: T.(Int) -> View?) = Lazy { t: T, desc -> + ids.map { + t.finder(it) as V? ?: viewNotFound(it, desc) + } +} -private fun optional(ids: IntArray, finder: T.(Int) -> View?) - = Lazy { t: T, _ -> ids.map { t.finder(it) as V? }.filterNotNull() } +private fun optional(ids: IntArray, finder: T.(Int) -> View?) = Lazy { t: T, _ -> ids.map { t.finder(it) as V? }.filterNotNull() } // Like Kotlin's lazy delegate but the initializer gets the target and metadata passed to it private open class Lazy(private val initializer: (T, KProperty<*>) -> V) : ReadOnlyProperty { @@ -269,17 +319,19 @@ fun SupportFragment.bindOptionalViewsResettable(vararg ids: Int) fun ViewHolder.bindOptionalViewsResettable(vararg ids: Int) : ReadOnlyProperty> = optionalResettable(ids, viewFinder) -private fun requiredResettable(id: Int, finder: T.(Int) -> View?) - = LazyResettable { t: T, desc -> (t.finder(id) as V?)?.apply { } ?: viewNotFound(id, desc) } +private fun requiredResettable(id: Int, finder: T.(Int) -> View?) = LazyResettable { t: T, desc -> + (t.finder(id) as V?)?.apply { } ?: viewNotFound(id, desc) +} -private fun optionalResettable(id: Int, finder: T.(Int) -> View?) - = LazyResettable { t: T, _ -> t.finder(id) as V? } +private fun optionalResettable(id: Int, finder: T.(Int) -> View?) = LazyResettable { t: T, _ -> t.finder(id) as V? } -private fun requiredResettable(ids: IntArray, finder: T.(Int) -> View?) - = LazyResettable { t: T, desc -> ids.map { t.finder(it) as V? ?: viewNotFound(it, desc) } } +private fun requiredResettable(ids: IntArray, finder: T.(Int) -> View?) = LazyResettable { t: T, desc -> + ids.map { + t.finder(it) as V? ?: viewNotFound(it, desc) + } +} -private fun optionalResettable(ids: IntArray, finder: T.(Int) -> View?) - = LazyResettable { t: T, _ -> ids.map { t.finder(it) as V? }.filterNotNull() } +private fun optionalResettable(ids: IntArray, finder: T.(Int) -> View?) = LazyResettable { t: T, _ -> ids.map { t.finder(it) as V? }.filterNotNull() } //Like Kotterknife's lazy delegate but is resettable private class LazyResettable(initializer: (T, KProperty<*>) -> V) : Lazy(initializer) { @@ -302,8 +354,7 @@ object Kotterknife { private object KotterknifeRegistry { private val lazyMap = WeakHashMap>>() - fun register(target: Any, lazy: LazyResettable<*, *>) - = lazyMap.getOrPut(target, { Collections.newSetFromMap(WeakHashMap()) }).add(lazy) + fun register(target: Any, lazy: LazyResettable<*, *>) = lazyMap.getOrPut(target, { Collections.newSetFromMap(WeakHashMap()) }).add(lazy) - fun reset(target: Any) = lazyMap[target]?.forEach { it.reset() } + fun reset(target: Any) = lazyMap[target]?.forEach(LazyResettable<*, *>::reset) } \ No newline at end of file diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt index 484e5bd..9a1e9b0 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt @@ -72,11 +72,6 @@ fun View.snackbar(text: String, duration: Int = Snackbar.LENGTH_LONG, builder: S fun View.snackbar(@StringRes textId: Int, duration: Int = Snackbar.LENGTH_LONG, builder: Snackbar.() -> Unit = {}) = snackbar(context.string(textId), duration, builder) -@KauUtils -fun TextView.setTextIfValid(@StringRes id: Int) { - if (id > 0) text = context.string(id) -} - @KauUtils fun ImageView.setIcon(icon: IIcon?, sizeDp: Int = 24, @ColorInt color: Int = Color.WHITE, builder: IconicsDrawable.() -> Unit = {}) { if (icon == null) return diff --git a/dependencies.gradle b/dependencies.gradle deleted file mode 100644 index 08a3869..0000000 --- a/dependencies.gradle +++ /dev/null @@ -1,28 +0,0 @@ -ext.versions = [ - coreMinSdk : 19, - minSdk : 21, - targetSdk : 27, - buildTools : '27.0.2', - - gradlePlugin : '3.0.1', - mavenPlugin : '2.0', - playPublishPlugin : '1.2.0', - dexCountPlugin : '0.8.2', - - supportLib : '27.0.2', - kotlin : '1.2.20', - aboutLibraries : '6.0.1', - anko : '0.10.4', - blurry : '2.1.1', - constraintLayout : '1.1.0-beta4', - fastAdapter : '3.1.2', - fastAdapterCommons : '3.1.2', - glide : '4.5.0', - iconics : '3.0.0', - iiconGoogle : '3.0.1.2', - materialDialog : '0.9.6.0', - - espresso : '3.0.0', - junit : '4.12', - testRunner : '1.0.0' -] diff --git a/docs/Changelog.md b/docs/Changelog.md index 937db20..f655515 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -1,5 +1,12 @@ # Changelog +## v3.8.0 +* Update everything to Android Studio 3.1 +* Fix new lint issues (see Migration for resource related methods) + +## v3.7.1 +* Update appcompat to 27.1.0 + ## v3.7.0 * :core: Fix potential NPE in restart() * :core: Create restartApplication() diff --git a/docs/Migration.md b/docs/Migration.md index 1d8cd9d..721cd0d 100644 --- a/docs/Migration.md +++ b/docs/Migration.md @@ -2,6 +2,13 @@ Below are some highlights on major refactoring/breaking changes +# v3.8.0 + +Along with the update to support Android Studio 3.1, a lot of changes have occurred with other dependencies and with lint. + +* Resource ids can be negatives due to the bit overflow. Instead, `INVALID_ID` has been introduced to signify an unset or invalid id. +Methods such as `Context.string(id, fallback)` now check against `INVALID_ID` through equality rather than using an inequality to address this. + # v3.6.0 ## startActivity diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 13372ae..f6b961f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 47b34c0..9a4163a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Tue Aug 29 17:23:46 EDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/gradlew b/gradlew index 9d82f78..cccdd3d 100644 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,20 +6,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -150,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282..f955316 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt index 992dd28..2491d01 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt @@ -34,7 +34,7 @@ abstract class KPrefItemCore(val core: CoreContract) : AbstractItem 0) + if (descRes != INVALID_ID) desc?.visible()?.setText(descRes) else desc?.gone() @@ -118,12 +118,12 @@ abstract class KPrefItemCore(val core: CoreContract) : AbstractItem + tools:ignore="RtlSymmetry" + tools:layout_editor_absoluteX="0dp" /> + app:layout_constraintTop_toTopOf="parent" + tools:ignore="NotSibling" /> - selectionCount.text = adapter.fastAdapter.selections.size.toString() + selectionCount.text = adapter.selectionSize.toString() } fab.apply { show() setIcon(GoogleMaterial.Icon.gmd_send) setOnClickListener { - val selection = adapter.fastAdapter.selectedItems + val selection = adapter.selectedItems if (selection.isEmpty()) { toast(R.string.kau_no_items_selected) } else { diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml index cb59c23..636525f 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -6,6 +6,15 @@ --> + + + + + + + + + diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt index 52a88a0..837b714 100644 --- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt +++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt @@ -121,7 +121,7 @@ class SearchView @JvmOverloads constructor( /** * Hint string res to be set in the searchView */ - var hintTextRes: Int = -1 + var hintTextRes: Int = INVALID_ID /** * StringRes for a "no results found" item @@ -131,7 +131,7 @@ class SearchView @JvmOverloads constructor( * For simplicity, kau contains [R.string.kau_no_results_found] * which you may use */ - var noResultsFound: Int = -1 + var noResultsFound: Int = INVALID_ID /** * Callback for when the query changes @@ -212,7 +212,7 @@ class SearchView @JvmOverloads constructor( var results: List get() = adapter.adapterItems set(value) = context.runOnUiThread { - val list = if (value.isEmpty() && configs.noResultsFound > 0) + val list = if (value.isEmpty() && configs.noResultsFound != INVALID_ID) listOf(SearchItem("", context.string(configs.noResultsFound), iicon = null)) else value if (configs.highlightQueryText && value.isNotEmpty()) list.forEach { it.withHighlights(editText.text.toString()) } -- cgit v1.2.3