Files
assistant-android/app/src/main/java/com/gh/common/util/Extensions.kt
2019-06-18 18:15:46 +08:00

191 lines
5.1 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.gh.common.util
import android.content.ClipboardManager
import android.content.Context
import android.text.Html
import android.text.Spanned
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.*
import androidx.viewpager.widget.ViewPager
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import okhttp3.MediaType
import okhttp3.RequestBody
import java.net.URI
/**
* 创建以 activity 为观察者上下文的 viewModel
*/
inline fun <reified VM : ViewModel> FragmentActivity.viewModelProvider(
provider: ViewModelProvider.Factory? = null
) =
ViewModelProviders.of(this, provider).get(VM::class.java)
/**
* 创建以 activity 为观察者上下文的 viewModel
*/
inline fun <reified VM : ViewModel> Fragment.viewModelProviderFromParent(
provider: ViewModelProvider.Factory? = null
) =
ViewModelProviders.of(requireActivity(), provider).get(VM::class.java)
/**
* 创建以 fragment 为观察者上下文的 viewModel
*/
inline fun <reified VM : ViewModel> Fragment.viewModelProvider(
provider: ViewModelProvider.Factory? = null
) =
ViewModelProviders.of(this, provider).get(VM::class.java)
/**
*
* ViewPager Extensions
*
*/
fun ViewPager.doOnPageSelected(action: (position: Int) -> Unit) = addOnPageChangeListener(onSelected = action)
fun ViewPager.addOnPageChangeListener(onSelected: ((position: Int) -> Unit)? = null) {
val listener = object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
// Do nothing.
}
override fun onPageSelected(position: Int) {
onSelected?.invoke(position)
}
override fun onPageScrollStateChanged(state: Int) {
// Do nothing.
}
}
addOnPageChangeListener(listener)
}
/**
* LiveData Extensions
*/
fun <T> LiveData<T?>.observeNonNull(owner: LifecycleOwner, callback: (T) -> Unit) {
observe(owner, Observer { value ->
if (value != null) {
callback(value)
}
})
}
/**
* Login related extensions
*/
fun Fragment.ifLogin(entrance: String, action: (() -> Unit)? = null) {
requireContext().ifLogin(entrance, action)
}
fun Context.ifLogin(entrance: String, action: (() -> Unit)? = null) {
CheckLoginUtils.checkLogin(this, entrance, action)
}
/**
* Gson related extensions.
*/
inline fun <reified T : Any> String.toObject(): T? {
return try {
GsonUtils.gson.fromJson(this, object : TypeToken<T>() {}.type)
} catch (e: Exception) {
e.printStackTrace()
null
}
}
inline fun <reified T : Any> T.toJson(): String {
return GsonUtils.toJson(this)
}
/**
* 在限定 interval 里只触发一次 action
*/
fun debounceActionWithInterval(id: Int, interval: Long = 300, action: (() -> Unit)? = null) {
if (!ClickUtils.isFastDoubleClick(id, interval)) {
action?.invoke()
}
}
fun View.debounceActionWithInterval(interval: Long = 300, action: (() -> Unit)? = null) {
debounceActionWithInterval(this.id, interval, action)
}
/**
* 告诉需要返回 true or false 的外层这个事件已经被消费(即返回 true
*/
inline fun consume(f: () -> Unit): Boolean {
f()
return true
}
/**
* 简化那些不得不写 try catch 的代码块
*/
inline fun tryWithDefaultCatch(action: (() -> Unit)) {
try {
action.invoke()
} catch (e: Throwable) {
e.printStackTrace()
}
}
/**
* String related
*/
fun String.fromHtml(): Spanned {
return Html.fromHtml(this)
}
// 去掉文章/答案的插入内容
fun String.removeInsertedContent(): String {
val textRegex = "(?s)<div class=\"gh-internal-content content-right\".*?</div>"
return this.replace(textRegex.toRegex(), "")
}
// 完全地清除所有 Html 格式
fun String.clearHtmlFormatCompletely(): String {
return Html.fromHtml(this).toString().replace('\n', 32.toChar())
.replace(160.toChar(), 32.toChar()).replace(65532.toChar(), 32.toChar()).trim { it <= ' ' }
}
// 如果该字符串长度超过固定长度的话,从头开始截取固定长度并返回
fun String.subStringIfPossible(length: Int): String {
return if (this.length > length) {
this.substring(0, length)
} else {
this
}
}
fun String.copyTextAndToast(toastText: String = "复制成功") {
val application = HaloApp.getInstance().application
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cmb.text = this
Utils.toast(application, toastText)
}
fun Map<String, String>.createRequestBody(): RequestBody {
val json = GsonUtils.toJson(this)
return RequestBody.create(MediaType.parse("application/json"), json)
}
// 对在浏览器(WebView)显示的路径进行转码
fun String.decodeURI(): String {
return URI(null, null, this, null).rawPath
}
/**
* 根据手机的分辨率从 dip(像素) 的单位 转成为 px
*/
fun Float.dip2px(): Int {
val scale = HaloApp.getInstance().application.resources.displayMetrics.density
return (this * scale + 0.5f).toInt()
}