android布局优化

来源:互联网 发布:淘宝图片水印设置 编辑:程序博客网 时间:2024/06/05 14:39

1、开始布一个局

  1,新建一个android项目,把新建一个Activity那个选项选上!然后用模拟器运行项目!什么?!!

   你没看错,记住照着做就没错了…因为,今天,我们要讲如何优化和兼容View ,所以,一切从研究View开始!

  2,打开hierarchyviewer

   这是一个帮助我们优化view的非常重要的工具的,接下来的大部分时间,都会借住这个工具进行讲解,这个工具沉睡在android sdk 目录 tools下 hierarchyviewer.bat,或者用Everything这样的搜索硬盘的工具直接找到!

3,分析

  还记得我们第一步运行的项目吗?接着用hierarchyviewer这样的神器,就可以导出这样的图!

H

 

   这么一张图就是我们一个Hello,World项目的View 布局结构,在HierarchyViewer上你点击每个按钮就会有非常详细的布局信息,所以,这里对于hierarchyViewer的介绍到此为止!关于这个工具的详细使用,请查阅Debugging and Profiling User Interfaces 这里不做赘述!

2、如何布好一个局

1.熟读API文档!

  布局这东西不是比酷的东西,不是比谁的布局越复杂,那个人就越牛叉,以最少的步骤完成,设计图的要求,这应该是每个android开发程序员的宗旨!!

  案例一:做一个带箭头的返回按钮

   经理:那个小与啊,你根据这设计图搞一个按钮

    image

   小与:这还不简单三分钟搞定

于是小于程序猿,敲下了如下代码

<RelativeLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:gravity="center" >        <Button            android:id="@+id/button1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/btn_headtita"            android:textColor="#ffffff"            android:text="@string/back" />        <ImageView            android:id="@+id/imageView1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentLeft="true"            android:layout_centerVertical="true"            android:src="@drawable/header_back" />    </RelativeLayout>


看代码多累啊,我们用刚刚介绍的hierarchyviewer来分析一下,这个按钮有什么问题!

image

我们从这个图中,我们可以看到,为了这么一个按钮我们用了view的三个节点去完成!假设,我们的一个view 有三个类似的按钮就意味着我们要用9个节点去完成,我们可以简单得出这是一个3N级的复杂度布局,我们可以尝试去优化吗?

技巧一:熟读官方的API文档!

个人建议,常用的Widget的所有参数都尽量了解一遍!在阅读官方文档的时候我们发现了Button,有一个可以把图绘制在左边的参数:android:drawableLeft

于是,我们优化了一下小与的代码

    <Button        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/btn_headtita"        android:drawableLeft="@drawable/header_back"        android:gravity="center"        android:padding="10dp"        android:text="@string/back"        android:textColor="#ffffff" />

用hierarchyviewer来分析一下

image

瞬间一个3N级复杂度的布局,变成了一个N级复杂的!所以,我建议各位android开发朋友,在考虑优化的时候先把api文档里面的内容烂熟与心,不然,这样折腾下去,很浪费时间!

有细心的朋友可能会问:android:padding="10dp"  这个用来做什么了?

我先告诉大家,不用这个参数:你将会看到:

image

用了以后:

image

这下大家能够明白了吧?

所以,当你在进行布局的时候,如果碰到比较繁琐的时候,你先想想会不会已经API本身就有这样的参数呢?

简单是所有布局开始最重要的原则!

简单意味着不容易出现兼容问题!

简单意味着性能不错!

2.模块化布局

480x800_MarkMan

  所谓,模块化布局就是要你熟悉使用<include /> 这个标签!

一个经典的Tab类布局由三部分组成,我们可以根据这三部分创建三个可以重用的布局

head_menu.xml

content_showweibo.xml

bottom_menu.xml

然后我们可以很灵活的组合我们要显示的,例如要完成上面的那个weibo布局

<?xml version="1.0" encoding="utf-8"?><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 />标签就可以大大的减少我们日后都维护工作!

3.合并没必要的节点

还记得我们一开始的那个项目吗?

image


在高效布局里面,有一条准则就是,尽量的减少节点!!!!如图,我们发现,其实LinearLayout其实啥都没干,我们却耗费了那么一点性能去绘制了这么没用的节点!

接下来,我们为了消灭这个节点,我们需要一个这么的标签

<merge ></merge>

修改咱们的代码让它,性能更好!

<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android">    <Button        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/btn_headtita"        android:drawableLeft="@drawable/header_back"        android:gravity="center"        android:layout_gravity="center_vertical|center_horizontal"        android:padding="10dp"        android:text="@string/back"        android:textColor="#ffffff" /></merge>


打开hierarchyviewer 一看!

image 

哦也!优化了一个节点!并且显示快了那么一点点...

4.ViewStub

       这是什么玩应儿呢?其实就是一个轻量级的页面,我们通常使用它来做预加载处理,来改善页面加载速度和提高流畅性,ViewStub本身不会占用层级,它最终会被它指定的层级取代。
       还是说说演出项目吧,还说?对了,实践才能发现问题嘛,在哪儿发现问题就在那儿改进。由于项目中用到了比较多的动画,而且嵌套布局比较复杂,所以在Android低端机上进行页面切换时候经常让人感觉卡卡的,不怎么流畅,因为页面切换动画和标题旋转动画是同时进行的,所以为了达到更好的体验就需要使用一种方法,在动画进行时尽量的减少其他操作,特别是页面加载重绘。赶紧想办法,起初我想先将要加载的页面所有的组件都初始为gone显示状态,整个页面只留一下加载滚动条,后来发现这是不行滴,因为在Android的机制里,即使是将某一个控件的visibility属性设置为不可见的gone,在整个页面加载过程中还是会加载此控件的。再后来就用到了ViewStub,在做页面切换动画时,只在页面中放一个loading加载图标和一个ViewStub标签,像下面这样:

       layout_loading.xml布局文件:

[html] view plaincopy
  1. <merge xmlns:android="http://schemas.android.com/apk/res/android">  
  2.     <ViewStub  
  3.         android:id="@+id/viewstub"  
  4.         android:layout_width="fill_parent"  
  5.         android:layout_height="fill_parent"/>  
  6.     <NetErrAndLoadView  
  7.         android:id="@+id/start_loading_lay"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="fill_parent" />  
  10. </merge>  
这个页面是相当轻量级的,所以导致动画加载速度非常快、而且流畅。等页面切换动画完成之后,我们再指定ViewStub的资源,来加载实际的页面,这个资源就是实际要加载的页面的布局文件。比如要加载MainActivity的布局文件layout_main.xml,onCreate实现如下:
protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.layout_loading);                    mLoadHandler = new Handler();          mLoadingView = (NetErrAndLoadView)findViewById(R.id.start_loading_lay);          mLoadingView.startLoading();          mViewStub = (ViewStub)findViewById(R.id.viewstub);          mViewStub.setLayoutResource(R.layout.layout_main);                    mLoadHandler.postDelayed(new Runnable() {              @Override              public void run() {                  mViewStub.inflate();                  mLoadingView.hide();              }          },500);  }  
上面的500单位是ms,就是延迟加载的时间。上面使用的是动态添加ViewStub指向布局资源的方法(mViewStub.setLayoutResource(R.layout.layout_main)),当然根据需要可以直接在ViewStub的布局块儿中设置,需要设置ViewStub标签下的layout属性(android:layout="@layout/ layout_main")。
        ViewStub也是有少许缺点的,下面所说:
        1、  ViewStub只能Inflate一次,之后ViewStub对象会被置为空。按句话说,某个被ViewStub指定的布局被Inflate后,就不能够再通过ViewStub来控制它了。所以它不适用于需要按需显示隐藏的情况。
       2、  ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,当然也可以把View写在某个布局文件中。如果想操作一个具体的view,还是使用visibility属性吧。
       3、  VIewStub中不能嵌套merge标签。(前面好像说过)
不过这些确定都无伤大雅,我们还是能够用ViewStub来做很多事情。
        有时候真的不得不佩服google的Android团队的远见性和架构性,这种细微的设计都能考虑的到,想用就有。

3、总结  

讲了,这么一大堆东西,貌似,没怎么如何去优化?都是在说一些操作性的东西,其实,这世上没有绝对的优化方案,所谓的优化方案都是基于一个最初的基本原则出发,例如,内存用得再少一点!那么如何才能将这内存用得再少一点做的了,这样就需要一些最基本的方法,关于布局这部分的基本方法,我在上面已经很详细的说了一遍了,当进行布局的时候你要牢记

1,尽量使用view自身的参数

2,减少一个布局的不必要节点

3,尽量重用一个布局文件

  兼容问题呢?兼容问题出现的原因千奇百怪,没有一套通用的法则!关于这点谈一下自己的看法

1,减少复杂度,往往,兼容问题的出现,就是布局太复杂了,例如,我举的那个按钮布局,本来一个View就能完成,你却用了三个view完成,在使用的时候,出现问题的概念也大幅度提升!所以,布局以简单为本,那样兼容问题就可以尽量避免!

2,熟练使用工具,还记得hierarchyviewer 吗?当出现兼容问题的时候,用这个软件可以快速定位到错误位置!




0 0