上一篇博文介绍了两种优化UI设计的方法。首先是使用尽可能少的组件来实现布局功能。二是使用标签减少不必要的根节点。这两种方式都可以提高应用程序UI的运行效率,但是这就够了吗?远远不够。就像金钱一样,方法永远不会嫌多,那么不引入更多的UI设计优化方法是否合理呢?摸摸兜里那台用了四年的老屌手机,运行着古老的android2.2系统,对我来说,任何大于10M的应用程序都有死机死机好几个街区的超强威力。但是对于某个字母来说,现在已经是24M大小了,在屌丝机器快要死的硬件资源上依然跑的飞快(至少没有死机)。不得不感叹应用优化还是挺不错的,也满足了我们的需求。屌丝的情感需要在寂寞的深夜里摇一摇。所以,一个APP能赢得市场,不仅仅是因为它有机会,而是因为同样的需求,它的功能更好,同样的功能比你的简单,同样简单的设计比你的更快!排队,当ActivityA跟ActivityB打招呼说:“我要回家了,你到最上面来”的时候,一个个慢慢排。解释顿时消失得无影无踪。这个时候,是当务之急。ActivityB赶紧测量、布局、快速绘制,创建一个界面来应对观众。他们非常忙;即将举行交接仪式——超级酷炫的切换动画!然而,在日益无限的欲望和逐渐枯竭的资源之间强烈而根本的矛盾之下,机器毫不犹豫地死机了几百毫秒。这种卡顿对手机前的强迫症患者来说是一种心理创伤,他们自然会说:“这软件真渣!切图总是要暂停一下再放弃。”用户体验瞬间降为0~有什么解决办法?当然,取消牛逼的切换动画很简单,但是如果你的产品经理不同意,你就得另辟蹊径了。在不放弃动画的前提下,我们可以把一些measure、layout、draw步骤延迟到动画之后执行,一个一个排队。至于如何操作?那么我们需要引入一个轻量级组件,也就是动态加载的方式。我们通常使用它来进行预加载,以提高页面加载速度和流畅度。ViewStub本身不占一个层级,最终会被它指定的层级所取代。有时我们还需要很少使用的复杂视图。我们可以根据需要加载它们以减少内存并改善体验。我们以前是在布局中设置,然后使用View.GONE属性隐藏组件,但是资源消耗影响性能。总的来说,这个东西是一个轻量级的View,是一个不占用布局位置,占用资源非常小的隐形控件。如下代码:ActivityB要加载的布局(复杂的动画代码请忽略)"match_parent">在这个UI界面中,当我们切换ActivityB的时候,因为有动画效果。所以我们让ViewStub暂停加载比较复杂的布局,先加载比较简单的显示加载画面loading_image,后面我们在代码中开始加载布局,看代码如下:@OverrideprotectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.layout_loading); LoadHandler=newHandler(); myStub=(ViewStub)findViewById(R.id.mystub); loadingView=(ImageView)findViewById(R.id.loading_image); myStub.setLayoutResource(R.layout.layout_main);//设置加载资源 LoadHandler.postDelayed(newRunnable(){ @Override publicvoidrun(){ myStub.inflate();//开始加载复杂界面 loadingView.setVisibility(View.GONE);//隐藏临时加载的简单界面 } },500);上面的代码先实现了复杂的动画。当切换界面达到500ms时,handler开始执行并加载复杂的界面子线程,从而错开资源的集中利用。这里使用了动态添加ViewStub指向布局资源的方法,简单实用,对于一个用户来说,延迟加载界面半秒远比切换画面卡顿更容易接受。使用ViewStub有几个要点:1.ViewStub只能充气一次。Inflate之后,ViewStub对象被设置为空值。更简单的说,当ViewStub被某个布局inflate时,是无法通过ViewStub来控制的,因为已经退役了,对于需要在不同场景下显示和隐藏的情况,自然推荐使用visibility。2、ViewStub只能用来inflate一个布局文件,对单个具体的View无能为力。当然,将View放在某个布局文件中也是可以接受的。3.合并标签不能嵌套在VIewStub中。重用布局是一个好习惯。重复使用是一个好习惯。由于大家常说“无图无真相”。为了避免回复无图之类的你说个jb~,我就勉强上传了一张图片。这个界面由三个小部分组成,分别是标题栏、内容显示和底部按钮。如果你的手指不能休息,来回点击,然后按下;你会发现每个界面的风格都惊人的相似!并且不仅体现在这款软件上,还体现在市面上的大部分应用中!其实说白了,这是风格的问题。那么,既然有这么多的重复,作为21世纪的标准码农,我们能承受这种浪费吗?所以我们将使用标签——一种模块化布局。布局如下:布局复用有多简单,你还说你不喜欢用标签?使用的好处是:1、模块化布局,提高复用率,便于日后维护和扩展。2.降低生成app的权重,用户流量很贵!简单说一下剩下的几点1.减少不必要的inflate(1)inflate的layout可以直接缓存,所有的变量都可以代替局部变量,避免下次需要再次inflateif(loadingView!=null){loadingView.setVisibility(View.VISIBLE);}else{loadingView=LayoutInflater.from(context).inflate(R.layout.loadingView,this,true);(2)ConvertView在BaseAdapter中item的缓存使用,请参考《关于BaseAdapter的使用及优化心得》PS详解:**第一次写的博文,太渣了,看不懂。.....2.避免有太多观点。每个视图都会消耗内存。如果在一个布局中安排了太多视图,布局将占用太多内存。假设一个布局包含超过80个视图,layoutopt可能会给出以下建议:-1:-1Thislayouthastoomanyviews:83views,它应该有<=80!上面给出的建议是浏览量不要超过80,当然最新的设备可能能支持这么多浏览量,但是如果真的出现性能不佳的情况下,***采纳这个建议。3.不要嵌套过多的布局。布局不应该有太多的嵌套。Layoutopt(和Android团队)建议将布局保持在10层以内。即使是最好的平板电脑屏幕,布局也不应超过10层。Level,RelativeLayout可能是一个解决方案,但是它的使用比较复杂,但是Eclipse中的GraphicalLayout资源工具已经更新,使它变得更容易。下面是嵌套布局过多时layoutopt的输出:-1:-1Thislayouthastoanynestedlayouts:12levels,itshouldhave<=10!305:318ThisLinearLayoutlayoutoritsRelativeLayoutparentispossiblyuseless嵌套布局警告通常伴随着无用布局的警告,有助于找出哪些布局可以删除以避免完全重新设计屏幕布局。4、在某些场景下,会用到非主线程绘制的UI组件。具体的组件名称忘记了,后面补上。