注:编码工具为IntelliJ
目录
案例一:
package step_ten
fun main() {
// 看到花括号,想到lambda,
layout {
// 看到lambda里面的花括号,想到类的成员函数时高阶函数,省略了this.
textview {
println("textview")
}
button {
println("button")
}
}
}
private class Helper
// 可以用扩展函数,也可以定义在类的内部
private inline fun Helper.textview(lambda: () -> Unit) = lambda()
private inline fun Helper.button(lambda: () -> Unit) = lambda()
private inline fun layout(
// 因为要在lambda里面调用类的高阶函数,要用到this,所以要声明成匿名扩展函数
lambda: Helper.() -> Unit
):
Helper {
val helper = Helper()
helper.lambda()
return helper
}
输出:
textview
button
案例二:
package step_ten
fun main() {
// 看到花括号,想到lambda
manifest {
// 看到lambda里调用函数,想到类的函数是普通函数,省略了this.
pkg("com.test")
permission("android.permission.INTERNET")
// 看到lambda里调用lambda,想到类的函数是高阶函数,省略了this.
application {
// 看到lambda里调用lambda,想到类的函数是高阶函数,省略了this.
activity {
intent_filter {
action("android.intent.action.MAIN")
category("android.intent.category.LAUNCHER")
}
}
service {
intent_filter {
}
}
receiver {
intent_filter {
}
}
provider {
intent_filter {
}
}
}
}
}
private class IntentFilter{
fun action(s: String) = println("action is $s")
fun category(s: String) = println("category is $s")
}
private class Component{
inline fun intent_filter(lambda: IntentFilter.() -> Unit): IntentFilter{
val intentFilter = IntentFilter()
intentFilter.lambda()
return intentFilter
}
}
private class Application{
inline fun activity(lambda: Component.() -> Unit): Component{
val component = Component()
component.lambda()
return component
}
inline fun service(lambda: Component.() -> Unit): Component{
val component = Component()
component.lambda()
return component
}
inline fun receiver(lambda: Component.() -> Unit): Component{
val component = Component()
component.lambda()
return component
}
inline fun provider(lambda: Component.() -> Unit): Component{
val component = Component()
component.lambda()
return component
}
}
private class Manifest {
fun pkg(s: String) = println("package is $s")
fun permission(s: String) = println("permission is $s")
inline fun application(lambda: Application.() -> Unit): Application{
val application = Application()
application.lambda()
return application
}
}
private inline fun manifest(
// 因为要在lambda里面调用类的高阶函数,要用到this,所以要声明成匿名扩展函数
lambda: Manifest.() -> Unit
): Manifest {
val manifest = Manifest()
lambda(manifest)
return manifest
}
输出:
package is com.test
permission is android.permission.INTERNET
action is android.intent.action.MAIN
category is android.intent.category.LAUNCHER
案例三:
package step_ten
import java.io.File
fun main() {
val list = listOf("30", "70", "1000")
val htmlObj = html {
head {
title { +"Html自动生成" }
}
body {
h1 { +"一行白鹭上青天" }
p { +"门泊东吴万里船" }
a(href = "https://www.google.com") { +"google" }
p {
+"牛奶面包"
b { +"outdoor" }
+"3366"
a(href = "https://404") { +"no way" }
+"breakfast"
}
p { +"a little scheme" }
p {
+"时光如流水"
ul {
for (item in list)
li {
+item
}
}
}
}
}
val file = File("auto.html")
val htmlText = htmlObj.toString()
file.writeText(htmlText)
println(htmlText)
}
private inline fun html(lambda: Html.() -> Unit): Html {
val html = Html()
html.lambda()
return html
}
private class Html : TagClass("html") {
inline fun head(lambda: Head.() -> Unit) {
val head = Head()
head.lambda()
subElements += head
}
inline fun body(lambda: Body.() -> Unit) {
val body = Body()
body.lambda()
subElements += body
}
}
private class Head : TagClass("head") {
inline fun title(lambda: Title.() -> Unit) {
val title = Title()
title.lambda()
subElements += title
}
}
private class Title : TagClass("title")
private open class Body(tagName: String = "body"): TagClass(tagName){
inline fun h1(lambda: H1.() -> Unit){
val h1 = H1()
h1.lambda()
subElements += h1
}
inline fun p(lambda: P.() -> Unit){
val p = P()
p.lambda()
subElements += p
}
inline fun a(href: String, lambda: A.() -> Unit){
val a = A()
a.lambda()
subElements += a
a.href = href
}
inline fun b(lambda: B.() -> Unit){
val b = B()
b.lambda()
subElements += b
}
inline fun ul(lambda: UL.() -> Unit){
val ul = UL()
ul.lambda()
subElements += ul
}
inline fun li(lambda: LI.() -> Unit){
val li = LI()
li.lambda()
subElements += li
}
}
private class H1: Body("h1")
private class P: Body("p")
private class A: Body("a"){
var href: String
get() = attributes["href"]!!
set(value){
attributes["href"] = value
}
}
private class B: Body("b")
private class UL: Body("ul")
private class LI: Body("li")
// HTML元素抽象 文本 标签
private interface Element {
fun transform(builder: StringBuilder, indent: String)
}
private class TextElement(val text: String) : Element {
override fun transform(builder: StringBuilder, indent: String) {
builder.append("$indent$text\n")
}
}
private open class Tag(val tagName: String) : Element {
val subElements = arrayListOf<Element>()
val attributes = hashMapOf<String, String>()
override fun transform(builder: StringBuilder, indent: String) {
builder.append("$indent<$tagName")
handleAttributes(builder)
for(e in subElements){
e.transform(builder, "$indent ")
}
builder.append("$indent</$tagName>\n")
}
fun handleAttributes(builder: StringBuilder){
for ((k, v) in attributes) {
builder.append(" $k=\"$v\"")
}
builder.append(">\n")
}
override fun toString(): String {
val builder = StringBuilder()
transform(builder, "")
return builder.toString()
}
}
private open class TagClass(tagName: String) : Tag(tagName) {
operator fun String.unaryPlus() {
subElements += TextElement(this)
}
}
输出:
<html>
<head>
<title>
Html自动生成
</title>
</head>
<body>
<h1>
一行白鹭上青天
</h1>
<p>
门泊东吴万里船
</p>
<a href="https://www.google.com">
google
</a>
<p>
牛奶面包
<b>
outdoor
</b>
3366
<a href="https://404">
no way
</a>
breakfast
</p>
<p>
a little scheme
</p>
<p>
时光如流水
<ul>
<li>
30
</li>
<li>
70
</li>
<li>
1000
</li>
</ul>
</p>
</body>
</html>