趁今晚老大不在偷偷早下班,因此有时间继续跟大伙扯扯UI设计之痛,也算一个是对上篇《Android:一个高效的UI才是一个拉风的UI(一)》的完整补充吧。写得很差的话你们尽管拍砖~(来!砸死我把~)html
前言android
前篇博客翻箱倒柜的介绍了优化UI设计的两个方法,第一个就是使用尽可能少的组件来实现布局功能,第二个就是使用<merge>标签来减小没必要要的根节点,这两个方法均可以提升应用UI的运行效率,可是够了吗?远远是不够的,方法就像money同样永远不嫌多,因此再也不介绍多一些UI设计优化的方法说得过去么?缓存
摸摸口袋里面的都快四岁、运行着古老的android 2.2系统的屌丝机对于我来讲,随便一个大于10M的应用都有完爆他几条街死机崩溃的超能力。可是对于某信来讲,现在已经24M大小的它依然在屌丝机濒临垂死的硬件资源上运行如飞(至少没崩溃过),让我不得不感叹应用优化作的至关不错,也知足咱们这种屌丝在深深的寂寞夜晚来摇一发的情感需求。因此来讲,一个应用能赢得市场,不只仅是赢得先机,而更多的是由于相同需求它功能作的比你好,相同功能它比你的简约,相同简约设计它运行比你快!app
----------------------------------我是分割线---------------------------------天王盖地虎-------------------------------------------------------------less
排队,一个一个慢慢来ide
当ActivityA跟ActivityB打招呼说:“偶要回家了,你来顶上”。说明就立刻溜得无影无踪,这时候急呀,ActivityB赶忙measure呀、layout呀、draw呀赶忙搞出一个界面来应付观众先,忙的不亦乐乎;更要命这时候的是他们还要搞一个交接仪式——超炫超牛的切换动画!然而在日益无穷大的欲望与逐渐干瘪的资源这强大的根本矛盾下,坚决果断的当机了几百毫秒。这一卡顿让手机前的强迫症患者来讲是多大的心理创伤,天然而然会说:“这软件真渣!切个画面都会总得顿一下才死心”。用户体验瞬间降为0~模块化
解决方案有哪些?固然很简单的就是,取消牛逼哄哄的切换动画咯,可是若是你的产品经理死活不一样意那还不得另寻途径。在不放弃动画的前提下,咱们能够把某些measure呀、layout呀、draw呀的步骤延迟在动画后面执行不就行咯,排队一个一个来,至于怎么操做呢?那咱们要引入一个轻量级组件<ViewStub>,也就是动态加载的方法。工具
咱们一般使用它来作预加载处理,来改善页面加载速度和提升流畅性,ViewStub自己不会占用层级,它最终会被它指定的层级取代。有时候咱们也须要复杂的视图且少用,咱们能够按须要的时候装载以便减小内存,提升体验。之前咱们都是设置在布局中,而后使用View.GONE属性来隐藏组件,可是耗资源影响性能。总得来讲这玩意就是一个轻量级的View,它一个看不见的,不占布局位置,占用资源很是小的控件。布局
下面上代码:post
要加载的ActivityB布局(复杂的动画代码请忽略)
<merge xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ViewStub android:id="@+id/mystub" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageView android:id="@+id/loading_image" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/loading_image" /> </merge>
在这个UI界面中,当咱们切换ActivityB时,由于兼顾到动画效果。因此咱们就让ViewStub暂缓加载比较复杂的布局,而先把较为简单的显示加载画面loading_image加载出来,当稍后时间咱们就在代码里面开始加载该布局,见代码以下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_loading); LoadHandler = new Handler(); myStub = (ViewStub)findViewById(R.id.mystub); loadingView = (ImageView)findViewById(R.id.loading_image); myStub.setLayoutResource(R.layout.layout_main);//设置加载资源 LoadHandler.postDelayed(new Runnable() { @Override public void run() { myStub.inflate();//开始加载复杂界面 loadingView.setVisibility(View.GONE);//隐藏临时加载的简单界面 } },500);
上面代码实现了先执行复杂动画,当切换界面到到500ms时,handler开始执行加载复杂的界面子线程,从而错开了资源的集中利用,这里使用的是动态添加ViewStub指向布局资源的方法,简单而实用吧,对于一个用户来讲,延迟半秒加载界面远远比切换画面卡顿更容易接受。
使用ViewStub须要主要几点:
一、ViewStub只能被Inflate一次,当Inflate以后ViewStub对象就被置为空值,说得更通俗点就是当ViewStub被某个布局Inflate后,就不能经过ViewStub来控制它,由于它已经功成身退了,天然对于须要不一样场景下显示隐藏的状况建议用visibility。
二、ViewStub只能用来Inflate一个布局文件,对于单个具体的View它是无能为力的,固然若是把View搞在某个布局文件中也是能够接受的。
三、VIewStub中不能嵌套merge标签。
重用布局是一个好习惯
重用是一个好习惯,既然你们都常念叨,无图无真相呀楼主,为了不你们说no picture you say a jb~这类回复,我仍是勉勉强强上个图吧。
这个界面由三个小部分组成,分别是标题栏、内容显示和底端按钮。若是你手指闲不住前先后后点一点,按一按;会发觉各个界面的风格惊人的类似!并且不只仅是在这软件上会体现,并且市场上大部分应用都是这样!其实说白了这就是一个风格的问题。
那么,既然这么多重复了,做为二十一世纪标准码农的咱们来讲,咱们能忍受这种浪费吗?因此咱们要用用<include>标签——模块化布局。
布局以下:多简单的layout复用,你还会说你不喜欢用<include>标签吗?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <include android:id="@+id/head_menu" layout="@layout/head_menu" /> <include android:id="@+id/content" layout="@layout/content_showweibo" /> <include android:id="@+id/bottom_menu" layout="@layout/bottom_menu" /> </LinearLayout>
使用<include>的好处有:
一、模块化布局,提升重用率,易于往后的维护和扩展。
二、下降生成的app的体重,用户的流量是很贵的!
简单说说剩下的点
一、减小没必要要的inflate
(1)对于inflate的布局能够直接缓存,用所有变量代替局部变量,避免下次需再次inflate
if (loadingView != null) { loadingView.setVisibility(View.VISIBLE); } else{ loadingView =LayoutInflater.from(context).inflate(R.layout.loadingView, this, true); }
(2)BaseAdapter中item的convertView缓存用法,详细请参考《关于BaseAdapter的使用及优化心得》
PS:第一次写的博文,写的渣得不能看。。。。。。
二、避免有太多的视图
每一个视图都会消耗内存,在一个布局中布置太多的视图,布局会占用过多的内存,假设一个布局包含超过80个视图,layoutopt可能会给出下面这样的建议:
-1:-1 This layout has too many views: 83 views, it should have <= 80!
上面给出的建议是视图数量不能超过80,固然最新的设备有可能可以支持这么多视图,但若是真的出现性能不佳的状况,最好采纳这个建议。
三、千万别布局嵌套太多
布局不该该有太多的嵌套,layoutopt(和Android团队)建议布局保持在10级之内,即便是最大的平板电脑屏幕,布局也不该该超过10级,RelativeLayout多是一个解决办法,但它的用法更复杂,好在Eclipse中的Graphical Layout资源工具更新后,使得这一切变得更简单。
下面是布局嵌套太多时,layoutopt的输出内容:
-1:-1 This layout has too many nested layouts: 12 levels, it should have <= 10! 305:318 This LinearLayout layout or its RelativeLayout parent is possibly useless
嵌套布局警告一般伴随有一些无用布局的警告,有助于找出哪些布局能够移除,避免屏幕布局所有从新设计。
四、在某些场景下使用非主线程绘制的UI组件,具体组件名称我忘了,后面想起来补上哈。
做者:enjoy风铃
出处:http://www.cnblogs.com/net168/
本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然下次不给你转载了。