优雅读取Activity的Intent、Fragment的Argument
属性委托实现方式有两种,这里直接通过实现接口的形式实现:
var
修饰的属性实现属性委托需要实现ReadWriteProperty
接口val
修饰的属性实现属性委托需要实现ReadOnlyProperty
接口
这里由于我们只需要读取值,所以直接实现ReadOnlyProperty
接口即可。下面直接上Activity的Intent
委托读取代码 :
class IntentWrapper<T>(private val default: T) : ReadOnlyProperty<AppCompatActivity, T?> {
override fun getValue(thisRef: AppCompatActivity, property: KProperty<*>): T? {
return when(default) {
is Int -> thisRef.intent.getIntExtra(property.name, default)
is String -> thisRef.intent.getStringExtra(property.name)
else -> throw Exception()
} as? T
}
}
需要注意,在这里读取Activity的Intent
使用的key默认为属性名称:property.name
,这也就意味着通过Intent
存储值的时候key也要使用属性名称。
如果需要读写Intent
的话key
不想要使用属性名称,那就得对这个属性委托类IntentWrapper
稍微改造下,构造方法中支持从外部传入key
键值
上面的属性委托类IntentWrapper
中,只是简单处理了String
和Int
类型,其他的类型Boolean
、Float
等类型需要请自行添加。
看下使用:
private val data by IntentWrapper(56)
//读
printlin(data)
上面使用起来还是有一丢丢不优雅,每次都得手动创建IntentWrapper
并传入默认值,我们可以封装几个常用类型的方法,实现起来更加方便:
fun intIntent(default: Int = 0) = IntentWrapper(default)
fun stringIntent(default: String = "") = IntentWrapper(default)
intIntent()
方法给了一个默认值为0,外部可以选择性传入的默认值,其他的类型也是一样处理。
然后就可以这样使用:
private val data by intIntent()
上面主要展示的是读取Activity的Intent
,Fragment的Argument
处理类似:
class ArgumentWrapper<T>(private val default: T) : ReadOnlyProperty<Fragment, T?> {
override fun getValue(thisRef: Fragment, property: KProperty<*>): T? {
return when(default) {
is Int -> thisRef.arguments?.getInt(property.name, default)
is String -> thisRef.arguments?.getString(property.name)
else -> throw Exception()
} as? T
}
}
使用起来也和Activity类似,这里就不做展示了。当然了,这里可以定义几个常用类型的方法创建ArgumentWrapper
,参考上面Activity的处理即可。
后续准备出一篇文章,从类委托
的角度考虑封装下Activity的Intent、Fragment的Argument
的读取。
作者:长安皈故里
链接:https://juejin.cn/post/7084418325878407181
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。