Elegantly read Intent of Activity and Argument of Fragment

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:

  • varThe decorated property implements property delegation and needs to implement the ReadWritePropertyinterface
  • valThe decorated property implements property delegation and needs to implement the ReadOnlyPropertyinterface

Here, since we only need to read the value, we can directly implement the ReadOnlyPropertyinterface. The following is directly on the Activity's Intentdelegate 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 Intentdefaults to the attribute name: property.name, which means that Intentthe key should also use the attribute name when storing the value.

IntentIf you keydon't want to use the property name if you need to read and write, you have to modify the property delegate class IntentWrapperslightly, and the constructor supports passing in keykey values ​​from outside.

In the above property delegation class , the sum type IntentWrapperis simply processed , and other types and other types need to be added by yourself.StringIntBooleanFloat

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 IntentWrapperand 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, Intentand the processing of Fragment is Argumentsimilar:

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

Guess you like

Origin juejin.im/post/7084418325878407181