使用延迟加载以及避免代码重复

在XML文件中使用include标签来避免代码的重复以及使用ViewStub类来实现视图的延迟加载。

使用include标签来避免代码重复

某一Activity的XML布局文件main.xml如下:

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

    <Button  android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="onShowMap" android:text="@string/show_map"/>


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

</RelativeLayout>

footer_with_layout_properties布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp" android:gravity="center" android:text="@string/footer_text"/>

在上述示例代码中,我们使用了include 标签,并且只需要指定该标签的layout属性值。读者可能回想:“这种方式之所以可行是因为Activity在main布局文件中使用的是RelativeLayout。如果其中一个Activity的布局文件使用的是LinearLayout呢?虽然android:layout_alignParentBottom=”true”适用于RelativeLayout,但并不适用于LinearLayout。”这个想法是正确的。接下来分析使用include 标签的第二种方法,这这种方法里,我们直接在include 标签里使用android:layout_*属性。

以下是修改后的main.xml文件,其中使用了include 标签的android:layout_*属性:

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

    <Button  android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="onShowMap" android:text="@string/show_map"/>


    <include  layout="@layout/footer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp"/>

</RelativeLayout>

footer布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="0dp" android:layout_height="0dp" android:gravity="center" android:text="@string/footer_text"/>

在第二种方法中,我们通过include 标签指定footer布局文件的位置。Android的缺陷(Issue)跟踪系统中报告过一个缺陷,缺陷的标题是:”include 标签失效了,如果想通过include 标签的属性覆盖被包含的布局所指定的属性是行不通的。“这个issue描述的问题在一定程度上是正确的,问题出在如果想在include 标签中覆盖被包含的布局所指定的任何android:layout_*属性,必须在include 标签中同时指定android:layout_width和android:layout_height这两个属性。

我们把所有android:layout_*属性都移到include 标签中了,而footer.xml文件中的android:layout_width和android:layout_height属性都指定为0dp。这么做的目的是由footer.xml文件的使用者在include 标签中指定android:layout_width和android:layout_height属性。如果使用者不指定这两个属性,它的默认值都是0,我们便看不到footer布局。

使用ViewStub类实现View的延迟加载

设计布局的时候,读者可能想过根据上下文或者用户交互情况显示一个视图。如果想要一个视图只在需要的时候显示,你可以尝试使用ViewStub这个类。

ViewStub的开发文档介绍:
”ViewStub是一个不可视并且大小为0的视图,可以延迟到运行时填充(inflate)布局资源。当ViewStub设置为可视或者inflate()方法被调用后,就会填充布局资源,然后ViewStub便会被填充的视图代替。“

Activity使用的布局文件如下:

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

    <Button  android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="onShowMap" android:text="@string/show_map"/>

    <!--inflatedId是调用ViewStub的inflate()方法或者setVisibility()方法时返回的ID,这个ID便是被填充的View 的ID。在本例中,我们不需要操作被填充的View,只需要调用setVisibility(View.VISIBLE)即可。如果想获取 被填充的视图的引用,inflate()方法会直接返回该引用,这样避免了再次调用findViewById()方法。-->
    <ViewStub  android:id="@+id/map_stub" android:layout_width="fill_parent" android:layout_height="fill_parent" android:inflatedId="@+id/map_view" android:layout="@layout/map"/>

    <include  layout="@layout/footer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp"/>

</RelativeLayout>

map.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey="my_api_key" android:clickable="true"/>

Activity源码:

package com.example.huangfei.demo;

import android.os.Bundle;
import android.view.View;
import android.view.ViewStub;

import com.google.android.maps.MapActivity;

public class MainActivity extends MapActivity {

    private ViewStub mViewStub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mViewStub = (ViewStub) findViewById(R.id.map_stub);
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    public void  onShowMap(View view){
        mViewStub.setVisibility(View.VISIBLE);
        //mViewStub.inflate();
    }

}

无论在什么情况下,只要开发者根据上下文选择隐藏或者显示一个视图,都可以用ViewStub实现。或许并不会因为一个视图的延迟加载而感觉到性能的明显提升,但是如果视图树的层次很深,便会感觉到性能上的差距了。

你可能感兴趣的:(ViewStub,include)