From 30da9477516d104bacf8ded7acea0a22436512f0 Mon Sep 17 00:00:00 2001
From: Jieyi
Date: Thu, 28 Feb 2019 18:56:07 +0900
Subject: [PATCH] Feature: added more utils.
---
kotlinknifer/build.gradle | 5 +-
.../com/devrapid/kotlinknifer/Animation.kt | 113 ++++++++++++++++++
.../java/com/devrapid/kotlinknifer/Bitmap.kt | 64 ++++++++--
.../java/com/devrapid/kotlinknifer/Bundle.kt | 24 ++++
.../com/devrapid/kotlinknifer/Collection.kt | 4 -
.../java/com/devrapid/kotlinknifer/Color.kt | 43 +++----
.../java/com/devrapid/kotlinknifer/Context.kt | 10 ++
.../com/devrapid/kotlinknifer/Delegate.kt | 14 +--
.../java/com/devrapid/kotlinknifer/Display.kt | 6 +-
.../com/devrapid/kotlinknifer/Drawable.kt | 47 ++------
.../com/devrapid/kotlinknifer/Fragment.kt | 4 -
.../java/com/devrapid/kotlinknifer/Glide.kt | 49 --------
.../com/devrapid/kotlinknifer/Keyboard.kt | 4 -
.../com/devrapid/kotlinknifer/Listener.kt | 19 ++-
.../java/com/devrapid/kotlinknifer/Logs.kt | 10 --
.../java/com/devrapid/kotlinknifer/Network.kt | 26 ++++
.../com/devrapid/kotlinknifer/Resolution.kt | 4 -
.../java/com/devrapid/kotlinknifer/Screen.kt | 6 +-
.../com/devrapid/kotlinknifer/Spannable.kt | 27 +++++
.../java/com/devrapid/kotlinknifer/Toast.kt | 16 +++
.../java/com/devrapid/kotlinknifer/View.kt | 8 +-
.../com/devrapid/kotlinknifer/ViewStub.kt | 28 +++++
.../kotlinknifer/recyclerview/Extensions.kt | 13 ++
.../WrapContentLinearLayoutManager.kt | 6 -
.../com/devrapid/kotlinshaver/ArrayList.kt | 10 +-
.../java/com/devrapid/kotlinshaver/Casting.kt | 1 +
.../com/devrapid/kotlinshaver/Coroutine.kt | 8 +-
.../java/com/devrapid/kotlinshaver/Field.kt | 2 -
.../com/devrapid/kotlinshaver/Instance.kt | 7 +-
.../java/com/devrapid/kotlinshaver/Int.kt | 2 -
.../java/com/devrapid/kotlinshaver/Kits.kt | 5 -
.../java/com/devrapid/kotlinshaver/String.kt | 8 +-
.../java/com/devrapid/kotlinshaver/Thread.kt | 8 +-
.../java/com/devrapid/kotlinshaver/Time.kt | 25 ++--
.../com/devrapid/kotlinshaver/TypeAliases.kt | 8 ++
.../kotlinshaver/{ => rxjava2}/Completable.kt | 8 +-
.../kotlinshaver/{ => rxjava2}/Observable.kt | 7 +-
.../kotlinshaver/{ => rxjava2}/Observer.kt | 10 +-
.../kotlinshaver/{ => rxjava2}/Single.kt | 8 +-
39 files changed, 393 insertions(+), 274 deletions(-)
create mode 100644 kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Animation.kt
create mode 100644 kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Bundle.kt
create mode 100644 kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Context.kt
create mode 100644 kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Network.kt
create mode 100644 kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Spannable.kt
create mode 100644 kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Toast.kt
create mode 100644 kotlinknifer/src/main/java/com/devrapid/kotlinknifer/ViewStub.kt
create mode 100644 kotlinknifer/src/main/java/com/devrapid/kotlinknifer/recyclerview/Extensions.kt
create mode 100644 kotlinshaver/src/main/java/com/devrapid/kotlinshaver/TypeAliases.kt
rename kotlinshaver/src/main/java/com/devrapid/kotlinshaver/{ => rxjava2}/Completable.kt (89%)
rename kotlinshaver/src/main/java/com/devrapid/kotlinshaver/{ => rxjava2}/Observable.kt (95%)
rename kotlinshaver/src/main/java/com/devrapid/kotlinshaver/{ => rxjava2}/Observer.kt (90%)
rename kotlinshaver/src/main/java/com/devrapid/kotlinshaver/{ => rxjava2}/Single.kt (90%)
diff --git a/kotlinknifer/build.gradle b/kotlinknifer/build.gradle
index 07befb5..0ce1017 100644
--- a/kotlinknifer/build.gradle
+++ b/kotlinknifer/build.gradle
@@ -26,14 +26,15 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
// 'compile' can also import to the new project with this.
compile "com.google.code.gson:gson:2.8.5"
- compile "com.github.bumptech.glide:glide:4.8.0"
+ compile "com.github.bumptech.glide:glide:4.9.0"
// 'implementation' can't import to the new project.
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutine_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$kotlin_coroutine_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutine_version"
implementation "org.jetbrains.anko:anko-commons:0.10.8"
implementation "androidx.appcompat:appcompat:1.0.2"
- implementation "androidx.recyclerview:recyclerview:1.1.0-alpha01"
+ implementation "androidx.core:core-ktx:1.0.1"
+ implementation "androidx.recyclerview:recyclerview:1.1.0-alpha02"
implementation "androidx.palette:palette:1.0.0"
compile project(":kotlinshaver")
}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Animation.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Animation.kt
new file mode 100644
index 0000000..2aff89b
--- /dev/null
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Animation.kt
@@ -0,0 +1,113 @@
+package com.devrapid.kotlinknifer
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ArgbEvaluator
+import android.animation.ValueAnimator
+import android.os.Build
+import android.os.Parcel
+import android.os.Parcelable
+import android.view.View
+import android.view.ViewAnimationUtils
+import androidx.interpolator.view.animation.FastOutSlowInInterpolator
+import kotlin.math.pow
+
+fun View.registerCircularRevealAnimation(
+ revealSettings: RevealAnimationSetting,
+ startColor: Int,
+ endColor: Int
+) {
+ val duration = 1000L
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
+ override fun onLayoutChange(
+ v: View,
+ left: Int,
+ top: Int,
+ right: Int,
+ bottom: Int,
+ oldLeft: Int,
+ oldTop: Int,
+ oldRight: Int,
+ oldBottom: Int
+ ) {
+ v.removeOnLayoutChangeListener(this)
+ val (cx, cy, width, height) = revealSettings
+
+ // Simply use the diagonal of the view.
+ val radius = Math.sqrt((width.toDouble().pow(2) + height.toDouble().pow(2))).toFloat()
+ ViewAnimationUtils.createCircularReveal(v, cx, cy, 0f, radius).apply {
+ this.duration = duration
+ interpolator = FastOutSlowInInterpolator()
+ }.start()
+ }
+ })
+ startColorAnimation(startColor, endColor, duration)
+ }
+}
+
+fun View.startCircularExitAnimation(
+ revealSettings: RevealAnimationSetting,
+ startColor: Int,
+ endColor: Int,
+ listener: () -> Unit
+) {
+ val duration = 1000L
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ val (cx, cy, width, height) = revealSettings
+
+ // Simply use the diagonal of the view.
+ val radius = Math.sqrt((width.toDouble().pow(2) + height.toDouble().pow(2))).toFloat()
+ ViewAnimationUtils.createCircularReveal(this, cx, cy, radius, 0f).apply {
+ this.duration = duration
+ interpolator = FastOutSlowInInterpolator()
+ addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ gone()
+ listener()
+ }
+ })
+ }.start()
+ startColorAnimation(startColor, endColor, duration)
+ }
+ else {
+ listener()
+ }
+}
+
+fun View.startColorAnimation(
+ startColor: Int,
+ endColor: Int,
+ duration: Long
+) {
+ ValueAnimator().apply {
+ this.duration = duration
+ setIntValues(startColor, endColor)
+ setEvaluator(ArgbEvaluator())
+ addUpdateListener { setBackgroundColor(it.animatedValue as Int) }
+ }.start()
+}
+
+data class RevealAnimationSetting(
+ var centerX: Int,
+ var centerY: Int,
+ var width: Int,
+ var height: Int
+) : Parcelable {
+ companion object CREATOR : Parcelable.Creator {
+ override fun createFromParcel(parcel: Parcel) = RevealAnimationSetting(parcel)
+
+ override fun newArray(size: Int) = arrayOfNulls(size)
+ }
+
+ constructor(parcel: Parcel) : this(parcel.readInt(), parcel.readInt(), parcel.readInt(), parcel.readInt())
+
+ override fun writeToParcel(parcel: Parcel, flags: Int) {
+ parcel.writeInt(centerX)
+ parcel.writeInt(centerY)
+ parcel.writeInt(width)
+ parcel.writeInt(height)
+ }
+
+ override fun describeContents(): Int = 0
+}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Bitmap.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Bitmap.kt
index 17e5f22..ac8cc4b 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Bitmap.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Bitmap.kt
@@ -1,15 +1,25 @@
package com.devrapid.kotlinknifer
+import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.BitmapRegionDecoder
+import android.graphics.BitmapShader
import android.graphics.Canvas
+import android.graphics.ComposeShader
+import android.graphics.Paint
+import android.graphics.PorterDuff
import android.graphics.Rect
+import android.graphics.Shader
import android.graphics.drawable.BitmapDrawable
-import android.graphics.drawable.Drawable
+import android.renderscript.Allocation
+import android.renderscript.Element
+import android.renderscript.RenderScript
+import android.renderscript.ScriptIntrinsicBlur
import android.util.Size
import androidx.annotation.DrawableRes
+import androidx.palette.graphics.Palette
import java.io.ByteArrayOutputStream
/**
@@ -86,19 +96,11 @@ fun Resources.createRegionBitmap(
decoder.decodeRegion(rect, opts)
}
-fun Drawable.toBitmap(): Bitmap {
- if (this is BitmapDrawable) return bitmap
+inline fun Bitmap.toDrawable(context: Context) = BitmapDrawable(context.resources, this)
- val width = if (bounds.isEmpty) intrinsicWidth else bounds.width()
- val height = if (bounds.isEmpty) intrinsicHeight else bounds.height()
+inline fun Bitmap.palette() = Palette.from(this)
- return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also {
- Canvas(it).let {
- setBounds(0, 0, it.width, it.height)
- draw(it)
- }
- }
-}
+inline fun Bitmap.palette(maxColorCount: Int) = Palette.from(this).maximumColorCount(maxColorCount).generate()
fun Bitmap.toBytes(format: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG, quality: Int = 100) {
val stream = ByteArrayOutputStream()
@@ -120,6 +122,44 @@ fun Bitmap?.safeRecycle() {
recycle()
}
+fun Bitmap.decorateGradientMask(shaderDst: Shader): Bitmap {
+ val res = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(res)
+ // Create the source shader bitmap.
+ val shaderSrc = BitmapShader(this, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
+
+ val paint = Paint().apply {
+ shader = ComposeShader(shaderDst, shaderSrc, PorterDuff.Mode.SRC_IN)
+ }
+ canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
+
+ return res
+}
+
+fun Context.blurBitmap(image: Bitmap, radius: Float = 25f, scale: Float = 0.4f): Bitmap {
+ val width = Math.round(image.width * scale)
+ val height = Math.round(image.height * scale)
+ // Because of the blurring, we don't have to use original bitmap to blur. It's able to reduce cost.
+ val scaledBitmap = Bitmap.createScaledBitmap(image, width, height, false)
+ // Create a image for blurring.
+ val blurBitmap = Bitmap.createBitmap(scaledBitmap)
+ val rs = RenderScript.create(this)
+ // RenderScript doesn't use VM to allocate memory, we have to do it by ourselves.
+ val tmpIn = Allocation.createFromBitmap(rs, scaledBitmap)
+ // The created Allocation is empty actually, copyTo() is necessary to fill the date.
+ val tmpOut = Allocation.createFromBitmap(rs, blurBitmap)
+
+ ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)).apply {
+ setRadius(radius)
+ setInput(tmpIn)
+ forEach(tmpOut)
+ }
+
+ tmpOut.copyTo(blurBitmap)
+
+ return blurBitmap
+}
+
object ImageUtils {
/**
* @param originWidth the width of the origin bitmap
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Bundle.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Bundle.kt
new file mode 100644
index 0000000..a564a76
--- /dev/null
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Bundle.kt
@@ -0,0 +1,24 @@
+package com.devrapid.kotlinknifer
+
+import android.app.Activity
+import androidx.fragment.app.Fragment
+
+inline fun Activity.extra(key: String, default: T? = null) = lazy {
+ val value = intent?.extras?.get(key)
+ if (value is T) value else default
+}
+
+inline fun Activity.extraNotNull(key: String, default: T? = null) = lazy {
+ val value = intent?.extras?.get(key)
+ requireNotNull(if (value is T) value else default) { key }
+}
+
+inline fun Fragment.extra(key: String, default: T? = null) = lazy {
+ val value = arguments?.get(key)
+ if (value is T) value else default
+}
+
+inline fun Fragment.extraNotNull(key: String, default: T? = null) = lazy {
+ val value = arguments?.get(key)
+ requireNotNull(if (value is T) value else default) { key }
+}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Collection.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Collection.kt
index f01d799..02b9868 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Collection.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Collection.kt
@@ -4,10 +4,6 @@ package com.devrapid.kotlinknifer
import java.util.Stack
-/**
- * @author jieyi
- * @since 2018/01/12
- */
inline fun Stack.safePop() = lastOrNull()?.let { pop() }
inline fun Stack.safePeek() = lastOrNull()?.let { peek() }
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Color.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Color.kt
index 42c31fa..9c040a9 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Color.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Color.kt
@@ -1,5 +1,3 @@
-@file:Suppress("NOTHING_TO_INLINE", "EXTENSION_SHADOWED_BY_MEMBER")
-
package com.devrapid.kotlinknifer
import android.content.Context
@@ -8,12 +6,8 @@ import android.view.View
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
+import androidx.fragment.app.Fragment
-/**
- *
- * @author jieyi
- * @since 5/30/17
- */
/**
* Add the alpha into the [Color] from resource id.
*
@@ -23,39 +17,29 @@ import androidx.core.content.ContextCompat
* @return transparent RGB integer resColor
*/
@ColorInt
-inline fun Context.getResColorWithAlpha(@ColorRes resColor: Int, ratio: Float): Int =
- this.getColorWithAlpha(this.getResColor(resColor), ratio)
+inline fun Context.getColorOfAlpha(@ColorRes resColor: Int, ratio: Float) =
+ ContextCompat.getColor(this, resColor).ofAlpha(ratio)
@ColorInt
-inline fun View.getResColorWithAlpha(@ColorRes resColor: Int, ratio: Float): Int =
- this.context.getResColorWithAlpha(resColor, ratio)
+inline fun Fragment.getColorOfAlpha(@ColorRes resColor: Int, ratio: Float) = getColor(resColor).ofAlpha(ratio)
+
+@ColorInt
+inline fun View.getColorOfAlpha(@ColorRes resColor: Int, ratio: Float) = getColor(resColor).ofAlpha(ratio)
/**
* Add the alpha into the Color.
*
- * @param color opaque RGB integer color for ex: -11517920
* @param ratio ratio of transparency for ex: 0.5f
*
* @return transparent RGB integer resColor
*/
@ColorInt
-inline fun Context.getColorWithAlpha(@ColorInt color: Int, ratio: Float): Int {
- val a: Int = Math.round(Color.alpha(color) * ratio)
+inline fun Int.ofAlpha(ratio: Float): Int {
+ val alpha = Math.round(Color.alpha(this) * ratio)
- return Color.argb(a, Color.red(color), Color.green(color), Color.blue(color))
+ return Color.argb(alpha, Color.red(this), Color.green(this), Color.blue(this))
}
-@ColorInt
-inline fun View.getColorWithAlpha(@ColorInt color: Int, ratio: Float): Int =
- this.context.getColorWithAlpha(color, ratio)
-
-@ColorInt
-inline fun Context.getColorInt(@ColorInt color: Int) =
- Color.rgb(Color.red(color), Color.green(color), Color.blue(color))
-
-@ColorInt
-inline fun View.getColorInt(@ColorInt color: Int) = context.getColorInt(color)
-
/**
* Get the [Color] from resource id.
*
@@ -64,7 +48,7 @@ inline fun View.getColorInt(@ColorInt color: Int) = context.getColorInt(color)
* @return transparent RGB integer resColor
*/
@ColorInt
-inline fun Context.getResColor(@ColorRes resColor: Int): Int = ContextCompat.getColor(this, resColor)
+inline fun Fragment.getColor(@ColorRes resColor: Int) = ContextCompat.getColor(requireContext(), resColor)
/**
* Get the [Color] from resource id.
@@ -74,4 +58,7 @@ inline fun Context.getResColor(@ColorRes resColor: Int): Int = ContextCompat.get
* @return transparent RGB integer resColor
*/
@ColorInt
-inline fun View.getResColor(@ColorRes resColor: Int): Int = ContextCompat.getColor(this.context, resColor)
+inline fun View.getColor(@ColorRes resColor: Int) = ContextCompat.getColor(context, resColor)
+
+@ColorInt
+inline fun generateColorInt(@ColorInt color: Int) = Color.rgb(Color.red(color), Color.green(color), Color.blue(color))
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Context.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Context.kt
new file mode 100644
index 0000000..a68ba2b
--- /dev/null
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Context.kt
@@ -0,0 +1,10 @@
+package com.devrapid.kotlinknifer
+
+import android.app.ActivityManager
+import android.content.Context
+import androidx.appcompat.app.AppCompatActivity
+
+fun Context.closeCurrentTask(activity: AppCompatActivity) =
+ (getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).appTasks
+ .find { it.taskInfo.id == activity.taskId }
+ ?.finishAndRemoveTask()
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Delegate.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Delegate.kt
index 7342c6e..cb29022 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Delegate.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Delegate.kt
@@ -10,12 +10,6 @@ import kotlin.properties.Delegates
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
-/**
- * Delegate methods.
- *
- * @author jieyi
- * @since 6/12/17
- */
/**
* Wrap the [SoftReference] by kotlin delegate. Don't have to use [get]/[set] method
* for accessing or assigning a variable each of times.
@@ -125,10 +119,8 @@ class SharedPrefs(var defaultValue: T, val objectType: Class? = null, var
is Long -> prefs.getLong(name, defaultValue as Long) as T
is String -> prefs.getString(name, defaultValue as String) as T
is Set<*> -> prefs.getStringSet(name, defaultValue as Set) as T
- // Using json format to deserialize a string to an object.
- else -> this.gson.fromJson(prefs.getString(name,
- null) ?: throw KotlinNullPointerException("There is no kind of $name was stored in the shared preferences."),
- objectType)
+ // Using json format to deserialize a string to an object.
+ else -> prefs.getString(name, null)?.let { this.gson.fromJson(it, objectType) } ?: defaultValue
}
}
@@ -143,7 +135,7 @@ class SharedPrefs(var defaultValue: T, val objectType: Class? = null, var
is Long -> it.putLong(name, value as Long)
is String -> it.putString(name, value as String)
is Set<*> -> it.putStringSet(name, value as Set)
- // Using json format to serialize an object to a string.
+ // Using json format to serialize an object to a string.
else -> it.putString(name, this.gson.toJson(value))
}
this.onChange?.invoke()
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Display.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Display.kt
index b45f9b7..9241bc4 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Display.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Display.kt
@@ -6,10 +6,6 @@ import android.content.Context
import android.util.DisplayMetrics
import android.view.WindowManager
-/**
- * @author Jieyi Wu
- * @since 2018/03/19
- */
inline fun Context.getDisplayMetrics() = DisplayMetrics().also {
(getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay.getMetrics(it)
-}
\ No newline at end of file
+}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Drawable.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Drawable.kt
index 5270e1b..97e5e56 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Drawable.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Drawable.kt
@@ -1,26 +1,16 @@
-@file:Suppress("NOTHING_TO_INLINE")
-
package com.devrapid.kotlinknifer
import android.content.Context
import android.graphics.Bitmap
+import android.graphics.Canvas
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.Rect
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.ScaleDrawable
-import android.renderscript.Allocation
-import android.renderscript.Element
-import android.renderscript.RenderScript
-import android.renderscript.ScriptIntrinsicBlur
import androidx.annotation.DrawableRes
-import androidx.palette.graphics.Palette
-/**
- * @author jieyi
- * @since 11/20/17
- */
fun Context.scaledDrawable(@DrawableRes drawableId: Int, width: Int, height: Int): Drawable {
val drawable = getDrawable(drawableId)?.apply {
bounds = Rect(0, 0, width, height)
@@ -48,33 +38,16 @@ inline fun Drawable.changeColor(color: Int) = apply {
inline fun Int.toDrawable(context: Context) = context.getDrawable(this)
-inline fun Bitmap.toDrawable(context: Context) = BitmapDrawable(context.resources, this)
-
-inline fun Bitmap.palette() = Palette.from(this)
-
-inline fun Bitmap.palette(maxColorCount: Int) =
- Palette.from(this).maximumColorCount(maxColorCount).generate()
+fun Drawable.toBitmap(): Bitmap {
+ if (this is BitmapDrawable) return bitmap
-fun Context.blurBitmap(image: Bitmap, radius: Float = 25f, scale: Float = 0.4f): Bitmap {
- val width = Math.round(image.width * scale)
- val height = Math.round(image.height * scale)
- // Because of the blurring, we don't have to use original bitmap to blur. It's able to reduce cost.
- val scaledBitmap = Bitmap.createScaledBitmap(image, width, height, false)
- // Create a image for blurring.
- val blurBitmap = Bitmap.createBitmap(scaledBitmap)
- val rs = RenderScript.create(this)
- // RenderScript doesn't use VM to allocate memory, we have to do it by ourselves.
- val tmpIn = Allocation.createFromBitmap(rs, scaledBitmap)
- // The created Allocation is empty actually, copyTo() is necessary to fill the date.
- val tmpOut = Allocation.createFromBitmap(rs, blurBitmap)
+ val width = if (bounds.isEmpty) intrinsicWidth else bounds.width()
+ val height = if (bounds.isEmpty) intrinsicHeight else bounds.height()
- ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)).apply {
- setRadius(radius)
- setInput(tmpIn)
- forEach(tmpOut)
+ return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also {
+ Canvas(it).let {
+ setBounds(0, 0, it.width, it.height)
+ draw(it)
+ }
}
-
- tmpOut.copyTo(blurBitmap)
-
- return blurBitmap
}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Fragment.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Fragment.kt
index 921d7a4..ff73ca5 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Fragment.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Fragment.kt
@@ -8,10 +8,6 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import java.util.Stack
-/**
- * @author jieyi
- * @since 2/15/17
- */
/**
* Adds a [Fragment] to this manager's layout.
* Using the [replace] method, we couldn't obtain the fragments. There a way to get it is that
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Glide.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Glide.kt
index 86bc5a4..e7562f7 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Glide.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Glide.kt
@@ -5,10 +5,6 @@ import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
-/**
- * @author jieyi
- * @since 2018/01/09
- */
fun glideListener(listener: GlideRequestListenerWrapper.() -> Unit): RequestListener {
val wrapper = GlideRequestListenerWrapper().apply(listener)
@@ -33,21 +29,6 @@ fun glideListener(listener: GlideRequestListenerWrapper.() -> Unit): Requ
}
class GlideRequestListenerWrapper {
- /**
- * Called when a load completes successfully, immediately before [Target.onResourceReady].
- *
- * @param resource The resource that was loaded for the target.
- * @param model The specific model that was used to load the image.
- * @param target The target the model was loaded into.
- * @param dataSource The [DataSource] the resource was loaded from.
- * @param isFirstResource [true] if this is the first resource to in this load to be
- * loaded into the target. For example when loading a thumbnail and a
- * full-sized image, this will be [true] for the first image to
- * load and [false] for the second.
- * @return [true] if the listener has handled setting the resource on the target,
- * [false] to allow Glide's request to update the target.
- * Setting the resource includes handling animations, be sure to take that into account.
- */
var onResourceReady: ((
resource: T,
model: Any?,
@@ -55,36 +36,6 @@ class GlideRequestListenerWrapper {
dataSource: DataSource?,
isFirstResource: Boolean
) -> Boolean)? = null
- /**
- * Called when an exception occurs during a load, immediately before [Target.onLoadFailed].
- * Will only be called if we currently want to display an image for the given model
- * in the given target. It is recommended to create a single instance
- * per activity/fragment rather than instantiate a new object for each call to [Glide.load]
- * to avoid object churn.
- *
- * It is safe to reload this or a different model or change what is displayed in the target at
- * this point. For example:
- *
- * {@code
- * public void onLoadFailed(Exception e, T model, Target target, boolean isFirstResource) {
- * target.setPlaceholder(R.drawable.a_specific_error_for_my_exception);
- * Glide.load(model).into(target);
- * }
- * }
- *
- *
- *
- * Note - if you want to reload this or any other model after an exception, you will need to
- * include all relevant builder calls (like centerCrop, placeholder etc).
- *
- * @param e The maybe [null] exception containing information about why the
- * request failed.
- * @param model The model we were trying to load when the exception occurred.
- * @param target The [Target] we were trying to load the image into.
- * @param isFirstResource [true] if this exception is for the first resource to load.
- * @return [true] if the listener has handled updating the target for the given exception,
- * [false] to allow Glide's request to update the target.
- */
var onLoadFailed: ((e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean) -> Boolean)? =
null
}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Keyboard.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Keyboard.kt
index c2c0922..f27278c 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Keyboard.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Keyboard.kt
@@ -7,10 +7,6 @@ import android.graphics.Rect
import android.view.View
import android.view.inputmethod.InputMethodManager
-/**
- * @author jieyi
- * @since 11/8/17
- */
inline fun View.hideSoftKeyboard() = run {
(context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
.hideSoftInputFromWindow(windowToken, 0)
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Listener.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Listener.kt
index 4458c65..ffb912c 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Listener.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Listener.kt
@@ -2,11 +2,6 @@ package com.devrapid.kotlinknifer
import android.animation.Animator
-/**
- *
- * @author jieyi
- * @since 6/12/17
- */
fun animatorListener(init: AnimatorListenerWrapper.() -> Unit): Animator.AnimatorListener {
val wrapper = AnimatorListenerWrapper()
@@ -15,9 +10,9 @@ fun animatorListener(init: AnimatorListenerWrapper.() -> Unit): Animator.Animato
return onListener(wrapper)
}
- /**
- * Using chain style for [animatorListener].
- */
+/**
+ * Using chain style for [animatorListener].
+ */
typealias animatorWithSelf = AnimatorListener.(animator: Animator) -> Unit
class AnimatorListener : Animator.AnimatorListener {
@@ -40,9 +35,9 @@ class AnimatorListener : Animator.AnimatorListener {
this.also { it.repeatFunction = onRepeatFun }
}
- /**
- * Using DSL style for [animatorListener].
- */
+/**
+ * Using DSL style for [animatorListener].
+ */
typealias animatorEmpty = (animator: Animator) -> Unit
class AnimatorListenerWrapper {
@@ -75,4 +70,4 @@ private fun onListener(wrapper: AnimatorListenerWrapper): Animator.AnimatorListe
override fun onAnimationCancel(animator: Animator) = wrapper._cancel(animator)
override fun onAnimationRepeat(animator: Animator) = wrapper._repeat(animator)
}
-}
\ No newline at end of file
+}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Logs.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Logs.kt
index 7beb04c..a0720fc 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Logs.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Logs.kt
@@ -2,20 +2,10 @@ package com.devrapid.kotlinknifer
import android.util.Log
-/**
- * Log Module
- *
- * @author Jieyi
- * @since 8/1/15
- */
fun logv(vararg msg: Any?) = Logs.v(*msg)
-
fun logd(vararg msg: Any?) = Logs.d(*msg)
-
fun logi(vararg msg: Any?) = Logs.i(*msg)
-
fun logw(vararg msg: Any?) = Logs.w(*msg)
-
fun loge(vararg msg: Any?) = Logs.e(*msg)
internal object Logs {
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Network.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Network.kt
new file mode 100644
index 0000000..42142bc
--- /dev/null
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Network.kt
@@ -0,0 +1,26 @@
+package com.devrapid.kotlinknifer
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.Context.CONNECTIVITY_SERVICE
+import android.net.ConnectivityManager
+import com.devrapid.kotlinshaver.cast
+import com.devrapid.kotlinshaver.isNotNull
+
+@SuppressLint("MissingPermission")
+fun Context.activeNetworkInfo() =
+ (getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
+
+fun Context.isWifiConnected() = activeNetworkInfo().run { isNotNull() && ConnectivityManager.TYPE_WIFI == type }
+
+fun Context.isConnected() = activeNetworkInfo().run { isNotNull() && isConnected }
+
+@SuppressLint("MissingPermission")
+fun hasNetwork(context: Context): Boolean {
+ var isConnected = false // Initial Value
+ val connectivityManager = cast(context.getSystemService(CONNECTIVITY_SERVICE))
+ val activeNetwork = connectivityManager.activeNetworkInfo
+ if (activeNetwork != null && activeNetwork.isConnected)
+ isConnected = true
+ return isConnected
+}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Resolution.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Resolution.kt
index db40b91..9cc74b4 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Resolution.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Resolution.kt
@@ -5,10 +5,6 @@ import android.content.res.Resources
import org.jetbrains.anko.px2dip
import org.jetbrains.anko.px2sp
-/**
- * @author jieyi
- * @since 11/24/17
- */
/** Convert dp to px */
fun Float.dp2px(context: Context) = this * context.resources.displayMetrics.density + 0.5f
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Screen.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Screen.kt
index f7e0fb6..e168641 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Screen.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Screen.kt
@@ -3,10 +3,6 @@ package com.devrapid.kotlinknifer
import android.app.Activity
import android.util.DisplayMetrics
-/**
- * @author Jieyi Wu
- * @since 2018/03/05
- */
/**
* Obtain the screen size in pixels.
*
@@ -14,4 +10,4 @@ import android.util.DisplayMetrics
*/
fun Activity.displayPixels() = DisplayMetrics().also {
windowManager.defaultDisplay.getMetrics(it)
-}.run { widthPixels to heightPixels }
\ No newline at end of file
+}.run { widthPixels to heightPixels }
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Spannable.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Spannable.kt
new file mode 100644
index 0000000..29604a2
--- /dev/null
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Spannable.kt
@@ -0,0 +1,27 @@
+package com.devrapid.kotlinknifer
+
+import android.text.Html
+import android.text.method.LinkMovementMethod
+import android.text.style.ClickableSpan
+import android.view.View
+import android.widget.TextView
+import androidx.core.text.HtmlCompat
+import androidx.core.text.parseAsHtml
+
+inline fun TextView.withMovement() = apply {
+ movementMethod = LinkMovementMethod.getInstance()
+}
+
+inline fun TextView.parseAsHtml(
+ flags: Int = HtmlCompat.FROM_HTML_MODE_LEGACY,
+ imageGetter: Html.ImageGetter? = null,
+ tagHandler: Html.TagHandler? = null
+) = apply {
+ text = text.toString().parseAsHtml(flags, imageGetter, tagHandler)
+}
+
+fun clickableSpan(block: (widget: View) -> Unit) = object : ClickableSpan() {
+ override fun onClick(widget: View) {
+ block(widget)
+ }
+}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Toast.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Toast.kt
new file mode 100644
index 0000000..e9f04bc
--- /dev/null
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/Toast.kt
@@ -0,0 +1,16 @@
+package com.devrapid.kotlinknifer
+
+import android.content.Context
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.widget.TextView
+import android.widget.Toast
+
+fun Context.buildCustomToast(customLayoutId: Int, tvId: Int, msg: String, durationTime: Int = Toast.LENGTH_SHORT) =
+ Toast(this).apply {
+ setGravity(Gravity.BOTTOM, 0, 16.dp2px(this@buildCustomToast).toInt())
+ duration = durationTime
+ view = LayoutInflater.from(view.context).inflate(customLayoutId, null).apply {
+ findViewById(tvId).apply { text = msg }
+ }
+ }
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/View.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/View.kt
index 7f80c26..c3c2465 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/View.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/View.kt
@@ -18,10 +18,6 @@ import androidx.annotation.ColorRes
import androidx.appcompat.app.AlertDialog
import com.example.kotlinknifer.R
-/**
- * @author jieyi
- * @since 4/12/17
- */
inline fun View.resizeView(width: Int? = null, height: Int? = null) {
val newLayoutParams = layoutParams?.apply {
height?.let { this.height = it }
@@ -100,10 +96,10 @@ inline fun Activity.statusBarHeight() = Rect()
.top
fun Activity.changeStatusBarColorRes(@ColorRes colorRes: Int) =
- setStatusBarColorBy { statusBarColor = getResColor(colorRes) }
+ setStatusBarColorBy { statusBarColor = getColorBy(colorRes) }
fun Activity.changeStatusBarColor(@ColorInt color: Int, ratio: Float = 1f) =
- setStatusBarColorBy { statusBarColor = getColorWithAlpha(color, ratio) }
+ setStatusBarColorBy { statusBarColor = ofAlpha(color, ratio) }
internal inline fun Activity.setStatusBarColorBy(block: Window.() -> Unit) {
if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT)
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/ViewStub.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/ViewStub.kt
new file mode 100644
index 0000000..827285e
--- /dev/null
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/ViewStub.kt
@@ -0,0 +1,28 @@
+package com.devrapid.kotlinknifer
+
+import android.app.Activity
+import android.view.View
+import androidx.annotation.IdRes
+import androidx.fragment.app.Fragment
+
+fun Activity.obtainViewStub(@IdRes stub: Int, @IdRes realView: Int) =
+ (findViewById(stub) as? View) ?: findViewById(realView)
+
+fun Fragment.obtainViewStub(@IdRes stub: Int, @IdRes realView: Int) =
+ (requireNotNull(view).findViewById(stub) as? View) ?: requireNotNull(view).findViewById(realView)
+
+fun Activity.showViewStub(@IdRes stub: Int, @IdRes realView: Int, options: (View.() -> Unit)? = null) {
+ obtainViewStub(stub, realView).apply {
+ visible()
+ bringToFront()
+ options?.let(this::apply)
+ }
+}
+
+fun Fragment.showViewStub(@IdRes stub: Int, @IdRes realView: Int, options: (View.() -> Unit)? = null) {
+ obtainViewStub(stub, realView).apply {
+ visible()
+ bringToFront()
+ options?.let(this::apply)
+ }
+}
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/recyclerview/Extensions.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/recyclerview/Extensions.kt
new file mode 100644
index 0000000..162dfc6
--- /dev/null
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/recyclerview/Extensions.kt
@@ -0,0 +1,13 @@
+package com.devrapid.kotlinknifer.recyclerview
+
+import android.content.Context
+import android.util.DisplayMetrics
+import androidx.recyclerview.widget.LinearSmoothScroller
+import androidx.recyclerview.widget.RecyclerView
+
+class SlowlySmoothScroller(context: Context) : LinearSmoothScroller(context) {
+ override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics) = .25f
+}
+
+fun RecyclerView.LayoutManager.smoothScrollTo(smoothScroller: LinearSmoothScroller, position: Int) =
+ startSmoothScroll(smoothScroller.apply { targetPosition = position })
diff --git a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/recyclerview/WrapContentLinearLayoutManager.kt b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/recyclerview/WrapContentLinearLayoutManager.kt
index b6462c5..26fb022 100644
--- a/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/recyclerview/WrapContentLinearLayoutManager.kt
+++ b/kotlinknifer/src/main/java/com/devrapid/kotlinknifer/recyclerview/WrapContentLinearLayoutManager.kt
@@ -7,12 +7,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.devrapid.kotlinknifer.loge
import com.devrapid.kotlinknifer.logw
-/**
- * Wrapper the linear layout manager for catching the exceptions and don't make app crash.
- *
- * @author jieyi
- * @since 2018/01/09
- */
class WrapContentLinearLayoutManager : LinearLayoutManager {
constructor(context: Context) : super(context)
constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(context, orientation, reverseLayout)
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/ArrayList.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/ArrayList.kt
index 9d8fbf4..5e0fa24 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/ArrayList.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/ArrayList.kt
@@ -1,14 +1,10 @@
package com.devrapid.kotlinshaver
-/**
- * @author jieyi
- * @since 11/8/17
- */
-fun ArrayList.removeRange(from: Int, to: Int): Boolean =
- if (!(from in 0 until size && to in 0 until size && from > to)) {
+fun ArrayList.removeRange(range: IntRange) =
+ if (!(range.start in 0 until size && range.last in 0 until size && range.start > range.last)) {
false
}
else {
- subList(from, to).clear()
+ subList(range.start, range.last).clear()
true
}
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Casting.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Casting.kt
index 9df1da3..2a29207 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Casting.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Casting.kt
@@ -1,6 +1,7 @@
package com.devrapid.kotlinshaver
inline fun castOrNull(from: Any?) = from as? T
+
inline fun cast(from: Any?): T {
if (null == from) throw NullPointerException("Null object can't cast.")
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Coroutine.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Coroutine.kt
index 83af68c..7c880a9 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Coroutine.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Coroutine.kt
@@ -1,5 +1,3 @@
-@file:Suppress("NOTHING_TO_INLINE")
-
package com.devrapid.kotlinshaver
import kotlinx.coroutines.CoroutineScope
@@ -35,8 +33,8 @@ inline fun gAsync(
noinline block: suspend CoroutineScope.() -> T
) = GlobalScope.async(context, start, block)
-inline fun aUI(noinline block: suspend CoroutineScope.() -> T) = CoroutineScope(Main).async(block = block)
+inline fun uiAsync(noinline block: suspend CoroutineScope.() -> T) = CoroutineScope(Main).async(block = block)
-inline fun aBKG(noinline block: suspend CoroutineScope.() -> T) = CoroutineScope(Default).async(block = block)
+inline fun bkgAsync(noinline block: suspend CoroutineScope.() -> T) = CoroutineScope(Default).async(block = block)
-inline fun aIO(noinline block: suspend CoroutineScope.() -> T) = CoroutineScope(IO).async(block = block)
+inline fun ioAsync(noinline block: suspend CoroutineScope.() -> T) = CoroutineScope(IO).async(block = block)
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Field.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Field.kt
index 32ca079..855d400 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Field.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Field.kt
@@ -1,5 +1,3 @@
-@file:Suppress("NOTHING_TO_INLINE")
-
package com.devrapid.kotlinshaver
import java.lang.reflect.Field
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Instance.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Instance.kt
index 6b61642..6328eb8 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Instance.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Instance.kt
@@ -2,10 +2,5 @@
package com.devrapid.kotlinshaver
-/**
- * @author jieyi
- * @since 2018/01/19
- */
/** This way might cost a little overhead. */
-inline fun List<*>.toInstance() =
- filterIsInstance().takeIf { it.size == this.size }
+inline fun List<*>.toInstance() = filterIsInstance().takeIf { it.size == this.size }
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Int.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Int.kt
index 90e3b75..9a58e9a 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Int.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Int.kt
@@ -1,5 +1,3 @@
-@file:Suppress("NOTHING_TO_INLINE")
-
package com.devrapid.kotlinshaver
inline fun Int.toBool() = 0 < this
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Kits.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Kits.kt
index 5bdd885..89f2fbb 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Kits.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Kits.kt
@@ -5,11 +5,6 @@ package com.devrapid.kotlinshaver
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
-/**
- *
- * @author jieyi
- * @since 7/28/17
- */
inline infix fun (() -> Unit).iff(condition: Any?): Any? {
return when (condition) {
is Boolean -> if (condition) this() else null
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/String.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/String.kt
index 17476af..389f004 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/String.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/String.kt
@@ -1,15 +1,9 @@
-@file:Suppress("NOTHING_TO_INLINE")
-
package com.devrapid.kotlinshaver
import java.text.DecimalFormat
import java.text.NumberFormat
import java.util.Locale
-/**
- * @author jieyi
- * @since 11/8/17
- */
inline fun String.formatToMoneyKarma() = DecimalFormat("###,###").format(java.lang.Double.parseDouble(this))
inline fun Long.toMoneyFormat(locale: Locale?) =
@@ -23,3 +17,5 @@ inline fun Long.toMoneyFormatWithCurrency(locale: Locale?) =
inline fun Double.toMoneyFormatWithCurrency(locale: Locale?) =
(locale?.let(NumberFormat::getCurrencyInstance) ?: NumberFormat.getCurrencyInstance()).format(this)
+
+fun String.trimMarginAndNewLine() = trimMargin().replace("\n", "")
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Thread.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Thread.kt
index 94f0487..164e185 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Thread.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Thread.kt
@@ -1,9 +1,3 @@
-@file:Suppress("NOTHING_TO_INLINE")
-
package com.devrapid.kotlinshaver
-/**
- * @author jieyi
- * @since 11/8/17
- */
-inline fun threadName(): String = Thread.currentThread().name
\ No newline at end of file
+inline fun threadName() = Thread.currentThread().name
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Time.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Time.kt
index 5489a46..728230e 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Time.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Time.kt
@@ -1,15 +1,22 @@
-@file:Suppress("NOTHING_TO_INLINE")
-
package com.devrapid.kotlinshaver
-/**
- * Time extension tool.
- *
- * @author jieyi
- * @since 9/8/17
- */
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+
+const val DATE_YYYY_MM_DD = "yyyyMMdd"
+const val DATE_YYYY_MM_DD_WITH_SLASH = "yyyy/MM/dd"
+const val DATE_YYYY_MM_DD_WITH_DASH = "yyyy-MM-dd"
+const val DATE_YYYY_MM_DD_WITH_DOT = "yyyy.MM.dd"
+
inline fun Int.format(digits: Int) = String.format("%0${digits}d", this)
-inline fun Int.toTimeString(): String = "${(this / 60).format(2)}:${(this % 60).format(2)}"
+inline fun Int.toTimeString() = "${(this / 60).format(2)}:${(this % 60).format(2)}"
+
+inline fun String.toDate(pattern: String = DATE_YYYY_MM_DD, locale: Locale = Locale.US) =
+ SimpleDateFormat(pattern, locale).parse(this)
+
+inline fun Date.asString(pattern: String = DATE_YYYY_MM_DD_WITH_SLASH, locale: Locale = Locale.US) =
+ SimpleDateFormat(pattern, locale).format(this)
val currentTime get() = System.currentTimeMillis()
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/TypeAliases.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/TypeAliases.kt
new file mode 100644
index 0000000..934c6c1
--- /dev/null
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/TypeAliases.kt
@@ -0,0 +1,8 @@
+package com.devrapid.kotlinshaver
+
+typealias UniqueId = Long
+
+// Generic with Type Parameters
+typealias LookUp = HashMap
+
+typealias Token = String
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Completable.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Completable.kt
similarity index 89%
rename from kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Completable.kt
rename to kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Completable.kt
index c57e546..1a94518 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Completable.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Completable.kt
@@ -1,13 +1,9 @@
-package com.devrapid.kotlinshaver
+package com.devrapid.kotlinshaver.rxjava2
import io.reactivex.CompletableObserver
import io.reactivex.disposables.Disposable
-/**
- * @author Jieyi Wu
- * @since 2018/03/25
- */
-fun completableObserver(): CompletablePlugin = CompletablePlugin()
+fun completableObserver() = CompletablePlugin()
fun completableObserver(
onError: (Throwable) -> Unit = {},
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Observable.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Observable.kt
similarity index 95%
rename from kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Observable.kt
rename to kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Observable.kt
index b3bea7b..bb16926 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Observable.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Observable.kt
@@ -1,6 +1,6 @@
@file:Suppress("NOTHING_TO_INLINE")
-package com.devrapid.kotlinshaver
+package com.devrapid.kotlinshaver.rxjava2
import io.reactivex.BackpressureStrategy
import io.reactivex.Completable
@@ -20,11 +20,6 @@ import io.reactivex.internal.operators.observable.ObservableCreate
import io.reactivex.internal.operators.single.SingleCreate
import io.reactivex.subjects.PublishSubject
-/**
- *
- * @author jieyi
- * @since 9/8/17
- */
inline fun observable(crossinline body: (ObservableEmitter) -> Unit): Observable =
ObservableCreate { body(it) }
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Observer.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Observer.kt
similarity index 90%
rename from kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Observer.kt
rename to kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Observer.kt
index c59b832..17ed029 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Observer.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Observer.kt
@@ -1,15 +1,9 @@
-package com.devrapid.kotlinshaver
+package com.devrapid.kotlinshaver.rxjava2
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
-/**
- * RxJava2 extension tool.
- *
- * @author jieyi
- * @since 9/8/17
- */
-fun observer(): ObserverPlugin = ObserverPlugin()
+fun observer() = ObserverPlugin()
fun observer(
onError: (Throwable) -> Unit = {},
diff --git a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Single.kt b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Single.kt
similarity index 90%
rename from kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Single.kt
rename to kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Single.kt
index 1ff4073..d3a02c6 100644
--- a/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/Single.kt
+++ b/kotlinshaver/src/main/java/com/devrapid/kotlinshaver/rxjava2/Single.kt
@@ -1,13 +1,9 @@
-package com.devrapid.kotlinshaver
+package com.devrapid.kotlinshaver.rxjava2
import io.reactivex.SingleObserver
import io.reactivex.disposables.Disposable
-/**
- * @author Jieyi Wu
- * @since 2018/03/25
- */
-fun singleObserver(): SinglePlugin = SinglePlugin()
+fun singleObserver() = SinglePlugin()
fun singleObserver(
onError: (Throwable) -> Unit = {},