热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

androidanko,AnkoforAndroid

Anko是一个使开发Android应用更简单更快捷的库,Anko使你的代码简洁易懂,使开发者不用再在意AndroidSDK对Java版本的限制(目前还不支持Java8。).Anko

Anko 是一个使开发Android应用更简单更快捷的库,Anko使你的代码简洁易懂, 使开发者不用再在意Android SDK对Java版本的限制(目前还不支持Java8 =。= ).

Anko版本的 hello world :

verticalLayout {

val name = editText()

button("Say Hello") {

onClick { toast("Hello, ${name.text}!") }

}

}

上面的代码创建了一个Button,放在 LinearLayout 内, 并为其设置了一个点击监听器OnClickListener .

oYYBAFYnZ7GAHENVAATT_iv8nqY107.gif

上面是一个DSL(Domain Specific Language),使用的是 Kotlin语言.

DSL,即 Domain Specific Language,领域相关语言。什么是 DSL,说白了它就是某个行业中的行话。

[TOC]

Why Anko?

为啥 DSL?

平时开发android, UI写在xml中,这就导致了下面的几个问题 :

It is not typesafe

It is not null-safe

It forces you to write almost the same code for every layout you make

XML is parsed on the device wasting CPU time and battery 渲染xml为对象过程耗时耗电

Most of all, it allows no code reuse. 大部分不能重用

但是全部只在代码中写UI,这很难,不仅代码丑,而且冗余难维护,下面是 Ktolin版本的(Java甚至更长):

val act = this

val layout = LinearLayout(act)

layout.setOrientation(LinearLayout.VERTICAL)

val name = EditText(act)

val button = Button(act)

button.setText("Say Hello")

button.setOnClickListener {

Toast.makeText(act, "Hello, ${name.getText()}!", Toast.LENGTH_SHORT).show()

}

layout.addView(name)

layout.addView(button)

DSL 就不一样类,相同的逻辑,但简洁易懂, 易于编写而且没有运行开销(runtime overhead)看下面的代码:

verticalLayout {

val name = editText()

button("Say Hello") {

onClick { toast("Hello, ${name.text}!") }

}

}

为啥不用 Scaloid?

Scaloid 是一个类似与 Scala 的库, 有很多非常酷的特性可供 Scala 开发者使用. Anko主要是针对 Java 和 Kotlin developers.

兼容已有的代码

不需要用Anko重写所有的UI, 你可以保留原有的Java代码. 此外, 如果你想写一个 Kotlin的activity类并且由于某些需求需要使用 inflate来渲染xml, 你完全可以按照原来的写法:

// Same as findViewById(), simpler to use

val name = find(R.id.name)

name.hint = "Enter your name"

name.onClick { /*do something*/ }

工作原理

There is no :tophat:. Anko 由一些 Kotlin的 扩展函数和属性,被设置成类型安全(type-safe builders)的, under Type Safe Builders.

他们繁琐的手工编写所有这些扩展, 使用Android SDK的源码中的 android.jar 文件自动生成

可扩展吗?

答案是: yes.

例如. 你可能想使用 MapView 在DSL中.你可以编写下面的代码(kotlin文件中),然后就可已到处使用了

public inline fun ViewManager.mapView() = mapView {}

public inline fun ViewManager.mapView(init: MapView.() -> Unit): MapView {

return ankoView({ MapView(it) }, init)

}

{ MapView(it) } 是你自定义View的一个工厂方法View. 接受一个 Context .

frameLayout {

val mapView = mapView().lparams(width = matchParent)

}

如果你想创建一个 顶级的 DSL,看这里Extending Anko.

使用 Gradle

这里有个例子 template project 展示类如果在Android中Gradle配置.

基本上,你只需要配置 repository 和一个 compile dependency:

dependencies {

compile 'org.jetbrains.anko:anko-sdk15:0.7.1' // sdk19, sdk21, sdk23 are also available

compile 'org.jetbrains.anko:anko-support-v4:0.7.1' // In case you need support.v4 bindings

}

当作 Jar library使用

加入你的项目不是基于Gradl, 不需要配置 Maven. 只要添加这里 的jar包即可.

编译 Anko

理解 Anko

Anko 是使用 Kotlin语言编写的.

如果不熟悉Kotlin看 kotlinlang.org.

Kotlin与Java很类似,所以很容易学.

基础

Anko中, 你不需要继承其他奇怪的类,只要标准的Activity, Fragment, FragmentActivity 或者其他任意的类

首先, 在使用Anko的DSL的类中导入 org.jetbrains.anko.* .

DSL 可以在 onCreate()中使用:

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

verticalLayout {

padding = dip(30)

editText {

hint = "Name"

textSize = 24f

}

editText {

hint = "Password"

textSize = 24f

}

button("Login") {

textSize = 26f

}

}

}

不需要显示的调用 setContentView(R.layout.something), Anko 自动为Activity(只会对Activity)进行 set content view

padding, hint 和 textSize 是 扩展属性. 大多数 View 具有这些属性,允许使用text = "Some text" 代替 setText("Some text").

verticalLayout (一个竖直方向的 LinearLayout), editText 和 button are

扩展函数. 这些函数存在与ANdroid 框架中的大部View中, Activities, Fragments ( android.support 包中的) 甚至 Context同样适用.

如果有一个 Context 实例, 可以写出下面的DSL结构:

val name = with(myContext) {

editText {

hint = "Name"

}

}

变量 name 成为了 EditText类型.

Helper 方法

你可能注意到了,前面章节中 button 方法接了一个字符串参数,这样的Helper方法同样使用与 TextView, EditText, Button , ImageView.

如果你不需要 View 其他的属性,你可以省略 {} 直接写 button("Ok") 或只有 button():

verticalLayout {

button("Ok")

button("Cancel")

}

Layouts 和 LayoutParams

在父布局中布局控件可能需要使用 LayoutParams. xml中长这样:

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android_layout_marginLeft="5dip"

android_layout_marginTop="10dip"

android:src="@drawable/something" />

Anko中, 在View的后面使用 lparams来实现类似与xml的 LayoutParams。

linearLayout {

button("Login") {

textSize = 26f

}.lparams(width = wrapContent) {

horizontalMargin = dip(5)

topMargin = dip(10)

}

}

如果指定了 lparams,但是没有指定 width 或者 height, 默认是 WRAP_CONTENT.但是你可以自己通过使用named arguments指定.

注意下面一些方便的属性:

horizontalMargin 同时设置 left 和 right margins,

verticalMargin 同时设置 top 和 bottom

margin 同时设置4个方向的 margins.

注意 lparams 的使用在不同的布局中是不同的, 例如在 RelativeLayout中:

val ID_OK = 1

relativeLayout {

button("Ok") {

id = ID_OK

}.lparams { alignParentTop() }

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

}

Listeners

设置listeners:

button("Login") {

onClick {

login(name, password)

}

}

下面的效果一样:

button.setOnClickListener(object : OnClickListener {

override fun onClick(v: View) {

login(name, password)

}

})

当一个Listener有多个方法时,Anko就显得很方便类. 看下面的代码(没有使用Anko):

seekBar.setOnSeekBarChangeListener(object: OnSeekBarChangeListener {

override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {

// Something

}

override fun onStartTrackingTouch(seekBar: SeekBar?) {

// Just an empty method

}

override fun onStopTrackingTouch(seekBar: SeekBar) {

// Another empty method

}

})

使用了Anko:

seekBar {

onSeekBarChangeListener {

onProgressChanged { seekBar, progress, fromUser ->

// Something

}

}

}

如果你同时设置了onProgressChanged 和 onStartTrackingTouch , 两个方法将被合并. 对于多个相同的方法,最后的一个有效.

Resources, Colors 和 Dimensions

Using resource identifiers

前面的所有例子直接使用的 Java的字符串,但是大多数时候字符串都是放在 res/values/ 目录下,并且是运行时调用的,例如 getString(R.string.login).

幸运的是,Anko中可以使用以下两个 helper方法 (button(R.string.login)) 和 (button { textResource = R.string.login }).

注意,这些属性不是 text, hint, image, 而是 textResource, hintResource and imageResource.

Resource properties always throw AnkoException when read.

Colors

两个简单的扩展函数使代码更加易懂。

Function

Result

0xff0000.opaque

non-transparent red

0x99.gray.opaque

non-transparent #999999 gray

Dimensions

你可以指定 dimension 的 dip (density-independent pixels) 或 sp (scale-independent pixels)值: dip(dipValue) 或 sp(spValue). 注意 textSize属性默认接受sp (textSize = 16f). 使用 px2dip 和 px2sp 相互转换.

Instance shorthands

在Activity中,有时你需要传一个 Context实例给一个 Android SDK中的方法,通常你会写 this, 如果在内部类呢?你可能写SomeActivity.this ,如果你使用 Kotlin,你只需写 this@SomeActivity ,

使用 Anko,你可以只写 ctx. ctx是Activity 和 Service 或者 Fragment (使用的 getActivity() )内部的一个属性. 你也可以使用act扩展属性获取 Activity实例.

UI wrapper

开始使用Anko 之前,将 UI tag 作为 DSL 顶级元素:

UI {

editText {

hint = "Name"

}

}

这将更易于扩展 DSL ,因为你必须声明一个函数 ViewManager.customView.

看这里 Extending Anko 获取更多信息.

Include tag

使用 include tag 很容易向 DSL 插入 一个 XML layout :

include(R.layout.something) {

backgroundColor = Color.RED

}.lparams(width = matchParent) { margin = dip(12) }

通常可以使用 lparams , 如果类型不是 View,仍然可以用 {}:

include(R.layout.textfield) {

text = "Hello, world!"

}

Styles

Anko 支持 styling: style 是一个简单的函数,接受一个View, 效果作用于这个 View , 并且当这个View 是一个ViewGroup 时,可以可以递归的作用与 这个View的 child View:

verticalLayout {

editText {

hint = "Name"

}

editText {

hint = "Password"

}

}.style { view -> when(view) {

is EditText -> view.textSize = 20f

}}

oYYBAFYnaXGAU36mAAA-AHHYR0Y038.png



推荐阅读
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 深入解析JVM垃圾收集器
    本文基于《深入理解Java虚拟机:JVM高级特性与最佳实践》第二版,详细探讨了JVM中不同类型的垃圾收集器及其工作原理。通过介绍各种垃圾收集器的特性和应用场景,帮助读者更好地理解和优化JVM内存管理。 ... [详细]
  • 本文详细介绍 Go+ 编程语言中的上下文处理机制,涵盖其基本概念、关键方法及应用场景。Go+ 是一门结合了 Go 的高效工程开发特性和 Python 数据科学功能的编程语言。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
author-avatar
韩庚plus
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有