android颜色透明度怎么设置(android按钮透明效果)
前言
最近kotlin的呼声又是日益高涨,前几天9012年google io正式将kotlin从first _class提升为kotlin_first。我也是接触了一段时间的kotlin,给我的感觉就是简约,快速。无需繁琐的findid,高阶函数的应用,再加上kotlin的null 安全,更是将代码的崩溃率降到更低。
今天我们就来介绍一下今天的主角—anko
1.anko
anko是jetbrains开发的一个强大的库,说起jetbrains ,那就牛逼了,kotlin语言是他们开发的,最流行的的开发工具intellij idea都是他们开发的,as也是基于idea的。好了,言归正传,anko是kotlin官方开发的一个让开发android应用更快速更简单的kotlin库,并且能让我们书写的代码更简单清楚更容易阅读。它包括多个部分
- anko commons: a lightweight library full of helpers for intents, dialogs, logging and so on;
- anko layouts: a fast and type-safe way to write dynamic android layouts;
- anko sqlite: a query dsl and parser collection for android sqlite;
- anko coroutines: utilities based on the kotlinx.coroutines library.
1.1 如何使用
添加依赖
dependencies {
implementation "org.jetbrains.anko:anko:$anko_version"
}
这里面包括上面四个部分,当然你也可以只依赖一个部分,如下:
dependencies {
// anko commons
implementation "org.jetbrains.anko:anko-commons:$anko_version"
// anko layouts
implementation "org.jetbrains.anko:anko-sdk25:$anko_version" // sdk15, sdk19, sdk21, sdk23 are also available
implementation "org.jetbrains.anko:anko-appcompat-v7:$anko_version"
// coroutine listeners for anko layouts
implementation "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version"
implementation "org.jetbrains.anko:anko-appcompat-v7-coroutines:$anko_version"
// anko sqlite
implementation "org.jetbrains.anko:anko-sqlite:$anko_version"
}
下面我们分别介绍这几个功能。
2 ankocommons
ankocommons对android开发者来说是一个工具集,包括但不限于下面这几个
- intents
- dialogs and toasts
- logging
- resources and dimensions
2.1 intents
前面已经提到,commons 库是一个工具集,那intents主要是帮助简化activity之间的跳转。
传统的 kotlin 启动新的 activity 的方式是创建一个 intent,同时可能传递一些参数,最后将创建的 intent 通过 context 的 startactivity() 方法传递,就像这样:
val intent = intent(this, someotheractivity::class.java)
intent.putextra("id", 5)
intent.setflag(intent.flag_activity_single_top)
startactivity(intent)
然鹅你用anko只需要这样:
startactivity(intentfor(“id” to 5).singletop())
如果想要传递多个参数,你也可以这样
startactivity<someotheractivity>(
"id" to 5,
"city" to "denpasar"
)
当然还有一些关于intent的其它操作,如:拨打电话等:如下
2.2 dialogs and toasts
这个库主要是用来快速搭建dialog和toast,具体包含以下几个
- toast
- snackbar
- alert (dialog)
- selectors
- progress dialogs
2.2.1 toast
anko为我们提供了更加简单的toast使用,只需要一行代码即可实现
toast("hi there!")
toast(r.string.message)
longtoast("wow, such duration")
2.2.2 snackbars
snackbar是 android support library 22.2.0 里面新增提供的一个控件,我们可以简单的把它理解成一个加强版的toast,或者是一个轻量级的dialog。
我们可以用下面代码快速创建snackbar。
view.snackbar("hi there!")
view.snackbar(r.string.message)
view.longsnackbar("wow, such duration")
view.snackbar("action, reaction", "click me!") { dostuff() }
这里需要传入view对象,这个可以是布局中的任意一个view对象。
2.2.3 alerts
anko alerts主要包括以下几个功能:
- android 默认dialog
- android appcompat 中alertdialog
- 自定义dialog
1.android 默认dialog
通过以下代码就可以构建一个可以交互的android 默认dialog。
alert("hi, i'm roy", "have you tried turning it off and on again?") {
yesbutton { toast("oh…") }
nobutton {}
}.show()
代码比较简单,就不做解释。
2.android appcompat 中alertdialog
另外anko还提供了appcompat的alertdialog实现方式,如下:
alert(appcompat, "some text message").show()
3.自定义dialog
什么,不能自定义dialog吗?怎么会,自定义dialog也是非常的简单
alert {
customview {
edittext()
}
}.show()
2.2.4 selectors (包含列表的dialog)
我们平时创建列表dialog是这样的:
val listitems = arrayof("russia", "usa", "japan", "australia") //传数组
val listdialog: alertdialog.builder = alertdialog.builder(this)
listdialog.setitems(listitems) { p0, p1 ->
toast(p1)
}
val dialog: alertdialog = listdialog.create()
dialog.show()
val window: window = dialog.window
val params: windowmanager.layoutparams = window.attributes
params.y = 45 * screenutils.getscreendensity().toint()
params.gravity = gravity.top or gravity.right
params.width = screenutils.getscreenwidth() / 2
params.height = viewgroup.layoutparams.wrap_content
window.attributes = params
但是我们用anko是这样的:
val countries = listof("russia", "usa", "japan", "australia") //传list
selector("where are you from?", countries, { dialoginterface, i ->
toast("so you're living in ${countries[i]}, right?")
})
看起来只是简化了dialog的创建过程。
2.2.5 progress dialogs
不显示进度的 loading dialg
pressdialog("please wait a minute.", "downloading…")
indeterminateprogressdialog("fetching the data…")
2.3 logging
打印log辅助工具。
android sdk 提供 android.util.log 类来提供一些 logging 方法,,这些方法都很实用,但是我们每次必须传递一个 tag 参数,同时这个 tag 信息必须是 string 类型的,这就略显麻烦。不过现在我们可以通过 ankologger 类摆脱这些恼人的问题:
class someactivity : activity(), ankologger {
fun somemethod() {
info("info message")
debug(42) // .tostring() method will be called automatically
}
}
默认的 tag 名是当前的类名( 本例中的是someactivity),但是通过重写 ankologger 的 loggertag 属性我们是可以来更改的,而且每个方法有两个版本:plain and lazy (inlined)
1.lazy:
info("string " + "concatenation")
info { "string " + "concatenation" }
2.plain:
class someactivity : activity() {
private val log = ankologger(this.javaclass)
private val logwithaspecifictag = ankologger("my_tag")
private fun somemethod() {
log.warning("big brother is watching you!")
}
}
上面两种方法分别是不同tag的实现方式。
ankologger中loggertag 属性具体对照如下:
2.4 resources and dimensions
你可以在你的项目中使用anko resources and dimensions来简化你的代码,例如color、dimen等,颜色透明度直接色值.opaque就可以,尺寸的话直接使用dip(dipvalue)、sp(spvalue)就可以。在这里面还有一个就是applyrecursively()用来控制子view的操作,如:
verticallayout {
textview{
text = "edittext01"
backgroundcolor = 0xff000.opaque
textsize = 14f
}
textview {
text = "edittext02"
backgroundcolor = 0x99.gray.opaque
textsize = 23f
}
}.applyrecursively {//如果是viewgroup的话可以使用applyrecursively来为每个child view进行设置
view -> when(view){
is textview -> view.textcolor = color.red
}
}
3.anko layouts
通常我们使用xml文件写我们的布局,但是他有一些缺点如不是类型安全,不是空安全,解析xml文件消耗更多的cpu和电量等等。而anko layout可以使用dsl(domain specific language)动态创建我们的ui,并且它比我们使用java动态创建布局方便很多主要是更简洁,它和拥有xml创建布局的层级关系,能让我们更容易阅读。(官方说的优点)
举个栗子:
verticallayout {
val name = edittext()
button("say hello") {
onclick { toast("hello, ${name.text}!") }
}
}
上面的代码是不是很简单易懂,当然,默认的控件并不能满足我们的需求,例如我们会更改字体的颜色及大小,会设置宽度和高度,会设置margin,padding值,那么该如何实行呢,当然也很简单,因为它的逻辑和xml书写布局是一个套路。例如以下实现
val textview=textview("我是一个textview"){
textsize = sp(17).tofloat()
textcolor=0xff000.opaque
}.lparams{
margin=dip(10)
height= dip(40)
width= matchparent
}
配合上前面common库是不是很简单呢?
这里我们不需要setcontentview。直接写在oncreate方法中就行。
在上面创建ui过程中,我们直接把创建ui的代码写在oncreate方法中了,当然,还有一种写法。我们创建一个内部类实行ankocomponent接口,并重写createview方法,该方法返回一个view,也就是我们创建的布局。修改如下
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}!") }
}
}
}
}
现在我们编译运行,发现效果和布局文件写的界面是一样的。但是它的性能是有优势的,其实吧并没有发觉性能优势。不管怎样,这种dsl确实便于阅读,也很容易上手,在上面的代码中,你可能注意到了dip(10),它表示将10dp转换为像素的意思,是anko的扩展函数,说的扩展函数,如果阅读过anko的源码我们发现里面大量的使用扩展函数,这也是kotlin语言的优势之一。
这里就简单介绍下layout的使用和优点。但是我想各位看官在实际开发中也不一定会用,因为不可视化用起来实在难以接受。不过这种见仁见智吧。
4.anko sqlite: a query dsl and parser collection for android sqlite;
anko sqlite是一个查询解析sqlite的领域专用语言
sqlite 存在的不足:
- 过多需要实现的模板代码;
- 通过字符串实现 sql 命令,容易出错,且编译时无法检查;
- 每次需要手动关闭数据库;
- 线程和同步访问的问题;
随着你应用的数据库越来越复杂,暴露出来的问题也会越多。所以也难怪很多人会选择 orm 或者 nosql,但这带来的方便性是以增加应用大小和方法数为代价的。
如果你打算使用 kotlin 来开发 android 应用,那么现在通过 anko sqlite 就可以很方便的进行 sqlite 操作了。比如可以告别麻烦的 cursor 和 contentvalue、内置安全机制,保证数据库在执行所有代码后能够关闭。
通过继承 managedsqliteopenhelper 类来实现数据库帮助类,推荐做法就是按照官方的实现:
class databasehelper(ctx: context) : managedsqliteopenhelper(ctx, "librarydatabase", null, 1) {
companion object {
private var instance: databasehelper? = null
@synchronized
fun instance(context: context): databasehelper {
if (instance == null) {
instance = databasehelper(context.applicationcontext)
}
return instance!!
}
}
override fun oncreate(database: sqlitedatabase) {
createtable(book.table_name, true, book.column_id to integer + primary_key, book.column_title to text, book.column_author to text)
}
override fun onupgrade(database: sqlitedatabase, oldversion: int, newversion: int) {
droptable(book.table_name, true)
}
}
访问数据库的推荐做法是通过依赖注入,或者为 context 添加一个 extension:
val context.database: databasehelper
get() = databasehelper.instance(applicationcontext)
下面这是一个简单的 model 类:
data class book(val id: int, val title: string, val author: string) {
companion object {
val book.column_id = "id"
val table_name = "books"
val column_title = "title"
val column_author = "author"
}
}
当数据库准备好后,就可以通过 use 方法来进行操作了。比如:
database.use {
insert(book.table_name, book.column_id to 1, book.column_title to "2666", book.column_author to "roberto bolano")
}
最后,让我们来比较一下常见库的大小:
要注意这里 anko sqlite 的依赖大小其实是包含了 kotlin runtim (method count: 6298, dex size: 1117 kb) 和 anko commons module (method count: 982, dex size: 174 kb) 的。因此如果你是通过 kotlin 来开发,anko sqlite 增加的大小其实并没有图表显示得那么多。
因此,如果你在使用 kotlin 做开发并且数据库的复杂度不高,首推 anko sqlite。但如果数据库结构非常复杂,dao 和 sql 查询可能会变得很痛苦,这时候 orm 和 nosql 就是首选方案了。
5.anko coroutines: utilities based on the kotlinx.coroutines library.
kotlin协程
协程本质上是一个轻量级的线程,支持我们用同步写法写异步请求,而不用callback。
doasync(ui) {
val data: deferred<data> = bg {
// runs in background
getdata()
}
// this code is executed on the ui thread
showdata(data.await())
}
我们可以用bg()在新的线程去做耗时操作,等返回结果再在ui线程进行操作。
具体协程教程我们可以看一下官方文档
kotlin协程
6.总结
anko是kotlin官方开发的一个让开发android应用更快速更简单的kotlin库,并且能让我们书写的代码更简单清楚更容易阅读。
主要包含了以下几个部分。
- anko commons: a lightweight library full of helpers for intents, dialogs, logging and so on;
- anko layouts: a fast and type-safe way to write dynamic android layouts;
- anko sqlite: a query dsl and parser collection for android sqlite;
- anko coroutines: utilities based on the kotlinx.coroutines library.
anko库用起来非常的简单方便,里面设计到dsl和扩展函数。