Android DSL

文章目录

  • Android DSL
    • 概述
    • 使用DSL构建HTML
    • 代码下载

Android DSL

概述

Kotlin DSL(领域特定语言)是一种使用 Kotlin 语言编写的,用于解决特定问题领域的语言。DSL 使得代码更易读、易写,因为它的语法和领域问题的语法更接近。Kotlin 的强大类型系统和灵活性使得创建 DSL 变得更加容易。

使用DSL构建HTML

定义接口:

interface IElement {

    // 拼接HTML字符串,每个元素都需要实现
    fun render(builder: StringBuilder, indent: String): String
}

实现父类:

/**
 * 需要传入标签名和内容
 * 每个元素都有标签名,如:

hello

*/
open class BaseElement(val tagName: String, val content: String = "") : IElement { private val children = mutableListOf<BaseElement>() //元素内的所有子元素 private val _attributes = mutableMapOf<String, String>() //元素的属性名和属性值 protected val attributes get() = _attributes protected fun addElement(element: BaseElement) { this.children.add(element) } protected fun renderAttributes(): String { val builder = StringBuilder() if (attributes.isNotEmpty()) { for ((attrName, attrValue) in attributes) { builder.append(""" $attrName="$attrValue"""") } } return builder.toString() } override fun render(builder: StringBuilder, indent: String): String { builder.append("$indent<$tagName") builder.append(renderAttributes()) builder.append(">\n") if (content.isNotBlank()) { builder.append(" $indent$content\n") } children.forEach { it.render(builder, " $indent") } builder.append("$indent$tagName>\n") return builder.toString() } operator fun invoke(): String { val builder = StringBuilder() return render(builder, "") } }

实现子元素:

fun html(block: Html.() -> Unit): Html {
    val html = Html()
    html.block()
    return html
}

// 标签
class Html() : BaseElement("html") {
    fun head(block: Head.() -> Unit): Head {
        val head = Head()
        head.block()
        addElement(head)
        return head
    }

    fun body(block: Body.() -> Unit): Body {
        val body = Body()
        body.block()
        addElement(body)
        return body
    }
}

// 标签
class Head : BaseElement("head") {
    fun title(block: () -> String): Title {
        val content = block()
        val title = Title(content)
        addElement(title)
        return title
    }
}

// 标签</span>
<span class="token keyword">class</span> <span class="token function">Title</span><span class="token punctuation">(</span>content<span class="token operator">:</span> String<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">BaseElement</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"title"</span></span><span class="token punctuation">,</span> content<span class="token punctuation">)</span>

<span class="token comment">// <body>标签</span>
<span class="token keyword">class</span> Body <span class="token operator">:</span> <span class="token function">BaseElement</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"body"</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">fun</span> <span class="token function">h1</span><span class="token punctuation">(</span>block<span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> String<span class="token punctuation">)</span><span class="token operator">:</span> H1 <span class="token punctuation">{</span>
        <span class="token keyword">val</span> content <span class="token operator">=</span> <span class="token function">block</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token keyword">val</span> h1 <span class="token operator">=</span> <span class="token function">H1</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span>
        <span class="token function">addElement</span><span class="token punctuation">(</span>h1<span class="token punctuation">)</span>
        <span class="token keyword">return</span> h1
    <span class="token punctuation">}</span>

    <span class="token keyword">fun</span> <span class="token function">p</span><span class="token punctuation">(</span>block<span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> String<span class="token punctuation">)</span><span class="token operator">:</span> P <span class="token punctuation">{</span>
        <span class="token keyword">val</span> content <span class="token operator">=</span> <span class="token function">block</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token keyword">val</span> p <span class="token operator">=</span> <span class="token function">P</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span>
        <span class="token function">addElement</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span>
        <span class="token keyword">return</span> p
    <span class="token punctuation">}</span>

    <span class="token keyword">fun</span> <span class="token function">a</span><span class="token punctuation">(</span>href<span class="token operator">:</span> String <span class="token operator">=</span> <span class="token string-literal singleline"><span class="token string">""</span></span><span class="token punctuation">,</span> block<span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> String<span class="token punctuation">)</span><span class="token operator">:</span> A <span class="token punctuation">{</span>
        <span class="token keyword">val</span> content <span class="token operator">=</span> <span class="token function">block</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token keyword">val</span> a <span class="token operator">=</span> <span class="token function">A</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">apply</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>href <span class="token operator">=</span> href
        <span class="token punctuation">}</span>
        <span class="token function">addElement</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span>
        <span class="token keyword">return</span> a
    <span class="token punctuation">}</span>

    <span class="token keyword">fun</span> <span class="token function">img</span><span class="token punctuation">(</span>src<span class="token operator">:</span> String <span class="token operator">=</span> <span class="token string-literal singleline"><span class="token string">""</span></span><span class="token punctuation">,</span> alt<span class="token operator">:</span> String <span class="token operator">=</span> <span class="token string-literal singleline"><span class="token string">""</span></span><span class="token punctuation">)</span><span class="token operator">:</span> Img <span class="token punctuation">{</span>
        <span class="token keyword">val</span> img <span class="token operator">=</span> <span class="token function">Img</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">apply</span> <span class="token punctuation">{</span>
            <span class="token keyword">this</span><span class="token punctuation">.</span>src <span class="token operator">=</span> src
            <span class="token keyword">this</span><span class="token punctuation">.</span>alt <span class="token operator">=</span> alt
        <span class="token punctuation">}</span>
        <span class="token function">addElement</span><span class="token punctuation">(</span>img<span class="token punctuation">)</span>
        <span class="token keyword">return</span> img
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// <h1>标签</span>
<span class="token keyword">class</span> <span class="token function">H1</span><span class="token punctuation">(</span>content<span class="token operator">:</span> String<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">BaseElement</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"h1"</span></span><span class="token punctuation">,</span> content<span class="token punctuation">)</span>

<span class="token comment">// <p>标签</span>
<span class="token keyword">class</span> <span class="token function">P</span><span class="token punctuation">(</span>content<span class="token operator">:</span> String<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">BaseElement</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"p"</span></span><span class="token punctuation">,</span> content<span class="token punctuation">)</span>

<span class="token comment">// <a>标签</span>
<span class="token keyword">class</span> <span class="token function">A</span><span class="token punctuation">(</span>content<span class="token operator">:</span> String<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">BaseElement</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"a"</span></span><span class="token punctuation">,</span> content<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> href<span class="token operator">:</span> String
        <span class="token keyword">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> attributes<span class="token punctuation">[</span><span class="token string-literal singleline"><span class="token string">"href"</span></span><span class="token punctuation">]</span><span class="token operator">!!</span>
        <span class="token keyword">set</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            attributes<span class="token punctuation">[</span><span class="token string-literal singleline"><span class="token string">"href"</span></span><span class="token punctuation">]</span> <span class="token operator">=</span> value
        <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// <img>标签</span>
<span class="token keyword">class</span> Img <span class="token operator">:</span> <span class="token function">BaseElement</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"img"</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> src<span class="token operator">:</span> String
        <span class="token keyword">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> attributes<span class="token punctuation">[</span><span class="token string-literal singleline"><span class="token string">"src"</span></span><span class="token punctuation">]</span><span class="token operator">!!</span>
        <span class="token keyword">set</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            attributes<span class="token punctuation">[</span><span class="token string-literal singleline"><span class="token string">"src"</span></span><span class="token punctuation">]</span> <span class="token operator">=</span> value
        <span class="token punctuation">}</span>

    <span class="token keyword">var</span> alt<span class="token operator">:</span> String
        <span class="token keyword">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> attributes<span class="token punctuation">[</span><span class="token string-literal singleline"><span class="token string">"alt"</span></span><span class="token punctuation">]</span><span class="token operator">!!</span>
        <span class="token keyword">set</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            attributes<span class="token punctuation">[</span><span class="token string-literal singleline"><span class="token string">"alt"</span></span><span class="token punctuation">]</span> <span class="token operator">=</span> value
        <span class="token punctuation">}</span>

    <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">render</span><span class="token punctuation">(</span>builder<span class="token operator">:</span> StringBuilder<span class="token punctuation">,</span> indent<span class="token operator">:</span> String<span class="token punctuation">)</span><span class="token operator">:</span> String <span class="token punctuation">{</span>
        <span class="token keyword">return</span> builder<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$</span><span class="token expression">indent</span></span><span class="token string"><</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$</span><span class="token expression">tagName</span></span><span class="token string">"</span></span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token function">renderAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">" />\n"</span></span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p><strong>使用:</strong></p> 
  <pre><code class="prism language-kotlin"><span class="token keyword">class</span> MainActivity <span class="token operator">:</span> <span class="token function">AppCompatActivity</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">onCreate</span><span class="token punctuation">(</span>savedInstanceState<span class="token operator">:</span> Bundle<span class="token operator">?</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">onCreate</span><span class="token punctuation">(</span>savedInstanceState<span class="token punctuation">)</span>
        <span class="token function">setContentView</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>layout<span class="token punctuation">.</span>activity_main<span class="token punctuation">)</span>
        <span class="token keyword">val</span> webView<span class="token operator">:</span> WebView <span class="token operator">=</span> <span class="token function">findViewById</span><span class="token punctuation">(</span>R<span class="token punctuation">.</span>id<span class="token punctuation">.</span>webView<span class="token punctuation">)</span>

        <span class="token keyword">val</span> htmlStr <span class="token operator">=</span> <span class="token function">getHtmlStr</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        webView<span class="token punctuation">.</span><span class="token function">loadData</span><span class="token punctuation">(</span>htmlStr<span class="token punctuation">,</span> <span class="token string-literal singleline"><span class="token string">"text/html"</span></span><span class="token punctuation">,</span> <span class="token string-literal singleline"><span class="token string">"UTF-8"</span></span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">fun</span> <span class="token function">getHtmlStr</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> String <span class="token punctuation">{</span>
        <span class="token keyword">return</span> html <span class="token punctuation">{</span>
            head <span class="token punctuation">{</span>
                title <span class="token punctuation">{</span>
                    <span class="token string-literal singleline"><span class="token string">"hello Kotlin"</span></span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            body <span class="token punctuation">{</span>
                h1 <span class="token punctuation">{</span>
                    <span class="token string-literal singleline"><span class="token string">"hello world DSL"</span></span>
                <span class="token punctuation">}</span>
                p <span class="token punctuation">{</span>
                    <span class="token string-literal singleline"><span class="token string">"--------------------------"</span></span>
                <span class="token punctuation">}</span>
                <span class="token function">img</span><span class="token punctuation">(</span>
                    src <span class="token operator">=</span> <span class="token string-literal singleline"><span class="token string">"https://img-home.csdnimg.cn/images/20201124032511.png"</span></span><span class="token punctuation">,</span>
                    alt <span class="token operator">=</span> <span class="token string-literal singleline"><span class="token string">"hello DSL"</span></span>
                <span class="token punctuation">)</span>
                p <span class="token punctuation">{</span>
                    <span class="token string-literal singleline"><span class="token string">"=========================="</span></span>
                <span class="token punctuation">}</span>
                <span class="token function">a</span><span class="token punctuation">(</span>href <span class="token operator">=</span> <span class="token string-literal singleline"><span class="token string">"https://blog.csdn.net/qq_14876133"</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    <span class="token string-literal singleline"><span class="token string">"Kotlin"</span></span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p><strong>效果:</strong></p> 
  <p><a href="http://img.e-com-net.com/image/info8/16a398b9028c4ce28a9c687dd3026043.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/16a398b9028c4ce28a9c687dd3026043.jpg" alt="Android DSL_第1张图片" width="365" height="290" style="border:1px solid black;"></a></p> 
  <p><strong>输出的html字符串:</strong></p> 
  <pre><code><html>
        <head>
            <title>
                hello Kotlin
            
        
        
            

hello world DSL

--------------------------

hello DSL

==========================

Kotlin

代码下载

你可能感兴趣的:(Android,android,Kotlin,DSL)