Following on from the previous article, which introduced the Kotlin features used in the project, this article continues to sort out the features used in the current project.
1. Apply and run functions
The with, apply, and run functions are all functions in the Kotlin standard library. With was introduced in the first article.
1.1 the apply function
The apply function refers to an object that can be referred to by this within a function block and returns the value of the object itself. In chained calls, consider using it without breaking the chain.
/** * Calls the specified function [block] with `this` value as its receiver and returns `this` value. */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T. () -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
Copy the code
Here’s an example:
/** * Created by tony on 2018/4/26. */
object Test {
@JvmStatic
fun main(args: Array<String>) {
val result ="Hello".apply {
println(this+" World")
this+" World"
}
println(result)
}
}
Copy the code
Execution result:
Hello World
Hello
Copy the code
The first string is printed in the closure, and the second string is the result of result, which is still “Hello.”
1.2 run function
The run function is similar to the apply function, but the run function returns the value of the last row.
/** * Calls the specified function [block] with `this` value as its receiver and returns its result. */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T. () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
Copy the code
Here’s an example:
/** * Created by tony on 2018/4/26. */
object Test {
@JvmStatic
fun main(args: Array<String>) {
val result ="Hello".run {
println(this+" World")
this + " World"
}
println(result)
}
}
Copy the code
Execution result:
Hello World
Hello World
Copy the code
The first string is printed in the closure, and the second string is the result of result, which returns the value of the last line in the closure, so “Hello World” is also printed.
1.3 Use in projects
In the feedback page of the App, you need to input the email, theme and content to complete the submission of the feedback button.
It was originally written like this:
if(viewModel.email.value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_email_address)).show()return@onClickRight
}
if(! Util.checkEmail(viewModel.email.value!!) ) { toast(resources.getString(R.string.the_email_format_you_have_filled_is_incorrect)).show()return@onClickRight
}
if(viewModel.subject.value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_feedback_subject)).show()return@onClickRight
}
if(viewModel.content.value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_details)).show()return@onClickRight
}
Copy the code
Change to use only the apply function
viewModel.apply {
if(email.value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_email_address)).show()return@onClickRight
}
if(! Util.checkEmail(email.value!!) ) { toast(resources.getString(R.string.the_email_format_you_have_filled_is_incorrect)).show()return@onClickRight
}
if(subject.value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_feedback_subject)).show()return@onClickRight
}
if(content.value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_details)).show()return@onClickRight}}Copy the code
It’s not cool enough. You can use it together with the run and apply functions
viewModel.email.run {
if(value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_email_address)).show()return@onClickRight
}
if(! Util.checkEmail(value!!) ) { toast(resources.getString(R.string.the_email_format_you_have_filled_is_incorrect)).show()return@onClickRight
}
viewModel
}.subject.run {
if(value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_feedback_subject)).show()return@onClickRight
}
viewModel
}.content.apply {
if(value!! .isEmpty()) { toast(resources.getString(R.string.you_have_not_completed_the_details)).show()return@onClickRight}}Copy the code
2. The data class
Kotlin’s data class is somewhat similar to Scala’s case class.
The following Java Bean code
/** * Created by tony on 2018/4/27. */
public class User {
public String userName;
public String password;
}
Copy the code
Is equivalent to
data class User (var userName: String? = null.var password: String? = null)
Copy the code
You can see how using data Classes can simplify Java Bean classes. Our App adopts the MVVM architecture, so all corresponding Model classes use data class.
No need to use findViewById or Butterknife
You can do this using the Kotlin Android Extensions plugin, which is part of the Kotlin plugin. You do not need to install a separate plugin.
We add the plugin to the build.gradle of each module and you can use it.
apply plugin: 'kotlin-android-extensions'
Copy the code
The id in the layout file can be used directly in the code. First of all, according to the import kotlinx. Android. Synthetic. Main. Layout file name * mode import.
For example, MainActivity, whose layout file is activity_main.xml, is imported as follows
import kotlinx.android.synthetic.main.activity_main.*
Copy the code
Then the id of the control in activity_main.xml can be used directly in the MainActivity without using findViewById or Butterknife. Isn’t it very convenient?
4. Click the buried point processing of the event
App burial point, use their own home product – magic window SDK to do the event of the burial point.
If you are developing your App in Java, you can use AOP to implement embedding. Since our App is written by Kotlin, Kotlin can simplify the click of the event into the following form
view.setOnClickListener {
....
}
Copy the code
This is a simplified lambda expression, so I’m going to do it the old-fashioned way.
Common ways to use Kotlin:
View.setonclicklistener {trackAgent.currentevent ().customEvent(eventName).... }Copy the code
or
View.setonclicklistener {trackAgent.currentevent ().customEvent(eventName, trackMap).... }Copy the code
Later, I wrote a View extension function click, which was later optimized by a colleague. Check out the short book article for an elegant implementation of “Prevent Repeated clicks” using extension functions.
At present, have put the extension function in my Kolin tool library at https://github.com/fengzhizi715/SAF-Kotlin-Utils
At this point, the buried point code looks like this
View.click {trackagent.currentevent ().customEvent(eventName).... }Copy the code
or
View.click {trackagent.currentevent ().customEvent(eventName, trackMap).... }Copy the code
To further optimize the processing, add the extension function clickWithTrack to View specifically for buried point click events.
package cn.magicwindow.core.ext
import android.view.View
import cn.magicwindow.TrackAgent
import com.safframework.ext.clickWithTrigger
/ * * * *@FileName:
* cn.magicwindow.core.ext.ViewExt.java
* @author: Tony Shen
* @date: * he was 2018-04-24@versionV1.0 < Describes the current version functions > */
fun <T : View> T.clickWithTrack(eventName: String, time: Long = 600, block: (T) -> Unit) = this.clickWithTrigger(time) {
TrackAgent.currentEvent().customEvent(eventName)
block(it as T)
}
fun <T : View> T.clickWithTrack(eventName: String, trackMap: HashMap<String, String>, time: Long = 600, block: (T) -> Unit) = this.clickWithTrigger(time) {
TrackAgent.currentEvent().customEvent(eventName, trackMap)
block(it as T)
}
Copy the code
At this point, the burial point can be used as follows:
view.clickWithTrack(key) {
....
}
Copy the code
or
view.clickWithTrack(key,trackMap) {
....
}
Copy the code
conclusion
Kotlin has a lot of syntactic sugar that you can use to simplify your code and implement functionality more gracefully.
Related articles in this series:
Use Kotlin to efficiently develop Android App(5) the final part
Developing Android Apps efficiently with Kotlin (part 4)
Developing Android Apps efficiently with Kotlin (part 3)
Developing Android Apps efficiently with Kotlin (1)
Java and Android technology stack: weekly updates push original technical articles, welcome to scan the public qr code below and follow, look forward to growing with you and progress together.