趁今晚老大不在偷偷早下班,所以有时间继续跟大伙扯扯UI设计之痛,也算一个是对上篇《Android:一个高效的UI才是一个拉风的UI(一)》的完整补充吧。写得不好的话大家尽管拍砖~(来!砸死我把~)

前言

  前篇博客翻箱倒柜的介绍了优化UI设计的两个方法,第一个就是使用尽量少的组件来实现布局功能,第二个就是使用<merge>标签来减少不必要的根节点,这两个方法都可以提高应用UI的运行效率,但是够了吗?远远是不够的,方法就像money一样永远不嫌多,所以不再介绍多一些UI设计优化的方法说得过去么?

  摸摸口袋里面的都快四岁、运行着古老的android 2.2系统的屌丝机对于我来说,随便一个大于10M的应用都有完爆他几条街死机崩溃的超能力。但是对于某信来说,如今已经24M大小的它依然在屌丝机濒临垂死的硬件资源上运行如飞(至少没崩溃过),让我不得不感叹应用优化做的相当不错,也满足我们这种屌丝在深深的寂寞夜晚来摇一发的情感需求。所以来说,一个应用能赢得市场,不仅仅是赢得先机,而更多的是因为相同需求它功能做的比你好,相同功能它比你的简约,相同简约设计它运行比你快!

----------------------------------我是分割线---------------------------------天王盖地虎-------------------------------------------------------------

排队,一个一个慢慢来

  当ActivityA跟ActivityB打招呼说:“偶要回家了,你来顶上”。说明就马上溜得无影无踪,这时候急呀,ActivityB赶紧measure呀、layout呀、draw呀赶紧搞出一个界面来应付观众先,忙的不亦乐乎;更要命这时候的是他们还要搞一个交接仪式——超炫超牛的切换动画!然而在日益无穷大的欲望与逐渐干瘪的资源这强大的根本矛盾下,毫不犹豫的当机了几百毫秒。这一卡顿让手机前的强迫症患者来说是多大的心理创伤,自然而然会说:“这软件真渣!切个画面都会总得顿一下才死心”。用户体验瞬间降为0~

  解决方案有哪些?当然很简单的就是,取消牛逼哄哄的切换动画咯,但是如果你的产品经理死活不同意那还不得另寻途径。在不放弃动画的前提下,我们可以把某些measure呀、layout呀、draw呀的步骤延迟在动画后面执行不就行咯,排队一个一个来,至于怎么操作呢?那我们要引入一个轻量级组件<ViewStub>,也就是动态加载的方法。

  我们通常使用它来做预加载处理,来改善页面加载速度和提高流畅性,ViewStub本身不会占用层级,它最终会被它指定的层级取代。有时候我们也需要复杂的视图且少用,我们可以按需要的时候装载以便减少内存,提高体验。以前我们都是设置在布局中,然后使用View.GONE属性来隐藏组件,但是耗资源影响性能。总得来说这玩意就是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常小的控件。

下面上代码:

要加载的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需要主要几点:

1、ViewStub只能被Inflate一次,当Inflate之后ViewStub对象就被置为空值,说得更通俗点就是当ViewStub被某个布局Inflate后,就不能通过ViewStub来控制它,因为它已经功成身退了,自然对于需要不同场景下显示隐藏的情况建议用visibility。

2、ViewStub只能用来Inflate一个布局文件,对于单个具体的View它是无能为力的,当然如果把View搞在某个布局文件中也是可以接受的。

3、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>的好处有:

1、模块化布局,提高重用率,易于日后的维护和扩展。

2、降低生成的app的体重,用户的流量是很贵的!

简单说说剩下的点

1、减少不必要的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:第一次写的博文,写的渣得不能看。。。。。。

2、避免有太多的视图

每个视图都会消耗内存,在一个布局中布置太多的视图,布局会占用过多的内存,假设一个布局包含超过80个视图,layoutopt可能会给出下面这样的建议:

-1:-1 This layout has too many views: 83 views, it should have <= 80!

上面给出的建议是视图数量不能超过80,当然最新的设备有可能能够支持这么多视图,但如果真的出现性能不佳的情况,最好采纳这个建议。

3、千万别布局嵌套太多

布局不应该有太多的嵌套,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

嵌套布局警告通常伴随有一些无用布局的警告,有助于找出哪些布局可以移除,避免屏幕布局全部重新设计。

4、在某些场景下使用非主线程绘制的UI组件,具体组件名称我忘了,后面想起来补上哈。

作者:enjoy风铃
出处:http://www.cnblogs.com/net168/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则下次不给你转载了。

Android:一个高效的UI才是一个拉风的UI(二)的更多相关文章

  1. Android:一个高效的UI才是一个拉风的UI(一)

    开篇 Android是一个运行在移动终端上的操作系统,跟传统PC最大的不同所在就是移动终端的资源紧缺问题“比较”明显,当然对于一些屌丝机型,应该用“非常“来形容才靠谱.所以经常会出现在一些比较缺乏青春 ...

  2. Android开发自学笔记(Android Studio1.3.1)—2.开始第一个Android应用

    一.前言      使用Android Studio开发Android应用是一件非常简单的事情,因为它会帮你自动完成很多工作.本篇我们主要完成一个单击按钮在文本框显示当前时间的简单应用,借此来演示一下 ...

  3. android面试题 不仅仅是面试是一个很好的学习

    下面的问题是在网上找到的总结,感谢您分享!希望,我们的共同进步,找到自己心仪的公司,: 1.android dvm 流程和Linux这个过程.无论是应用程序对同一概念: 答案:dvm是dalivk虚拟 ...

  4. 关于Eclipse创建Android项目时,会多出一个appcompat_v7的问题

     问题描述: 使用eclipse创建一个Android项目时,发现project列表中会多创建出一个appcompat_v7项目,再创建一个Android项目时,又会再多出一个appcompat_ ...

  5. 【转】关于Eclipse创建Android项目时,会多出一个appcompat_v7的问题

    问题描述: 使用eclipse创建一个Android项目时,发现project列表中会多创建出一个appcompat_v7项目,再创建一个Android项目时,又会再多出一个appcompat_v7_ ...

  6. 我把阿里、腾讯、字节跳动、美团等Android性能优化实战整合成了一个PDF文档

    安卓开发大军浩浩荡荡,经过近十年的发展,Android技术优化日异月新,如今Android 11.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS. 但是,到了各大厂商手 ...

  7. android穿越之旅--如何弹出一个非比寻常的窗体

    上一篇中介绍了一种闻所未闻在android执行java命令的方法,虽然这是一种非常"高级"的技术,然后并没有什么卵用,因此被移除了博客园首页.实际上也并不是一点用处也没有,对已立即 ...

  8. 想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ #精选JAVASCRIPT前端开发

    想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ 作为一个软(ku)件(bi)工(de)程(ma)师(nong),你有没有觉得做什么事都没时间?没时间学习新东西,没时间去回顾.整理原来写的烂代 ...

  9. 发布一个高效的JavaScript分析、压缩工具 JavaScript Analyser

    发布一个高效的JavaScript分析.压缩工具 JavaScript Analyser 先发一段脚本压缩示例,展示一下JSA语法压缩和优化功能. try { //xxxx(); } catch (e ...

随机推荐

  1. 学习致用九---centos7.2+vim vundle

    目的,安装vim插件,vundle   Vundle是Vim的插件管理插件 YouCompleteMe 简称 YCM 1.安装vundle: git clone https://github.com/ ...

  2. js实现锚点定位

    js实现锚点定位的原理是,算出定位的标签距离顶部的高度,点击触发标签,重新赋值滚动条的高度到达指定位置. <!DOCTYPE html> <html> <head> ...

  3. AngularJS实战之ng-repeat的详细用法

    一.基本语法 {{$index}}:获取元素的下标. {{$first}}:判断当前元素是否是第一个元素,是则为true,否则:false: {{$last}}:判断当前元素是否是最后一个元素,是则为 ...

  4. 归并排序 JavaScript 实现

    前文我们了解了快速排序算法的实现,本文我们来了解下另一种流行的排序算法-归并排序算法. 我们先来回顾下快排.快排的核心是找出一个基准元素,把数组中比该元素小的放到左边数组,比该元素大的放到右边数组,如 ...

  5. session(会话)研究(一)基础

    一.Session对象的生成 session对象生成的过程,可以通过一个直观图进行观察. 也就是说,客户第一次请求访问时,Cookie中是没有SessionID的.在第一次访问之后,由服务器生成一个S ...

  6. day28(ajax之js原生代码实现)

    ajax ajax:异步页面无刷新技术 AJAX:异步的 JavaScript And XML. * 使用的是老的技术,用的是新的思想. AJAX的功能:完成页面的局部刷新,不中断用户的体验. XML ...

  7. 《javascript高级程序设计》 touch事件的一个小错误

    最近一段时候都在拜读尼古拉斯大神的<javascript高级程序设计>,真的是一本好书,通俗易懂,条理比<javascript权威指南>好理解一些,当然<javascri ...

  8. Python自动化开发 - 网络编程

    本节内容 1.客户端/服务器架构 2.OSI七层 3.socket层 4.socket是什么 5.套接字发展史及分类 6.套接字工作流程 一.客户端/服务器架构 即Client/Server架构,包括 ...

  9. HDU 4893 线段树的 点更新 区间求和

    Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  10. Android-Java构造代码块&构造方法隐式三行

    构造代码块: 描述Teacher对象/实体: package android.java.oop06; public class Teacher { private int id = 007; priv ...