注册

优雅读取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中,只是简单处理了StringInt类型,其他的类型BooleanFloat等类型需要请自行添加。


看下使用:


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
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册