kotlin的属性代理


今天学习了一下kotlin的属性代理,觉的挺有趣的,借助属性代理我们可以实现一些有意思的功能。

基本语法

class Student{
    var name: String by Delegate()
}

class Delegate{
    operator fun <T> getValue(thisRef: Any?, property: KProperty<*>): T{
        ...
    }
    operator fun <T> setValue(thisRef: Any?, property: KProperty<*>, value: T){
        ...
    }
}

案例一:利用属性代理实现json字段的获取

class JsonDelegate(jsonStr: String) {

    val jsonObject: JSONObject = JSONObject(jsonStr)

    public fun <T> delegate(defaultValue: T, key: String = ""): Delegate<T> {
        return Delegate(jsonObject, key, defaultValue)
    }

    public override fun toString(): String {
        return jsonObject.toString()
    }

    class Delegate<T>(
        var jsonObject: JSONObject,
        var key: String,
        val defaultValue: T
    ) {

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
            val key = getKey(property)
            jsonObject.put(key, value)
        }

        protected fun getKey(property: KProperty<*>): String {
            if (!key.isEmpty()) {
                return key
            }
            return property.name
        }

        operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
            val key = getKey(property)
            if (jsonObject.has(key)) {
                val value = jsonObject.get(getKey(property))
                return value as T
            } else {
                return defaultValue
            }
        }
    }

}

使用方式:

val jsonDelegate = JsonDelegate(jsonStr)
val value1 by jsonDelegate.delegate(-1,"test")//第一个参数是默认值,第二个参数是key
val value2 by jsonDelegate.delegate(-2)//若没有第二个参数,则key为变量名

这样我们在从一段json当中取值时,就不用每次都判断json是否存在这个key,若不存在这个key,则直接返回传入的默认值。

案例二:利用属性代理实现SharedPreferences取值和存储

class SPDelegate(tag: String, context: Context) {
    val sp:SharedPreferences by lazy {
        context.applicationContext.getSharedPreferences(tag,Context.MODE_PRIVATE)
    }

    public fun <T> delegate(defaultValue: T, key: String = ""): Delegate<T> {
        return Delegate(sp,key,defaultValue)
    }

    class Delegate<T>(
        val sp:SharedPreferences,
        var key: String,
        val defaultValue: T
    ) {

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
            val key = getKey(property)
            with(sp.edit()) {
                when (value) {
                    is String -> putString(key, value)
                    is Int -> putInt(key, value)
                    is Float -> putFloat(key, value)
                    is Long -> putLong(key, value)
                    is Boolean -> putBoolean(key, value)
                    else -> throw IllegalArgumentException("Unsupported type.")
                }
            }.apply()
        }

        protected fun getKey(property: KProperty<*>): String {
            if (!key.isEmpty()) {
                return key
            }
            return property.name
        }

        operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
            val result =  when (defaultValue) {
                is String -> sp.getString(getKey(property), defaultValue as String) ?: defaultValue
                is Int -> sp.getInt(getKey(property), defaultValue as Int)
                is Float -> sp.getFloat(getKey(property), defaultValue as Float)
                is Long -> sp.getLong(getKey(property), defaultValue as Long)
                is Boolean -> sp.getBoolean(getKey(property), defaultValue as Boolean)
                else -> throw IllegalArgumentException("Unsupported type.")
            }
            return result as T
        }
    }
}

使用方式:

val delegate = SPDelegate("MainActivity",this)
var test by delegate.delegate(1,"tttt")//第一个参数表示默认值,第二个参数表示key
var test1 by delegate.delegate("test")//若只有一个参数,则key为变量名称

这样我们就可以避免写出大段的SharedPreferences代码,我们的代码也非常的简洁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值