Kotlin入门(20)几种常见的对话框

提醒对话框
手机上的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实现的效果,具体的对话框界面如下图所示。

原文地址:https://www.cnblogs.com/aqi00/p/9716207.html

时间: 2024-11-14 02:28:34

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

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

<%@LANGUAGE="JAVASCRIPT" CODEPAGE="936"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/

selenium自动化实施中对windows弹出框的几种常见处理方案

一.概述 在使用自动化框架selenium实施中,经常会遇到windows弹出框的出现,刚入门的web自动化测试小伙伴不要慌哦! 二.几种常见的处理windows弹出框的方案 2.1 Selenium 处理安全对话框 (windows security dialog)用autoit 来代替 2.1.1 安装autoit-v3-setup.exe 2.1.2 将AutoitX3.dll和jcob.1.18-M2-x86.dll放到C:\windows\System32路径下:如果是64位系统,需把

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

手机上的资源毕竟有限,为了获取更丰富的信息,就得到辽阔的互联网大海上冲浪.对于App自身,也要经常与服务器交互,以便获取最新的数据显示到界面上.这个客户端与服务端之间的信息交互,基本使用HTTP协议进行通信,即App访问服务器的HTTP接口来传输数据.HTTP接口调用在Java代码中可不是一个轻松的活,开发者若用最基础的HttpURLConnection来编码的话,至少要考虑以下场景的处理:1.HTTP的请求方式是什么,是GET还是POST还是PUT还是DELETE?2.HTTP的连接超时时间是

java几种常见的排序算法总结

[java] view plain copy /*************几种常见的排序算法总结***************************/ package paixu; public class PaiXu { final int MAX=20; int num[]=new int[MAX]; { System.out.print("生成的随机数组是:"); for(int i=0;i<20;i++){ num[i]=(int)(Math.random()*100)

Android基础入门教程——2.5.3 AlertDialog(对话框)详解

Android基础入门教程--2.5.3 AlertDialog(对话框)详解 标签(空格分隔): Android基础入门教程 本节引言: 本节继续给大家带来是显示提示信息的第三个控件AlertDialog(对话框),同时它也是其他 Dialog的的父类!比如ProgressDialog,TimePickerDialog等,而AlertDialog的父类是:Dialog! 另外,不像前面学习的Toast和Notification,AlertDialog并不能直接new出来,如果你打开 Alert

[转]6种常见的数据加载模式设计

原文链接:http://elya.cc/2014/03/31/loading/ 设计师在进行APP设计的设计时,往往会更加专注于界面长什么样,界面和界面之间怎么跳转,给予用户什么样的操作反馈,却偏偏特别容易忽略掉一个比较重要的环节,就是APP数据加载中的设计,所以会导致我们看到的APP,往往有着华丽的启动界面,然后就是漫长的数据加载等待,甚至在无网络的时候,整个处于不可用状态.那么我们怎么处理好界面交互中的加载设计,保证体验无缝衔接,保证用户没有漫长的等待感,而可以轻松自在的享受等待,对加载后的

C# 实现AOP 的几种常见方式

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的中统一处理业务逻辑的一种技术,比较常见的场景是:日志记录,错误捕获.性能监控等 AOP的本质是通过代理对象来间接执行真实对象,在代理类中往往会添加装饰一些额外的业务代码,比如如下代码: class RealA { public virtual string Pro { get; set; } public virtual void ShowHello(string

几种常见SQL分页方式效率比较-转

原文地址:几种常见SQL分页方式效率比较 分页很重要,面试会遇到.不妨再回顾总结一下. 1.创建测试环境,(插入100万条数据大概耗时5分钟). create database DBTestuse DBTest --创建测试表create table pagetest(id int identity(1,1) not null,col01 int null,col02 nvarchar(50) null,col03 datetime null) --1万记录集declare @i intset

Java几种常见的编码方式

Java综合 几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解的符号的,这些符号也就是我们人类使用的语言.由于人类的语言有太多,因而表示这些语言的符号太多,无法用计算机中一个基本的存储单元—— byte 来表示,因而必须要经过拆分或一些翻译工作,才能让计算机能理解.我们可以把计算机能够理解的语言假定为英语,其它语言要能够在计算机中使用必须经过一次翻译,把它翻译成英语.这个翻译的过程就是编