用过 Sketch 的朋友应该都知道一个叫 Mirror 的功能,它可以将你的设计稿放到手机上预览,为设计师们提高了不少效率。而今天我要介绍的 jimu Mirror ,和 Sketch Mirror 类似,可以将 Android 的 xml 实时放到手机上预览。但是现代化的 IDE 都已经提供在 IDE 内实时预览 xml 的功能,**jimu Mirror** 有啥用呢?
有用!还是相当有用! 本文将以微信的界面作为参考,在不写一句 Java 代码的情况下,轻松实现微信的几个界面。
安装 jimu Mirror
jimu Mirror 支持 Android Studio / IDEA,本文将以 Android Studio 作为开发环境,读者请自行下载对应版本。
将插件下载下来后,在 Android Studio 菜单进行简单操作,即可安装。
Configure -> Plugins -> install plugin from disk
没什么意外的话,你应该就能看见 Mirror 的小图标了。:)
配置 jimu Mirror
如果你使用的是 Android Studio,恭喜你,你什么都不用做,把手机接上电脑就可以了!如果你是其它 IDE,请查看官方文档。
基本操作
首先,将 Android Studio 的 Project 面板从 Android 切换到 Project,这样我们就能观察所有文件的变化;
再通过菜单,将 Mirror 的 Console 打开,这样我们就能观察 Mirror 的运行情况;
最后点一下「Start/Stop Mirror」的小图标,把 Mirror 跑起来,如无意外,Project 下会生成一个 app/mirror 的目录,同时你的手机应该会跑起 jimu Mirror 的主程序。
编写「聊天」列表界面
先新建两个 layout,一个放 ListView 一个放 ListView Item。
- fragemnt_messages.xml
- list_item_message.xml
往 fragment_messages.xml 增加一个 ListView,代码大概如下:
<LinearLayout> <ListView ... android:id="@+id/listView"/> </LinearLayout>
然后往 list_item_message.xml 添加所需要的控件,例如放置头像的 ImageView,放置昵称的 TextView。
<LinearLayout> <ImageView ... android:id="@+id/avatar"/> <TextView ... android:id="@+id/name"/> <TextView ... android:id="@+id/content"/> <TextView ... android:id="@+id/time"/> </LinearLayout>
按下「保存」按钮,可以看到在 Mirror 的 Console 里有新的输出,它为刚才修改的文件生成了新的 mirror 数据文件。
Mirror XML 简介
打开 app/mirror 下的 list_item_message.xml,可以看到如下 XML 代码:
<screen> <_content layout="@layout/list_item_message"> <!-- ImageView Examples: <avatar src="@drawable/image_resource" /> <avatar src="relative_path/image.jpg" /> --> <avatar /> <!-- TextView Examples: <name text="@string/string_resource" /> <name text="Text literal" textSize="14sp" /> --> <name /> <content /> <time /> </_content> </screen>
我们在 layout 中 ID 为 avatar 的 ImageView,在 Mirror 的数据文件里被 <avatar/>
闭合所定义,我们可以在闭合内设置 avatar 的属性,例如我要给它设置个 src:
<avatar src="@drawable/image_resource" />
实现聊天列表界面
上面简单地说明了下 Mirror XML,但是我们的目标是编写一个列表,然不是一个 Item,所以要实现聊天列表,真正要修改的是 app/mirror/fragment_messages.xml。
打开 app/mirror/fragment_messages.xml,可以看到类似结构。
<screen> <_content layout="@layout/fragment_messages"> <listView> </listView> </_content> </screen>
要往 ID 为 listView 的 ListView 添加数据,往闭合内放 items 即可;
<items layout="list_item_message"> <_item> <avatar src="@drawable/avatar_special"/> <name text="Special"/> <content text="[图片]"/> <time text="晚上 11:59"/> </_item> <_item> .... </_item> ... </items>
小 Tips: 这里的测试数据,例如 drawable,可以放到 app/mirror/res 下,这样可以实现测试数据与正式代码分离,非常优雅!
其中我们在最外层的 items 声明了渲染的 layout 为 list_item_message,子 _item 也支持定义它自己的 layout,例如在聊天列表里,有服务号、订阅号的记录,它们的样式可能与其它不同。
<items layout="list_item_message"> <_item layout="list_item_message_special"/> <_item count="5"/> </items>
另外,通过设置 count 属性可以实现添加重复的 item。
聊天列表效果
添加好各种模拟数据后,保存好所有文件,回到手机上,在 jimu Mirror 的界面列表选择 fragment_messages
。
编写主界面
目前 jimu Mirror 暂时只支持 Actionbar Tab 去切换 Fragments,所以主界面先用 Actionbar Tab 吧。
新建 layout activity_main.xml,往里添加一个 ViewPager:
<LinearLayout> <android.support.v4.view.ViewPager android:id="@+id/pager" /> </LinearLayout>
<screen> <actionbar title="微信" showTabsFor="@id/pager"/> <_content layout="@layout/activity_main"> <pager> <_page title="聊天" layout="fragment_messages"> <listView> <items> .... </items> </listView> </_page> <_page title="发现" layout="fragment_discovery"> <listView> <items> .... </items> </listView> </_page> <_page title="通讯录" layout="fragment_contacts"/> </pager> </_content> </screen>
<items></items>
内就是把上面**编写「聊天列表」**的 items 往里堆,当然这样很不 DRY。我们可以把**items**抽离出一个 XML,再把它们 include 进去。
<!--- File name: messages.xml ---> <items layout="list_item_message"> <_item> <avatar/> <name/> <content/> <time/> </_item> .... </items> <!--- File name: activity_main.xml ---> ... <_page title="聊天" layout="fragment_messages"> <listView> <items include="messages.xml"/> </listView> </_page> ...
效果
在 jimu Mirror 的 layout 列表里选择 activity_main,哈哈,还挺像嘛!
结语
这几年 Android 相关的开发工具都在飞速进步,前几年我们还在挣扎 ADT,现在一个 Android Studio 妥妥的,再配个 Genymotion,谁还想念那自带模拟器呢?
这个插件虽算不上革命之举,但从效率上,无疑提高了界面开发速度,如果团队里还有屌炸天懂 XML 规范的设计师,相当部分的前端工作可以托付给他了。
最后,**相关资源**附上本文项目代码。
相关资源
- MirrorWechat: 本文示范代码,使用 jimu Mirror 模仿微信界面。
- MirrorTutorial: 官方的说明文档