提醒对话框
手机上的App极大地方便了人们的生活,很多业务只需用户拇指一点即可轻松办理,然而这也带来了一定的风险,因为有时候用户并非真的想这么做,只是不小心点了一下而已,如果App不做任何提示的话,继续吭哧吭哧兀自办完业务,比如转错钱了、误删资料了,往往令用户追悔莫及。所以对于部分关键业务,App为了避免用户的误操作,很有必要弹出消息对话框,提醒用户是否真的要进行此项操作。这个提醒对话框便是App开发常见的AlertDialog,说起这个AlertDialog,安卓开发者都有所耳闻,该对话框不外乎消息标题、消息内容、确定按钮、取消按钮这四个要素,使用Java编码显示提醒对话框,基本跟下面的示例代码大同小异:

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("尊敬的用户");
builder.setMessage("你真的要卸载我吗?");
builder.setPositiveButton("残忍卸载", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tv_alert.setText("虽然依依不舍,但是只能离开了");
}
});
builder.setNegativeButton("我再想想", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tv_alert.setText("让我再陪你三百六十五个日夜");
}
});
AlertDialog alert = builder.create();
alert.show();

显而易见上述代码非常冗长,特别是两个按钮的点击事件,又是匿名类又是函数重载,令人不堪卒读。尝试将以上Java代码转换为Kotlin代码,则改写后的Kotlin代码如下所示:

    val builder = AlertDialog.Builder(this)
builder.setTitle("尊敬的用户")
builder.setMessage("你真的要卸载我吗?")
builder.setPositiveButton("残忍卸载") { dialog, which -> tv_alert.text = "虽然依依不舍,还是只能离开了" }
builder.setNegativeButton("我再想想") { dialog, which -> tv_alert.text = "让我再陪你三百六十五个日夜" }
val alert = builder.create()
alert.show()

这下看来点击事件的代码在很大程度上简化了,不过除此之外,整块代码依然显得有些臃肿,尤其是运用了建造者模式的Builder类,虽然表面上增强了安全性,但对于编码来说其实是累赘。因此,Anko库将其做了进一步的封装,给Context类添加了一个扩展函数,即“alert(消息内容, 消息标题) { 几个按钮及其点击事件 }”,简化后的alert弹窗代码举例如下:

    alert("你真的要卸载我吗?", "尊敬的用户") {
positiveButton("残忍卸载") { tv_alert.text = "虽然依依不舍,还是只能离开了" }
negativeButton("我再想想") { tv_alert.text = "让我再陪你三百六十五个日夜" }
}.show()

现在的Kotlin代码相比之下更方便阅读了,并且代码量还不到原来Java代码的三分之一。当然,为了正常地使用这么好的扩展函数,不要忘了在代码文件头部加上下面一行导入语句:

import org.jetbrains.anko.alert

这么精简的Kotlin代码,功能上可是一点都没偷工减料的,它的提醒对话框效果与Java编码一模一样,都如下图所示。

下拉选择框
对于某些固定值的条件选择,比如红绿蓝三原色选择其一,一月份到十二月份选择其中一个月份等等,这些情况在Android中用到了下拉框Spinner。界面上的Spinner控件一开始是个右侧带向下箭头的文本,点击该文本会弹出一个选择对话框,选中某一项之后,对话框消失,同时界面上的文本替换为刚才选中的文本内容。光看下拉框的功能其实挺简单的,可是若用Java代码实现的话,就得费一番功夫了,下面便是Spinner控件的调用代码例子:

    private void initSpinner() {
ArrayAdapter<String> starAdapter = new ArrayAdapter<String>(this,
R.layout.item_select, starArray);
starAdapter.setDropDownViewResource(R.layout.item_dropdown);
Spinner sp = (Spinner) findViewById(R.id.sp_dialog);
sp.setPrompt("请选择行星");
sp.setAdapter(starAdapter);
sp.setSelection(0);
sp.setOnItemSelectedListener(new MySelectedListener());
} private String[] starArray = {"水星", "金星", "地球", "火星", "木星", "土星"};
class MySelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Toast.makeText(SpinnerDialogActivity.this, "你选择的行星是"+starArray[arg2], Toast.LENGTH_LONG).show();
} public void onNothingSelected(AdapterView<?> arg0) {}
}

不出所料这再次体现了Java编码的尾大不掉,简简单单的功能在Java代码中被分解为以下几个专门的处理:

1、首先要定义一个数组适配器ArrayAdapter,指定待选择的字符串数组,以及每项文本的布局文件;
2、其次要定义一个选择监听器OnItemSelectedListener,在用户选中某项时触发,响应文本项的选中事件;
3、最后Spinner控件依次设置选择对话框的标题、数组适配器、选择监听器、默认选项等等;
我的天,这也太专业了吧,在产品经理看来,这只是个下拉框而已,有必要搞这么复杂吗?然而Java代码就是这么错综复杂,要想开发Android,只能这么捣腾,不然还有更好的法子吗?不信的话换成Kotlin试试?说时迟那时快,在Android Studio上面把Spinner上述的Java代码转换为Kotlin,不一会儿就生成了如下的Kotlin代码:

    private fun initSpinner() {
val starAdapter = ArrayAdapter(this, R.layout.item_select, starArray)
starAdapter.setDropDownViewResource(R.layout.item_dropdown)
val sp = findViewById(R.id.sp_dialog) as Spinner
sp.prompt = "请选择行星"
sp.adapter = starAdapter
sp.setSelection(0)
sp.onItemSelectedListener = MySelectedListener()
} private val starArray = arrayOf("水星", "金星", "地球", "火星", "木星", "土星")
internal inner class MySelectedListener : OnItemSelectedListener {
override fun onItemSelected(arg0: AdapterView<*>, arg1: View, arg2: Int, arg3: Long) {
toast("你选择的行星是${starArray[arg2]}")
} override fun onNothingSelected(arg0: AdapterView<*>) {}
}

瞧瞧,号称终结者的Kotlin也不过尔尔,整体代码量跟Java相比是半斤八两,丝毫不见了往日的威风。由于这里的Java代码逻辑实在拐弯抹角,又是数组适配器又是选择监听器的,因此Kotlin对这种玩意确实没有好办法。既然此路不通,那就试试别的办法呗,前面提到Spinner其实由两部分组成,一部分是直接显示在界面上的带箭头文本,另一部分是点击后弹出的选择对话框,所以能不能绕过Spinner,运用所见即所得的理念,干脆把下拉框分离成两个控件好了。倘若仅仅是一个带箭头的文本,毫无疑问使用文本视图TextView就可以了,箭头图标可以在布局文件中通过drawableRight属性来指定。于是布局文件中的下面Spinner节点:

    <Spinner
android:id="@+id/sp_dialog"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@+id/tv_dialog"
android:gravity="left|center"
android:spinnerMode="dialog" />

表面上完全可以被下面这个TextView节点所取代:

    <TextView
android:id="@+id/tv_spinner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@+id/tv_dialog"
android:gravity="center"
android:drawableRight="@drawable/arrow_down"
android:textColor="@color/black"
android:textSize="17sp" />

如果再来一个选择对话框,这样只要给该文本视图添加点击事件,点击TextView弹出选择框,岂不是万事大吉?正巧Anko库已经提供了这股东风,与alert一样来自于Context的扩展函数,它便是“selector(对话框标题, 字符串队列) { i -> 第i项的选中处理代码 }”,那么将其与前面的文本视图相结合,即可无缝实现原来的下拉框功能,具体的Kotlin代码如下所示:

    val satellites = listOf("水星", "金星", "地球", "火星", "木星", "土星")
tv_spinner.text = satellites[0]
tv_spinner.setOnClickListener {
selector("请选择行星", satellites) { i ->
tv_spinner.text = satellites[i]
toast("你选择的行星是${tv_spinner.text}")
}
}

看看这几行代码,完全不见了数组适配器和选择监听器的踪影,故而代码量一下剧减到对应Java代码的三分之一。当然,为了正常地使用selector函数,不要忘了在代码文件头部加上下面一行导入语句:

import org.jetbrains.anko.selector

虽然把布局文件里面的Spinner控件换成TextView,但是二者在功能使用上是没什么区别的,同样支持点击文本弹出选择框,也同样支持选中某项的回调。改造后下拉框的界面效果如下图所示。

如此方便易用的selector,竟然撇开了数组适配器和选择监听器,那么它又是怎么实现的呢?认真阅读Anko库里面的selector源码,发现原来该函数利用了AlertDialog的setItems方法,通过setItems方法指定一串文本,并且定义了每项的点击事件,其运行结果竟然与Spinner的选择对话框殊途同归。下面给出AlertDialog对应selector函数的Java实现代码,方便读者理解它的本质:

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("请选择行星");
builder.setItems(satellites, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(SpinnerDialogActivity.this, "你选择的行星是"+starArray[arg2], Toast.LENGTH_LONG).show();
}
});
builder.create().show();

  

进度对话框
App加载网页之类的请求服务端行为,经常属于耗时操作,往往要过好几秒才能加载完毕,在此期间为了减少用户的等待焦灼感,界面需要展示正在加载的动画,一方面避免造成App卡死的错觉,另一方面提示用户耐心等待。这时就用到了进度对话框,在加载开始前弹出进度框,加载结束后关闭进度框,从而改善了加载交互的用户体验。
进度对话框分两种,一种是水平进度对话框,另一种是圆圈进度对话框,下面分别进行介绍。
水平进度对话框
水平进度对话框允许实时刷新当前进度,方便用户知晓已处理的进展百分比。它主要包含几个元素,包括消息标题、消息内容、对话框样式(水平还是圆圈)、当前进度这四种,如果使用Java代码实现该对话框,则是很常规的编码风格,具体的Java代码例子如下:

    ProgressDialog dialog = new ProgressDialog(this);
dialog.setTitle("请稍候");
dialog.setMessage("正在努力加载页面");
dialog.setMax(100);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.show();

水平进度对话框的Java编码,看起来十分中规中矩,可是仍然显得拖泥带水,很简单的功能也花费了六行Java代码。倘若使用Kotlin书写,则借助于Anko库只需下面两行代码:

    val dialog = progressDialog("正在努力加载页面", "请稍候")
dialog.show()

瞧瞧,水平进度对话框的实现代码顿时变得清爽了许多,其界面效果与Java是完全一样的。当然,因为用到了Anko库的扩展函数,所以务必在代码头部加上一行导入语句:

import org.jetbrains.anko.progressDialog

在水平进度对话框弹出之后,若想更新水平条的进度值,则可调用以下代码设置当前进度:

    dialog.progress = 进度值(取值为0到100)

当进度值达到100,意味着处理完成,此时即可调用对话框对象的dismiss函数关闭对话框,下图展示了水平进度对话框的进度变化效果。

圆圈进度对话框
圆圈进度对话框仅仅展示转圈的动画效果,不支持实时刷新处理进度,自然在编码上比水平对话框会简化一些,可是用Java来显示圆圈进度对话框,依旧需要下列的五行代码:

    ProgressDialog dialog = new ProgressDialog(this);
dialog.setTitle("请稍候");
dialog.setMessage("正在努力加载页面");
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.show();

如果用Kotlin实现该对话框的话,有了水平进度对话框的的先例,不出意料只需以下的两行Kotlin代码就行了:

    val dialog = indeterminateProgressDialog("正在努力加载页面", "请稍候")
dialog.show()

注意到上面的Kotlin函数采取了前缀indeterminate,该单词意思是“模糊的、不定的”,表示这种对话框的处理进度是不确定的,不像水平进度对话框可以明确指定当前进度,据此开发者能够将progressDialog与indeterminateProgressDialog两个函数区分开。由于该函数同样来自于Anko库,因此不要忘了在用到的代码文件头部加入下面这行语句:

import org.jetbrains.anko.indeterminateProgressDialog

Kotlin实现的圆圈进度对话框,转圈效果等同于Java实现的效果,具体的对话框界面如下图所示。

Kotlin入门(20)几种常见的对话框的更多相关文章

  1. Kotlin入门教程——目录索引

    Kotlin是谷歌官方认可的Android开发语言,Android Studio从3.0版本开始就内置了Kotlin,所以未来在App开发中Kotlin取代Java是大势所趋,就像当初Android ...

  2. 【转】javascript入门系列演示·三种弹出对话框的用法实例

    对话框有三种 1:只是提醒,不能对脚本产生任何改变: 2:一般用于确认,返回 true 或者 false ,所以可以轻松用于 if...else...判断 3: 一个带输入的对话框,可以返回用户填入的 ...

  3. javascript入门系列演示·三种弹出对话框的用法实例

    对话框有三种 1:只是提醒,不能对脚本产生任何改变: 2:一般用于确认,返回 true 或者 false ,所以可以轻松用于 if...else...判断 3: 一个带输入的对话框,可以返回用户填入的 ...

  4. 写给Android开发者的Kotlin入门

    写给Android开发者的Kotlin入门 转 https://www.jianshu.com/p/bb53cba6c8f4 Google在今年的IO大会上宣布,将Android开发的官方语言更换为K ...

  5. Kotlin 入门教程

    Kotlin 入门教程 Android / Java https://developer.android.com/kotlin?hl=zh-cn 使用 Kotlin 开发 Android 应用 使用 ...

  6. Kotlin入门第二课:集合操作

    测试项目Github地址: KotlinForJava 前文传送: Kotlin入门第一课:从对比Java开始 初次尝试用Kotlin实现Android项目 1. 介绍 作为Kotlin入门的第二课, ...

  7. Kotlin入门(32)网络接口访问

    手机上的资源毕竟有限,为了获取更丰富的信息,就得到辽阔的互联网大海上冲浪.对于App自身,也要经常与服务器交互,以便获取最新的数据显示到界面上.这个客户端与服务端之间的信息交互,基本使用HTTP协议进 ...

  8. Kotlin入门(28)Application单例化

    Application是Android的又一大组件,在App运行过程中,有且仅有一个Application对象贯穿应用的整个生命周期,所以适合在Application中保存应用运行时的全局变量.而开展 ...

  9. Kotlin入门(9)函数的基本用法

    上一篇文章介绍了Kotlin新增的空安全机制,控制语句部分可算是讲完了,接下来将连续描述Kotlin如何定义和调用函数,本篇文章先介绍函数的基本用法. 前面几篇文章介绍控制语句之时,在setOnCli ...

随机推荐

  1. Python编程语言基础

    今天给大家讲解python语言基础~~ 01.python核心数据类型   整型数 int:整数是不带有小数部分的数字 浮点型数 float:浮点数是带有小数部分的数字(小数部分可以是0) 复数 co ...

  2. 关于@font-face的使用

    以前在写网页的时候,总是使用浏览器默认的字体,因此从未使用过@font-face,然而,最近在做官网的时候,UI规定了字体,要在所有浏览器下都展现同一效果.多番查询下,发现@font-face用起来是 ...

  3. spring boot集成 servlet自动注册的两种方式

    有两种方式:(两种方式同时存在时,@Bean优先@ServletComponentScan实例化,生成两个对象) 1)通过@ServletComponentScan类注解 扫描 带有@WebServl ...

  4. web自动化测试---自动化脚本设置百度搜索每页显示条数

    前面学的都是基础知识,本篇将进入实战练习 以百度“搜索设置”为对象进行测试用例的写作: 百度的搜索设置在首页的“设置”里面,鼠标悬停之后即可显示,如下图红框位置: 测试目标是,修改每页的显示条数为50 ...

  5. ZolltyMVC配置-说明文档

    目前XML里支持的一级元素如下: <!-- 配置 -->     <xsd:element ref="mvc"/>     <xsd:element ...

  6. 移动 Ubuntu16.04 桌面左侧的启动器到屏幕底部

    与其他 Linux 发行版不同,Ubuntu 多年来一直使用 Unity 做桌面环境,该环境的最突出特点就是桌面左侧有一个启动器栏(Launcher).从 16.04 版本开始,Ubuntu 提供了一 ...

  7. Turbine——Hystrix集群监控

    上一篇文章讲述了如何利用Hystrix Dashboard去监控断路器的Hystrix command.当我们有很多个服务的时候,这就需要聚合所有服务的Hystrix Dashboard的数据了.这就 ...

  8. win32进程概念之句柄表,以及内核对象.

    句柄表跟内核对象 一丶什么是句柄表什么是内核对象. 1.句柄表的生成 我们知道.我们使用CreateProcess 的时候会返回一个进程句柄.以及线程句柄. 其实在调用CreateProcess的时候 ...

  9. sql server备份和还原

    官方文档:http://msdn.microsoft.com/zh-cn/library/ms187048%28v=sql.90%29.aspx

  10. HTML XML 介绍

    一. HTML(HyperTextMark-upLanguage)即超文本标记语言,是WWW的描述语言. 二. XML即ExtentsibleMarkup Language(可扩展标记语言), XML ...