继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Kotlin Android 框架 Anko:Anko布局有什么好

汪汪一只猫
关注TA
已关注
手记 579
粉丝 129
获赞 718

为什么选择Anko布局?

<a target="_blank title=" null"="" style="word-wrap: break-word; word-break: break-all;">为何使用 DSL?

默认情况下,Android的UI使用XML来写的。这种方式有以下几个不方便的地方:

  • 不是类型安全的;

  • 不是空指针安全的;

  • 它着力于让你的每一个布局都写几乎一样的代码;

  • XML在设备上进行解析会浪费CPU时间和电量;

  • 最重要的是,它不允许代码重用。

当你使用程序代码来创建UI时,这通常让你感到为难,代码丑陋还不易于维护。 这是一个原生的Kotlin版本的代码 (在Java中代码可能更多):

    val act = this
    val layout = LinearLayout(act)
    layout.orientation = LinearLayout.VERTICAL    val name = EditText(act)    val button = Button(act)
    button.text = "Say Hello"
    button.setOnClickListener {
        Toast.makeText(act, "Hello, ${name.text}!", Toast.LENGTH_SHORT).show()
    }
    layout.addView(name)
    layout.addView(button)

使用 DSL 使得处理同样的逻辑时,代码变得易读、易写并且还没有运行时额外的性能损耗。看下面这端代码:

    verticalLayout {        val name = editText()
        button("Say Hello") {
            onClick { toast("Hello, ${name.text}!") }
        }
    }

注意: onClick() 支持协同程序 (挂起lambda表达式) 所以你可以直接在里面写你的异步代码,而不用显示的 async(UI) 调用。

Kotlin Android扩展让代码变的更加简洁。

扩展函数和属性到类型安全的建造器(在它可以扩展吗?

简单的回答: 可以。

例如,已可能想在DSL中使用一个 MapView。 只需要在任何一个你可以导入的Kotlin文件中这样写:

    inline fun ViewManager.mapView() = mapView(theme = 0) {}    inline fun ViewManager.mapView(init: MapView.() -> Unit): MapView {        return ankoView({ MapView(it) }, theme = 0, init = init)
    }

{ MapView(it) } 是一个关于自定义 View 的工厂函数。 它接收一个 Context 实例。

所以,现在你可以这样写:

    frameLayout {        val mapView = mapView().lparams(width = matchParent)
    }

如果你想你的使用者可以应用自定义主题,也可以这样写:

    inline fun ViewManager.mapView(theme: Int = 0) = mapView(theme) {}    inline fun ViewManager.mapView(theme: Int = 0, init: MapView.() -> Unit): MapView {        return ankoView({ MapView(it) }, theme, init)
    }

<a target="_blank title=" null"="" style="word-wrap: break-word; word-break: break-all;">在你的项目中使用Anko布局

包含这些依赖库:

    dependencies {        // Anko Layouts
        compile "org.jetbrains.anko:anko-sdk25:$anko_version" // sdk15, sdk19, sdk21, sdk23 are also available
        compile "org.jetbrains.anko:anko-appcompat-v7:$anko_version"

        // Coroutine listeners for Anko Layouts
        compile "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version"
        compile "org.jetbrains.anko:anko-appcompat-v7-coroutines:$anko_version"
    }

请阅读 理解Anko

合成扩展属性 绑定了 JavaBean风格的 getters 和 setters, padding 是一个Anko的 扩展函数 。我们像Blocks一样引用这些函数。

Blocks几乎在Android框架中的每一个 View 中都存在,它们工作在 ActivitiesFragments (在 android.support 中的也行) 甚至是 Context 中。 例如, 你想要一个 AnkoContext 实例。 你可以像这样写 blocks :

    val name: EditText = with(ankoContext) {        editText {            hint = "Name"
        }
    }

布局预览的特性 。

    class MyActivity : AppCompatActivity() {        override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {            super.onCreate(savedInstanceState, persistentState)
            MyActivityUI().setContentView(this)
        }
    }    class MyActivityUI : AnkoComponent<MyActivity> {        override fun createView(ui: AnkoContext<MyActivity>) = with(ui) {
            verticalLayout {                val name = editText()
                button("Say Hello") {
                    onClick { ctx.toast("Hello, ${name.text}!") }
                }
            }
        }
    }

主题化的 blocks

Anko 提供“可制定主题” 的 blocks 版本,包括 blocks 助手:

    verticalLayout {
        themedButton("Ok", theme = R.style.myTheme)
    }

命名参数.

这用一些方便的属性助手值得注意:

  • horizontalMargin 设置左侧和右侧的外边距,

  • verticalMargin 设置顶部和底部的

  • margin 同时设置所有的外边边距。

注意对于不同的布局 lparams() 也是不同的,例如,在使用 RelativeLayout 的情况下:

    val ID_OK = 1

    relativeLayout {
        button("Ok") {
            id = ID\_OK
        }.lparams { alignParentTop() }

        button("Cancel").lparams { below(ID_OK) }
    }

自定义协程上下文

你可以传递一个自定义的协程上下文到监听器助手中:

    button("Login") {
        onClick(yourContext) {
            val user = myRetrofitService.getUser().await()
            showUser(user)
        }
    }

实例速记符

有些时候,你需要传递一个 Context 实例到一些Android SDK的方法中。 通常情况下, 你可以仅仅使用 this, 但如果是在一个内部类中,该怎么办呢? 在Java中你会写 SomeActivity.this 如果你用的是Kotlin的话,则应该这样 this@SomeActivity 。

在kotlin中你可以只写 ctx。 这是一个工作在 Activity 和 Service 甚至是在 Fragment 中的扩展属性 (它背后使用的是 getActivity() 方法)。 你也可以使用扩展属性 act 获取 Activity 的实例。

Anko 扩展 for more information.

Anko 支持插件

在IntelliJ IDEA 和 Android Studio 中可以使用Anko支持插件。它能帮你在IDE中,直接预览使用Anko写的AnkoComponent 。


5b9216240001327501280128.jpg

:warning:

Anko支持插件Android Studio 2.4及以上版本


here.

<a target="_blank title=" null"="" style="word-wrap: break-word; word-break: break-all;">使用插件

保证你已经使用Anko写了这些类:

    class MyActivity : AppCompatActivity() {        override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {            super.onCreate(savedInstanceState, persistentState)
            MyActivityUI().setContentView(this)
        }
    }    class MyActivityUI : AnkoComponent<MyActivity> {        override fun createView(ui: AnkoContext<MyActivity>) = ui.apply {
            verticalLayout {                val name = editText()
                button("Say Hello") {
                    onClick { ctx.toast("Hello, ${name.text}!") }
                }
            }
        }.view
    }

将鼠标放到 MyActivityUI 的声明中, 打开 Anko布局预览 工具窗口 ("View(视图)" "Tool Windows(工具窗口)" "Anko Layout Preview(Anko布局预览)") 并点击 Refresh(刷新).

这个过程需要构建工程,所以在看到图像之前需要等待一定的时间。

<a target="_blank title=" null"="" style="word-wrap: break-word; word-break: break-all;">XML 转 DSL

这个插件运训你将XML格式的布局转换为Anko布局代码。 打开XML文件,并选择 "Code(代码)" "Convert to Anko Layouts DSL"。 你可以同时转化多个XML文件。

原文链接:http://www.apkbus.com/blog-822717-72682.html

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP