在开发中我们往往会遇到这种情况,当一个布局文件比较复杂时,我们一个劲地往里面拖各种控件button,textView,imageView阿等等,等过了一段时间后,出现bug,自己都把自己搞懵比啦,特别是如果以RelativeLayout为RootView时,我们只是改动某个控件,但是整个布局都乱啦,再令人悲伤的是,其实页面上的某段代码我们在其他布局也能用到,我们还得敲一遍或者复制粘贴一遍,整个流程下来浪费了辣么多时间和精力,得到的却是冗余,不堪入目,可阅读性极差,后期维护代价极大的的代码,想想都得进入委屈模式。好啦,先看看API Guide里面对<include>

标签的介绍。

 

看看大标题的Re-usering Layouts,真的是一针见血,可重复使用的布局,没错,<include>标签就是帮助你重复利用哪些在你程序里经常出现的布局模块,劳资的英语实在是太差太差啦,上面的实在是看不懂,无奈只能跑去谷歌翻译,跑去百度翻译才能大致的了解了大概意思说是虽然Android提供了一些小部件和可重复利用的互动元素,当是我们可能还需要特殊的可重复利用的大组件,我们可以使用<include/>标签把一个布局页面嵌套到另外一个布局页面中。

 

举个最普遍的例子吧,很多App的页面都有标题栏吧,一般都是左边一个返回按钮键,中间一个说明标题文本,几乎每个页面都有标题栏,而且可能除了中间的说明标题文字不一样之外,其他的都一模一样,这时候,总不能每个页面都来这段重复的页面吧,多傻啊,我们只需要新建一个title_bar.xml,在每个页面用<include layout=“@layout/action_bar">把标题栏嵌套进去即可。就说说马蓉出轨这事吧,先看看下面两个页面。

  


虽然他们的标题栏不一样,但是他们用的是同一个布局actionBar

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dip"
    android:background="#f34323">

    <ImageButton
        android:id="@+id/ib_action_bar_left"
        android:layout_width="50dip"
        android:layout_height="match_parent"
        android:background="#f34323"
        android:src="@mipmap/navigation_previous_item" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:textColor="#FFF"
        android:textSize="20sp"
        android:text="标题"
        android:textStyle="bold" />

    <ImageButton

        android:id="@+id/ib_action_bar_right"
        android:layout_width="50dp"
        android:layout_height="match_parent"
        android:background="#f34323"
        android:layout_alignParentRight="true"
        android:src="@mipmap/navigation_next_item_dark" />
</RelativeLayout>

自己相应的页面再使用标签<include layout=“@layout/action_bar">,然后获取相应的控件,用不到的就inVisible

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/action_bar"/>


</LinearLayout>

正如上面,<include/>标签让我们可以重复利用重复出现的布局模块,但在使用的过程中,带给我们的好处不仅如此,整个页面代码的可阅读性和后期的维护代价都非常的好,当是在使用include标签中也需要注意几点。

(1)如果include标签的父布局是LinearLayout,类似于android:layout_alignParentBottom="true"这些在RelativeLayout中能够使用的属性会失效。如下图第一张图是footBar显示在了底部,第二张图却显示不了。

       


(2)我们可以将详细页面里的 android:layout_width属性, android:layout_height等属性转移到include标签中控制它的显示隐藏,比如说android:layout_width="0dp"   android:layout_height="0dp",这时候我们是看不到这个底部栏的,我们只需要<include /> 标签中同时指定 android:layout_width 和android:layout_height 这两个属性的值就可以浮现啦,其实也就类似于设置Android:visibility的属性啦。


其实只要工作过一段时间的童鞋都知道include标签啦,但是ViewStub标签就未必啦,为什么呢,个人觉得呢因为Android:visibility太好用啦,先看看那API Guides怎么介绍ViewStub标签的吧。

 看了这货的介绍,牛逼吧,这家伙简直 就是忍者啊,只有在需要他的时候(ViewStub 设置为可视或者 inflate() 方法被调用)他才会蹦的一下凭空而出,你可能会说这不和设置android:visibility属性的功能一个样吗,有啥啊,但请注意标红的invisible,zero-size,这个家伙是不可视的,零大小的,我们在java代码中设置XX.setVisibility(View.XX)相对于使用ViewStub来说是耗内存的。天下哪有免费的午餐,虽然ViewStub相对来说省内存,但是ViewStub只能Inflate一次,之后ViewStub对象就会被你要显示的那个View替代啦,也就是你inflate之后就没有ViewStub这个对象存在啦,你要想再inflate没门,抛异常啦,所以我们啥时候使用ViewStub呢,一个页面模块在inflate之后就不再改变的时候,我们就是用ViewStub,通俗易懂的讲吧,马蓉喝了一种叫做ViewStub的饮料,自打她嫁给王宝强(即inflate())那一刻起,她老公就只能是王宝强(这时候王宝强就相当于Layout:属性里的布局View)啦,如果马蓉劈腿啦,想把老公换成宋喆,那行,她挂啦(抛异常啦)。Demo我就不写啦,就官方文档那几句话,设置一下Layout属性就行,当是我们注意一下图中下面标红的那句英语,啥意思呢,就是inflate()方法返回的是一个View,其实这个View就是你要显示的那个View , 你不用再FindviewById()啥的啦,当然如果在这其中有和用户交互的控件,你直接用inflate()返回的View.findViewbyId即可。

 

 

 

 

 

 

 

换成