本篇文章被重新写了一遍,基本上一篇文章写完后,过20天后,就发现以前的观点站不住脚了。
scaloid强大的表现力
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dip"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Sign in" android:layout_marginBottom="25dip" android:textSize="24.5sp"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="ID"/> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/userId"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Password"/> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/password" android:inputType="textPassword"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/signin" android:text="Sign in"/> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:text="Help" android:id="@+id/help" android:layout_width="match_parent" android:layout_height="wrap_content"/> <Button android:text="Sign up" android:id="@+id/signup" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
is reduced to
new SVerticalLayout { STextView("Sign in").textSize(24.5 sp).<<.marginBottom(25 dip).>> STextView("ID") SEditText() STextView("Password") SEditText() inputType TEXT_PASSWORD SButton("Sign in") this += new SLinearLayout { SButton("Help") SButton("Sign up") } }.padding(20 dip)
以上摘自scaloid github主页,是不是被其简洁性打动了呢,不管你有没有,至少我是心动的不行了。于是乎,这几天将 《疯狂android讲义》前面关于UI组件讲解的几个重点例子,用scaloid翻译了一遍。然后,现实告诉我们,简洁是有代价的...
class clazzName extends SActivity{activity=> lazy val comp1= new SUIComponent().styles//... lazy val comp2= new SUIComponent().styles//... onCreate{ contentView = new SUILayout{ this+=com1.<<.layoutStyles.>> this+=com1.<<.layoutStyles.>> } comp1.onClick{(_:android.widget.AdapterView[_], _:android.view.View,position: Int, _:Long)=> //todo } } }
这基本就是我关于UI初始化的标准模版了(你也可以将lazy val
换成var
)。至于为什么不将layoutStyles
写在声明后面,则是由于scaloid关于UI组件的实现都是继承与原生android api,并使用了的隐式转换(implicit context:Context) 来简化代码量。而渲染效率呢,则和用xml写布局的没什么区别。
这时,便出现了第一个问题:到底使用xml写view还是说用代码写view?
虽然最近一直在用代码写view,熟悉id,在实际生产环境下,我更倾向于使用后者,原因如下:
java和scala之间切换更容易
scala编译速度真的很慢
可以直接通过可视化工具生成xml(据我了解,有不少android程序员都是通过拖拽来实现布局的)
减少progurd配置
当你要开发view组件时,最好参照scaloid已经写好的组件。例如你要实现一个View,最好时继承scaloid的 TraitView,这样你才能拥有一些简便的api。还有一些构造函数等问题,基本上照着scaloid源码来,基本上没啥大问题。
scaloid的网络资源真心不丰富,github上的readme+官方blog几乎就是所有资料了。很多api都没有覆盖到,基本上你要用到哪里,就要去扒一下源码才可以。我在里碰到的问题呢,是说,一些java原生api(例如 SimpleArrayAdapter)是不支持scala集合的?
这里的解决方案:
集合等api全部使用java原生的
使用scala集合,然后进行类型转换
摒弃掉java原生api,使用scaloid提供的或者自己封装
以上方案,用第一种,就真心没必要使用scala语言了,直接java写会更省劲;第二种,最好自己封装一些隐式转换加快开发;第三种,初期比较痛苦,得查scaloid api以及看源码,才能掌握好用法,往后发展的话,还是蛮ok的。
貌似只要和scala占上边的就没有什么是简单的,不管是scala的类型系统还是sbt build工具,每一个都需要花大量的时间来入门。当scala与android结合时,更是如此。
当你用scala开发android正爽的时候,突然发现编译报 classNotFound 的错误,而产生这个问题根源则是proguard剪切代码带来的,如果你懒的解决这个问题呢,可以直接sbt 运行 clean android:run 指令。如果要想好好的解决这个问题呢,推荐看看douban-android项目的以proguard开头的两个配置文件。
除了view组件的api进行简化外,还对log,ui更新等做了简化,简化后,用起来真心舒适,github上关于简化的讲解,基本能让你上手使用。代码量有大幅的减少。
与其说是小坑,倒不如说时对api的掌握程度不够造成的。将小坑记录在这里
//颜色转换 new ColorDrawable(Color.parseColor("#F00000")) //动画效果 AnimationUtils.loadAnimation(context,android.R.anim.fade_out)
还有一些是java和scala混用带来的一些问题,这里就不做赘述了,如果真想用scala做开发的话,就尽量减少直接调用原生java api的机会。还有就是scala开发和java开发还是有很多细节上的不同,一些思维上还是要做一些转变的,现在用scaloid写的开源的android真心少,开发技巧更多还是从一些后台代码中学习吧。
总的来讲,除了一贯的编译速度慢以外,用scala开发android,对源码的阅读和学习能力要求还是蛮高的,如果没有真正的需求或者能跟得上技术的团队的话,还是用java开发好一点,简单即效率。