Get into the habit of writing together! This is the 8th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .
This article will implement the elegant read and write encapsulation of Activity's Intent and Fragment's Argument from the perspective of attribute delegation
There are two ways to implement property delegation. Here, it is directly implemented by implementing the interface:
var
The decorated property implements property delegation and needs to implement theReadWriteProperty
interfaceval
The decorated property implements property delegation and needs to implement theReadOnlyProperty
interface
Here, since we only need to read the value, we can directly implement the ReadOnlyProperty
interface. The following is directly on the Activity's Intent
delegate reading code:
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
}
}
复制代码
It should be noted that the key used to read the Activity here Intent
defaults to the attribute name: property.name
, which means that Intent
the key should also use the attribute name when storing the value.
Intent
If you key
don't want to use the property name if you need to read and write, you have to modify the property delegate class IntentWrapper
slightly, and the constructor supports passing in key
key values from outside.
In the above property delegation class , the sum type IntentWrapper
is simply processed , and other types and other types need to be added by yourself.String
Int
Boolean
Float
Take a look at using:
private val data by IntentWrapper(56)
//读
printlin(data)
复制代码
The above is still a bit inelegant to use. You have to manually create IntentWrapper
and pass in the default value every time. We can encapsulate several common types of methods, which are more convenient to implement:
fun intIntent(default: Int = 0) = IntentWrapper(default)
fun stringIntent(default: String = "") = IntentWrapper(default)
复制代码
intIntent()
The method gives a default value of 0, a default value that can be optionally passed in from the outside, and other types are handled in the same way.
Then it can be used like this:
private val data by intIntent()
复制代码
The above mainly shows the reading of Activity, Intent
and the processing of Fragment is Argument
similar:
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
}
}
复制代码
It is also similar to Activity, so I won't show it here. Of course, several common types of methods can be defined here ArgumentWrapper
, just refer to the above Activity processing.
A follow-up article will be prepared to consider the reading 类委托
under encapsulation from the perspective .Activity的Intent、Fragment的Argument