kotlin 通用工具,持续更新,个人笔记

本文介绍了几个Kotlin实用工具类,包括条件判断、惰性初始化、协程执行链,以及一个泛型Dialog基类。这些工具类提供了便捷的数据操作和UI交互功能,例如延迟执行、日志打印和自定义Dialog的管理。同时,展示了如何创建元组以及一个通用Dialog基类的详细实现,该基类考虑了生命周期管理和自动关闭。
摘要由CSDN通过智能技术生成

 通用工具类:

fun<T> T.ifNotIs(compareValue:T):T?{
    return if (this != compareValue) {
        this
    } else {
        null
    }
}
fun<T> T?.then(block:(T)->Unit) {
    if (this != null) {
        try {
            block(this)
        } catch (e: Exception) {
            LogUtils.e("LogicExt--then ",e)
        }
    }
}


class Do<Item1,Item2>(block: Do<Item1,Item2>.() -> Unit) {
    init {
        block()
    }
    fun<You:List<Item1>,Me:List<Item2>> You.loveTogetherWith(me:Me, block:(Item1, Item2)->Unit):Boolean{
        if (size != me.size) {
            return false
        }
        forEachIndexed { index, yourBaby ->
            block(yourBaby, me[index])
        }
        return true
    }
}

//使用方式
//private val mDialogTimePicker by lazyMeNeedKFC{LBDatePickerDialog(mContext)}

fun<T> Any.lazyMeNeedKFC(initializer:()->T):Lazy<T>{
    return ValLazyLoading(initializer)
}

private class ValLazyLoading<T>(private val initializer:()->T):Lazy<T>{
    private var cached: T? = null
    override val value: T
        get() {
            return cached ?: initializer().also {
                cached = it
            }
        }
    override fun isInitialized() = cached != null
}

//方法调用链,用于提供顺序执行内容的能力
    suspend fun CoroutineScope.exeChain(delay:Long,dp:CoroutineDispatcher=Dispatchers.Main,block:suspend ()->Unit):CoroutineScope {
        if (delay <= 0) {
            withContext(dp){
                block()
            }
            return this
        } else {
            delay(delay)
            withContext(dp){
                block()
            }
            return this
        }
    }
 //exeChain使用方式:
  CoroutineScope(Dispatchers.Main).launch {
            for (i in 0 until 1000) {
                exeChain(0, dp = Dispatchers.IO) {
                    Log.d(TAG, "onCreate: 1 time=${getTime()} ${Thread.currentThread().name}")
                }.exeChain(0, dp = Dispatchers.Default) {
                    Log.d(TAG, "onCreate: 2 time=${getTime()} ${Thread.currentThread().name}")
                }.exeChain(0, dp = Dispatchers.IO) {
                    Log.d(TAG, "onCreate: 3 time=${getTime()} ${Thread.currentThread().name}")
                }.exeChain(0, dp = Dispatchers.Main){
                    Log.d(TAG, "onCreate: 4 time=${getTime()} ${Thread.currentThread().name}")
                }
            }
        }

//打印日志
//D/MainActivity: onCreate: 1 time=17:00:02 DefaultDispatcher-worker-1 tDispatcher-worker-1 
//D/MainActivity: onCreate: 2 time=17:00:03 DefaultDispatcher-worker-1 tDispatcher-worker-1 
//D/MainActivity: onCreate: 3 time=17:00:03 DefaultDispatcher-worker-1 tDispatcher-worker-1 
//D/MainActivity: onCreate: 4 time=17:00:03 main                                            
//D/MainActivity: onCreate: 1 time=17:00:03 DefaultDispatcher-worker-4 tDispatcher-worker-4 
//D/MainActivity: onCreate: 2 time=17:00:03 DefaultDispatcher-worker-4 tDispatcher-worker-4 
//D/MainActivity: onCreate: 3 time=17:00:03 DefaultDispatcher-worker-3 tDispatcher-worker-3 
//D/MainActivity: onCreate: 4 time=17:00:03 main                                            
//D/MainActivity: onCreate: 1 time=17:00:03 DefaultDispatcher-worker-5 tDispatcher-worker-5 
//D/MainActivity: onCreate: 2 time=17:00:03 DefaultDispatcher-worker-5 tDispatcher-worker-5 
//D/MainActivity: onCreate: 3 time=17:00:03 DefaultDispatcher-worker-3 tDispatcher-worker-3 
//D/MainActivity: onCreate: 4 time=17:00:03 main                                            
//D/MainActivity: onCreate: 1 time=17:00:03 DefaultDispatcher-worker-2 tDispatcher-worker-2 
//D/MainActivity: onCreate: 2 time=17:00:03 DefaultDispatcher-worker-2 tDispatcher-worker-2 
//D/MainActivity: onCreate: 3 time=17:00:03 DefaultDispatcher-worker-2 tDispatcher-worker-2 
//D/MainActivity: onCreate: 4 time=17:00:03 main                                            
//D/MainActivity: onCreate: 1 time=17:00:03 DefaultDispatcher-worker-1 tDispatcher-worker-1 
//D/MainActivity: onCreate: 2 time=17:00:03 DefaultDispatcher-worker-1 tDispatcher-worker-1 
//D/MainActivity: onCreate: 3 time=17:00:03 DefaultDispatcher-worker-4 tDispatcher-worker-4 
//D/MainActivity: onCreate: 4 time=17:00:03 main                                            

Kotlin创建Tuple:

data class Tuple1<out A>(val _1: A) : Tuple(1)
data class Tuple2<out A, out B>(val _1: A, val _2: B) : Tuple(2)
data class Tuple3<out A, out B, out C>(val _1: A, val _2: B, val _3: C) : Tuple(3)
data class Tuple4<out A, out B, out C, out D>(val _1: A, val _2: B, val _3: C, val _4: D) : Tuple(4)
data class Tuple5<out A, out B, out C, out D, out E>(val _1: A, val _2: B, val _3: C, val _4: D, val _5: E) : Tuple(5)

open class Tuple(val size: Int) {
    companion object {
        operator fun <A> invoke(_1: A): Tuple1<A> = Tuple1(_1)
        operator fun <A, B> invoke(_1: A, _2: B): Tuple2<A, B> = Tuple2(_1, _2)
        operator fun <A, B, C> invoke(_1: A, _2: B, _3: C): Tuple3<A, B, C> = Tuple3(_1, _2, _3)
        operator fun <A, B, C, D> invoke(_1: A, _2: B, _3: C, _4: D): Tuple4<A, B, C, D> = Tuple4(_1, _2, _3, _4)
        operator fun <A, B, C, D, E> invoke(_1: A, _2: B, _3: C, _4: D, _5: E): Tuple5<A, B, C, D, E> = Tuple5(_1, _2, _3, _4, _5)
    }
}

 通用Dialog基类:

abstract class DialogSafeBase(var time:Long=3_000L): LifecycleObserver {
    private var mTimer: CountDownTimer = object : CountDownTimer(time, 1000) {
        override fun onTick(millisUntilFinished: Long) {
        }

        override fun onFinish() {
            LogUtils.d("DialogSafeBase--onFinish this=$this ")
            mDialogInternal?.dismiss()
        }
    }

    private class EmptyView(context: Context) : View(context)


    protected abstract fun theme(): Int
    protected abstract fun layoutID(): Int
    protected abstract fun useDataBinding(): Boolean
    protected abstract fun useViewBinding(): Boolean
    protected abstract fun initView(root: View)
    protected abstract fun setData()
    protected abstract fun initConfig(window: Window?)
    protected abstract fun onDismiss()
    protected abstract fun onShowListener()

    protected open fun onCreateDataBindingView(
        inflater: LayoutInflater
    ): View {
        return EmptyView(inflater.context)
    }

    protected open fun onCreateViewBinding(inflater: LayoutInflater): View {
        return EmptyView(inflater.context)
    }

    private inner class DialogInternal(val mContext: Context) :
        Dialog(mContext, theme()) {


        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val inflater = LayoutInflater.from(mContext)
            val view = if (useDataBinding()) {
                onCreateDataBindingView(inflater)
            } else {
                if (useViewBinding()) {
                    onCreateViewBinding(inflater)
                } else {
                    inflater.inflate(layoutID(), null)
                }
            }
            initView(view)
            setContentView(view)
            initDefaultConfig()
            initConfig(window)
        }

        override fun onStart() {
            setData()
            super.onStart()
        }
        private fun initDefaultConfig() {
            val screenWH = getScreenWH()
            window?.apply {
                setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)
                attributes?.apply {
                    width = (screenWH[0] * 0.5f).toInt()
                    height = (screenWH[0] * 0.5f).toInt()
                    attributes = this
                }
                setBackgroundDrawableResource(R.color.transparent)
            }
        }
    }

    protected lateinit var mContext:Context
    private var mDialogInternal:DialogInternal?=null
    private var mIgnoreLifeStop=false
    /**
     * repeatShow:是否允许重复显示(重复dismiss->show) true:允许  false:不允许
     */
    fun show(context: Context, lifecycle: Lifecycle, isAutoDismiss: Boolean = false, cancelOutside:Boolean=true,repeatShow:Boolean=true,ignoreLifeStop:Boolean=false) {
        mIgnoreLifeStop=ignoreLifeStop
        LogUtils.d("DialogSafeBase--show this=$this")
        mDialogInternal?:apply {
            LogUtils.d("DialogSafeBase--show init dialog")
            mDialogInternal=DialogInternal(context)
        }
        mContext=context
        mDialogInternal?.apply {
            if (isShowing) {
                if (repeatShow) {
                    dismiss()
                } else {
                    return
                }
            }
            setOnShowListener {onShowListener()  }
            setOnDismissListener {
                lifecycle.removeObserver(this@DialogSafeBase)
                mTimer.cancel()
                onDismiss()
            }
            setCanceledOnTouchOutside(cancelOutside)
            show()
        }
        lifecycle.addObserver(this)
        if (isAutoDismiss) {
            mTimer.cancel()
            mTimer.start()
        }
    }

    fun dismiss() {
        LogUtils.d("DialogSafeBase--dismiss this=$this")
        mDialogInternal?.apply {
            if (isShowing) {
                mDialogInternal!!.dismiss()
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onHostLifeStop(owner: LifecycleOwner) {//自动关闭弹框,通用情况下,
        // 宿主stop的时候需要关闭弹框,比如主界面到设置界面,主界面没有destroy,
        // 但是这时候不能显示主界面的弹框,防止遮蔽设置界面视野
        //但是对于娱乐弹框来说,他必须始终显示已确保进入其他app后,能够显示浮动按钮,用于退出
        LogUtils.d("DialogSafeBase--onHostLifeDestroy ON_STOP mIgnoreLifeStop=$mIgnoreLifeStop")
        if (!mIgnoreLifeStop) {
            dismiss()
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onHostLifeDestroy(owner: LifecycleOwner) {//自动关闭弹框,对于destroy来说,无论什么情况都必须关闭弹框
        LogUtils.d("DialogSafeBase--onHostLifeDestroy ON_DESTROY")
        dismiss()
    }

    protected fun getScreenWH(): Array<Int> {
        val wm = mContext.applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val dm = DisplayMetrics()
        wm.defaultDisplay.getRealMetrics(dm)
        return arrayOf(dm.widthPixels, dm.heightPixels)
    }
}
    <style name="DialogWarnning" parent="Theme.AppCompat.Dialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
<!--        <item name="android:windowBackground">@android:color/transparent</item>-->
        <item name="android:windowIsFloating">true</item>
        <item name="android:padding">0dp</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:backgroundDimEnabled">false</item><!--activity不变暗-->
    </style>

其基础编译器(他们将其改为kompiler——开创了一系列以K字打头的用语——甚至连 contributors这类词他们也用改成了kontributors)可以被独立出来并嵌入到 Maven、Ant 或 Gradle 工具链中。这使得在 IDE 中开发的代码能够利用已有的机制来构建,从而尽可能的减少了在新环境中使用所受的干预,哪怕与那些没有安装 Kotlin 插件的开发人员一起合作项目也没有问题。 The IntelliJ Kotlin 插件扩展了 Java 编译器使得 Kotlin 代码能够得以编写、编译和调试。除此之外,关于基本的 Java 集合,已经有编写好的帮助函数,可以更顺畅地衔接将在 Java 8 中出现的集合扩展。 有两篇文章对 Kotlin 与 Java 以及 Kotlin 与 Scala 分别进行了比较,对各自特性和异同进行了对比。即便 Scala 可能还是更为强大些,Kotlin 还是尝试着提供比 Java 更好的函数、模式匹配、空指针预防和泛型。该语言同时也支持特征(traits)和模式匹配。 Kotlin 插件在当前版本的 IntelliJ 和 Eclipse 中均已能使用。 [4] Kotlin,类似 Xtend 一样,旨在提供一种更好的 Java 而非重建整个新平台。这两种语言都向下编译为字节码(虽然 Xtend 是首先转换成相应的 Java 代码,再让 Java 编译器完成繁重的工作),而且两者都引入了函数和扩展函数(在某个有限范围内静态地增加一个新方法到某个已有类型的能力)。Xtend 是基于 Eclipse 的,而 Kotlin 是基于 IntelliJ 的,两者都提供无界面构建。能够首先演变到其他 IDE 的语言有可能成为最后的赢家。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值