Kotlin/DSL(Anko),原汁原味Kotlin开发Android---Activity Fragment与AnkoUI分离,强大的复用,更加便捷的开发
/写在前面
翻开自己的CSDN,已经很久很久没有活动了,最近的关于PDF签章的博客还是16年写的。将近年关,工作内容阶段性告一段落,终于有时间写一下自己的东西。
废话少说,说说Kotlin。kotlin开发者给kotlin的定位---不是用来取代任何一种语言,而是 让开发者有更多的选择,更加便捷的开发自己的产品。kotlin不是学院派语言,而是工程性质的语言,kotlin并没有带给开发者更多的新奇的技术,而是把工程实践中,开发者觉得很便捷的技术特性 集成到kotlin中。
最初没有真正在项目中用到kotlin之前,我同大部分人的看法是一致的,以为kotlin无非是java的升级,语法糖而已。后来,抱着学习语言特性的想法,学习了kotlin,并用到自己项目中之后,才发现kotlin的真正牛掰之处。基于kotlin与java的无缝互操作,到目前为止,我已经很少写java代码了。
下边,开始kotlin + DSL(Anko),给大家开发时一个新思路
给大家介绍一下kotlin + anko的强大之处,文章比较长,希望对各位开发同学有所帮助
有所谓 仁者见仁智者见智,kotlin + anko还处于成长中,不一定适合所有开发环境。
我的建议是,可以在项目中 将xml和anko结合起来。 xml和anko各有优势,并且anko可以用include包含xml,anko的优势是 动态生成和复用。 二者结合,相信可以更加便捷的开发。
本文所用的源码demo,在码云上开源,地址如下
https://gitee.com/akai_liu/AkaiKotlinWithAnko
推荐几个地址,本文不说kotlin语法基础和如何构建项目,需要这方面的可以参考如下
kotlin极简教程
kotlin官方文档中文版
《Kotlin for android developers》中文版翻译
anko github
kotlin协程github
开始
准备工作
Anko开始
1、万里之行,始于hello world
2、Anko布局与Activity分离
anko基本实现方式
使用AnkoComponent接口
3、稍微进阶,UI布局中插入代码
各位看到这里,估计心里会有嘀咕,这不是和写xml布局文件一样么,看不出来有什么差别。甚至连预览都那么麻烦。OK,这只是表面现象,下边,我们开始一步一步的揭示,anko的强大。
根据大家的经验,xml文件中只能写静态页面,如果有动态需求,就需要用java类动态生成,且不说java类写界面有多繁琐,单是与xml的交互,就没那么容易。
但是,这些事情,对于kotlin/Anko来说,易如反掌,天生支持。
上文说过,虽然anko写UI看起来类似xml中使用view标签,但是anko中其实每个‘标签’本质都是一个扩展函数,因此,在函数中写代码,绑定事件,动态生成布局,这是再正常不过的事情了,特别是anko为开发者封装了很多方便的工具。
基于上述的hello world项目,我们先来个简单的修改,给hello world绑定一个点击事件,土司一句话。如下截图
是不是很简单,这时,运行到模拟器上,textView就会有onclick事件了,弹出一个提示“我是hello world”。
同样,可以在textView 之后 直接用常规的 .setOnClicklistioner调用,不过,那样不么是显得啰嗦么。
onClick函数和 toast函数是 anko封装的扩展函数,就是为了减少开发时不必要的样板代码。
有了这个操作, 对于只执行简单操作的按钮 等控件view,点击事件 就可以顺手写在ui里。 比如只是为了跳转页面,直接在onclick中写 startActivity就好了,省去了定义id findview等很多麻烦。
4、在activity中,使用view
看了上边的介绍,大家一定有这样的疑问,我们总不能把所有的代码都写到 UI类中吧,那样太傻了。
OK,下边就看看我们怎样在activity中操作view。
先在activity中定义view,然后在AnkoComponent中实例化view,最后,activity中就可以使用view了。
上文说过,AnkoComponent重写的函数createView 的入参ui ,包含了绑定的activity/fragment的实例,基于此,我们可以如下实现
类似如下过程,
为了不进行多余的 kotlin空指针处理,这里把textView定义为懒初始化属性。
然后在AnkoComponent中实例化,最后,就可以在 绑定ui之后 使用textView了。
这样,是不是省去了大量findView操作呢?
当然,我们同样可以 在UI中指定View的Id属性,在activity中使用findView的方式来实例化。然而,我们多数时候不会这样做,因为findViewbyId是比较消耗的操作,可以直接代码实例化的话,还是尽量不用findView。
配置View的id,不一定是为了findview才配置的。还有一个作用是在activity中区分不同的view,比如在activity中统一处理点击事件。
5、再次进阶,使用自定义view
anko为我们封装好了 android原生包括support库design库用到的所有控件,能够完成我们大部分的工作。但是,很多时候我们需要自定义控件,那么,我们怎么在anko中使用自定义控件呢?
上文,有介绍framelayout源码的定义,其实,我们按照源码,就可以定义自己的anko控件了。
比如,我从网上找了一个 圆形imageview的自定义控件RoundImageView(java也好,kotlin也好,都不影响,因为kotlin与java无缝互操作),代码太长我就不贴了,可以到项目中查看。
那么,我需要怎样配置,才能在anko中使用呢?
为了方便,我单独为自定义view建一个配置用的kotlin file,叫ConfigMyView, 并仿照anko源码,定义RoundImageView的内联函数,如下截图,由于我是在AnkoComponent中使用这个函数,所以我只声明了ViewManager的扩展函数。
OK,有了这个定义后,我们就可以使用roundImageView标签了。我们稍微修改一下hello world项目,把自定义的view加进入,把原来hello world删除掉,把跟布局改为relativeLayout。先从网上下载一张png图片
然后,放到roundImageView里,看看是什么效果
好了,这样,自定义view也可以用了。
6、重点来了,复用 复杂布局,不仅仅是 复用布局。
至此,我们基本可以正常使用akno进行开发了,但是,各位看官,是不是依旧没有看出anko的优势在哪里?别急,如下,就是见证奇迹的时刻。
根据经验,很多时候,同一个项目中,同一个布局样式会在很多处都出现,为了使用方便,我们会单独为这些布局写一个xml文件,然后在不同的地方使用include 的方式引用。 anko同样支持include操作引用xml文件,来实现xml与anko的交互。
但是,anko能做的不仅仅是这样。
我们来设定一个需求,做一个类似如下形式的输入框。 输入框背景可自定义,输入框头部图标可自定义,输入框提示文字可自定义,输入框会判断输入内容正确性,正确显示对号,错误显示红叉,输入时 显示灰色叉子,点击灰色叉子可以删除输入框内容。
然后,在项目中,这种类型的输入框,有好多个,那么怎么办?
我们想想这个要怎么实现,如果使用传统的xml方式, 我们可以单独写一个输入框布局,然后在每次include后,在activity中一个一个findview,然后设置对应控件的属性,例如头部图标图片,对号叉子图片,输入框提示内容,并且要指定输入框各个事件,让对号红叉可以正常显示 等等等。
上述过程,光想想都够酸爽,如果 项目中多处用到,呵呵。。。
当然,如果您是大拿,说直接自定义view实现,那我拜服。
ok,来看看使用kotlin anko可以怎样实现?
①准备资源
然后再下载3个图标 对号 ,红叉子,灰色叉子 作为 输入框尾部的图标
② anko书写布局,并绑定事件
下边,我们根据需求,分析对应的输入框布局。
最外层linearlayout水平布局,头部放一个imageview,中间放个edittext,尾部 framelayout 中放3个imageview,OK,其实布局结构很简单,我们在MyInputEdit中添加一个函数getInputEdit(),用来生成这样的布局,入参viewManager。
接下来,就是分析事件绑定了,我们简单的实现一下。
1、edittext失去焦点时,判断 输入正确 错误,如果没有输入,则什么都不显示
2、在文本编辑时,显示 灰色叉子,一键清空输入内容
因此,edit需要绑定 onFocusChangeListener 和 textChangedListener
尾部删除imageView需要绑定点击事件
为了方便控制 尾部3个imageview的显示,我们增加一个函数来控制showInputCheckIcon
ok,让我们先来看 edit的onFocusChangeListener中的逻辑
再看看textChangeedListener中的逻辑
删除按钮的点击事件很简单,点击后 清空 edittext就行了
ok,完整的 函数代码,可以到 项目中查看,太长,就不贴了
除此之外,我们再增加一个获取输入内容的函数,方便后续使用
OK,至此,MyInputEdit类基本完成,整体如下
③AnkoComponent UI类中使用MyInputEdit类
ok,我们再来一个 密码输入框,同样的方式,但因为是密码,我们需要多传一个参数,输入类型
运行后,如下效果
基于此,一般连同 注册页面, 登陆页面, 忘记密码页面,修改密码页面,我们可能需要很多个类似的输入框,使用kotlin anko,可以轻松的把实现 复杂的 输入框需求,并且不需要自定义view。
看到这里,您是不是开始有些明白anko的强大之处了呢?
7、继续进阶,使用函数来定义各种类型的布局复用,不仅仅是布局
我们来看看另外一种,实现布局复用的方式-----直接定义布局函数
第6节中,因为 子布局有很多事件需要处理,所以,我们直接建一个类来方便事件绑定
然而,对于一般没有很多事件处理的 复用布局,我们可以直接定义函数来进行复用。
比如这样的需求,我们项目中可能有 很多类似如下的 动作条 ,有时带有头部图标,优势带有尾部图标
并且有的还可以显示用户内容,用户内容可能是图片或者文字,文字有可能要经过特殊处理(如截图中手机号不完全显示),动作条本身又有点击事件。
基于此,我们定义一个类似如下的内联函数, 入参根据需求,暂时定如下这几个
结束语
Kotlin/DSL(Anko),原汁原味Kotlin开发Android---Activity Fragment与AnkoUI分离,强大的复用,更加便捷的开发相关推荐
- android 美颜相机开发,Android OpenGL ES从入门到进阶(一)—— 五分钟开发一款美颜相机...
源码链接:https://github.com/smzhldr/AGLFramework 一.前言 商店里有数十款的美颜相机类产品,以及像抖音,唱吧之类带有视频的软件,功能很强大,其实现原理基本上都是 ...
- android activity fragment 销毁,activity被销毁而fragment未被销毁视图残留的处理方法
环境描述:java7+android studio2.2+sdk14 背景描述:目前主流的应用主页一般是一个MainActivity托管几个fragment.我的主页MainActivity继承自Fr ...
- Android Activity/Fragment间的数据传递
Activity间的数据传递 举例:MainActivity是已经打开的Activity,在这个界面打开第二个Activity,SecondActivtiy,如果是直接通过startActivity( ...
- 像 Compose 那样写代码 :Kotlin DSL 原理与实战
1. 前言 Kotlin 是一门对 DSL 友好的语言,它的许多语法特性有助于 DSL 的打造,提升特定场景下代码的可读性和安全性.本文将带你了解 Kotlin DSL 的一般实现步骤,以及如何通过 ...
- Kotlin DSL 实战
1. 前言 Kotlin 是一门对 DSL 友好的语言,它的许多语法特性有助于 DSL 的打造,提升特定场景下代码的可读性和安全性.本文将带你了解 Kotlin DSL 的一般实现步骤,以及如何通过 ...
- 使用phoneGap和Sencha Touch 2开发Android应用程序(四)
2019独角兽企业重金招聘Python工程师标准>>> 本文是" 使用phoneGap和Sencha Touch 2开发Android应用程序"系列教程的第4章, ...
- 用HTML5/CSS3/JS开发Android/IOS应用
现在人人都想成为安卓/IOS应用开发工程师.其实,安卓/IOS应用可以用很多种语言来实现.由于我们前端开发工程师,对HTML5/CSS/JavaScript的网络编程已经相当熟悉了.所以,今天大家将会 ...
- 【26】Android - 初识Fragment
目录 目录 前言 相关库包 简单使用 静态加载 动态添加 Fragment 与Activity 通讯 组件获取 消息传递 生命周期 基本状态 回调 测试 进阶使用 如何在 Fragment 中增加 M ...
- 《Kotin 极简教程》第13章 使用 Kotlin 和 Anko 的Android 开发
第13章 使用 Kotlin 和 Anko 的Android 开发 最新上架!!!< Kotlin极简教程> 陈光剑 (机械工业出版社) 可直接打开京东,淘宝,当当===> 搜索: ...
最新文章
- Shell脚本经典之Fork炸弹
- sublime text3
- 网页底部的版权信息_Shopify底部的版权信息(Powered by Shopify )如何删除
- 集合添加元素python_Python 集合(Set)
- LeetCode 497. 非重叠矩形中的随机点(前缀和+二分查找)
- sqlserver的for xml path和mysql的group_concat的区别
- Spark算子:RDD键值转换操作(5)–leftOuterJoin、rightOuterJoin、subtractByKey
- 跟着百度学PHP[3]-PHP中结构嵌套之循环结构与条件结构嵌套
- mac安装win7之后鼠标失灵_苹果电脑安装win7时键盘鼠标无响应3种解决方案
- 《软件工程之美》打卡第六周
- Java 相关知识的学习(第一章至第三章)
- win10系统 Windows 资源保护找到了损坏文件 无法修复的有效解决方法
- Win7网络和共享中心 依赖服务或组无法启动 解决办法
- 工作组和域的概念及辨析
- Scrapy中的item和pipline
- php think-queue队列的安装使用和Supervisor的安装配置和使用
- 零基础Unreal Engine 4(UE4)图文笔记之准备篇(一)
- UE4-蓝图-角色的移动,视角控制(四)人物瞄准偏移(视角自由转动)
- 奥克兰大学计算机科学硕士,奥克兰大学计算机硕士解析
- 内存、ram、 rom、 norflash,nandflash详细区别
热门文章
- opencv warpAffine()函数详解 -- 图像旋转与平移
- css firefox火狐浏览器下的兼容性问题
- Libuv源码解析 - uv_loop整个初始化模块
- 什么是知识图谱(Knowledge Graph)(上)
- 基于ndis protocol driver 后门 分析
- nvme固态硬盘开机慢_6个固态硬盘优化设置技巧 让你的SSD速度飞起来 (全文)
- 大学计算机基础导论备考
- 【5G RLC】AM模式的数据传输详解
- sqlserver2008 R2数据库-不允许表修改保存,阻止保存要求重新创建表的更改
- LaTex支持中文的三种方式