xml namespace in android
使用 Android Studio 创建 Project 时,默认的 MainActivity 的布局文件 activity_main.xml 如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height=tools:context=".MainActivity">
<TextView
"wrap_content"
android:text="@string/hello_world" />
</RelativeLayout>
在使用 Eclipse 的时候,我曾经就有疑问,上面的xmlns:android=”http://schemas.android.com/apk/res/android”是什么意思。这篇博客就是简单的介绍一下 Android XML 文件的命名空间是什么以及如何使用。 ###XML namespace xmlns 即 XML namespace,也就是 XML 文件的命名空间,这是 XML 通用的一个特性,并非 Android 的资源文件特有。XML 命名空间使用 URI 引用来标识,是加在 XML 元素和元素的属性上的约束。注意,URI 是 Identifier,所以,虽然通常会有http://的字符出现,但不一定会像 URL 一样指向特定的资源。XML 的元素和元素的属性,属于不同的命名空间,就可以拥有不同的意义,甚至可以进行自定义,另外这样做也可以防止冲突。 我们可以这样定义 XML namespace:xmlns:aaa=”http://schemas.aaa.com”这样就定义了一个“http://schemas.aaa.com”的命名空间,它的别名是“aaa” 下面是一个简单的同一个 XML 文件里使用多个命名空间的例子: <?xml version="1.0"?>
<bk:book
xmlns:bk='urn:loc.gov:books'
xmlns:isbn='urn:ISBN:0-395-36341-6'<bk:title>Cheaper by the Dozen</bk:title>
<isbn:number>1568491379</isbn:number>
</bk:book>
这样 XML 的解析器就可以根据不同的命名空间来进行解析工作了。其实,这和 Java 中类的全限定名有些类似,可以有相同的类名,只要它们处于不同的包中,就还是两个不同的类,JVM 是通过类的全限定名来加载类的。 ###Android 资源文件的命名空间 ####xmlns:android=”http://schemas.android.com/apk/res/android” 这是 Android 的 Framework 层解析 XML 布局文件默认的命名空间,android 是它的别名,所以在 View 的属性前都会有android:的前缀,你也可以取其它的名字,但是这个命名空间的字符串标识符是唯一、不可更改的。 ####xmlns:tools=”http://schemas.android.com/tools” Android 还有另外一个常用的命名空间,URI是“http://schemas.android.com/tools”,它可以让工具提取 XML 文件的信息,并且在打包 APK 的时候去除掉此命名空间下的元素和属性,这样就不会影响运行时了。 根据 Android Tools 的官网,下面举几个常用的例子:
<string name="show_all_apps" tools:ignore="MissingTranslation">All</string>
Used by: Lint
<GridLayout
tools:targetApi="ICE_CREAM_SANDWICH" >
locale用于资源文件的根节点,指定资源的语言或者地区。 <resources
tools:locale="es" Used by: Lint,Studio (关闭非英语资源文件的拼写检查)
<android.support.v7.widget.GridLayout
".MainActivity" />
Used by: Layout Editor in Studio & Eclipse,Lint
<fragment
android:name="com.example.master.ItemListFragment"
tools:layout="@android:layout/list_content" Used by: Layout Editor in Studio & Eclipse
<ListView
android:id="@android:id/list"
tools:listitem="@android:layout/simple_list_item_2" showIn为了方便布局的复用,我们会 include 某些公用的布局文件。在公用的布局文件的根元素中使用这个属性,可以在合适的上下文,也就是外围布局中渲染这个布局,看到全部的效果。
<?xml version="1.0" encoding="utf-8"?>
<TextView "@string/hello_world"
"wrap_content"
tools:showIn="@layout/activity_main" Used by: Layout Editor in Studio
<LinearLayout android:orientation="vertical"
tools:menu="menu1,menu2" actionBarNavMode这个属性告诉工具 Action Bar 的导航模式,包括“standard”,“list”,“tabs”三种。
tools:actionBarNavMode="tabs" Used by: Layout Editor in Studio
####Designtime Layout Attributes 既然我们上面说到的命名空间只是在设计时起作用,我们可以更进一步,覆写 Framework 提供的 View 的属性,只是在设计阶段查看界面渲染的效果,打包的时候会被去除,所以不会影响运行时。 要使用这个功能,和上面一样,首先需要在布局的根元素中加入此命名空间的声明。然后,可以把所有原来以android:前缀开始的 View 的属性改为tools:前缀。而且,这两个命名空间下的属性可以同时出现,一个是设计阶段起作用,一个是运行时起作用,互不影响。 <TextView
tools="Dummy text"
"wrap_content" 比如上面这段 TextView 的声明,由于没有预设的文字,所以没法在工具渲染的时候看到它的样子,此时可以加入tools=”Dummy text”,就可以实时查看这个 TextView 的样子了,而且不会影响运行时。
再例如,有些 View 的显示与否是运行时动态控制的,这个时候我们可以这样做: <Button
"@+id/button"
"First"
tools:visibility="invisible" "@+id/button2"
"Second"
"visible" 这样我们就可以在工具渲染布局的时候动态控制 View 的可见性,十分方便。
###在 Android 中自定义命名空间 上面说的都是 Android 的 Framework 和开发工具定义的 XML 命名空间,我们来看看自定义 XML 命名空间的应用。我们在 Android 的开发中,偶尔会需要自定义 View,自定义的 View 都是继承自 Framework 的android.view.View类或者它的子类。这个时候,如果我们想要除了 Framework 提供的属性以外的属性,就会用到自定义命名空间。 首先,我们继承View类,并提供接受Context和AttributeSet作为参数的构造方法,这样就可以在XML布局中直接使用自定义 View 了。 class PieChart extends View {
public PieChart(Context context, AttributeSet attrs) {
super(contextattrs);
}
}
如果我们想要自定义属性,并且可以在 XML 布局文件中直接使用,请遵守以下 4 条:
首先,让我们来自定义属性,在res/values/文件夹下添加attrs.xml文件,文件的内容如下: <resources>
<declare-styleable "PieChart">
<attr "showText" format="boolean" />
"labelPosition" "enum">
<enum "left" value="0"/>
"right" "1"</attr>
</declare-styleable>
</resources>
上面的代码定义了两个自定义属性,showText和labelPosition,它们都属于PieChart的样式。样式的名称虽然不一定非要和自定义 View 的类名相同,但是有些代码编辑器是通过名称来进行关联的,所以最好是遵循这个习惯。 下面就可以在 XML 布局文件中使用自定义属性了,但是和 Framework 提供的内置属性不同的是,自定义属性不是属于http://schemas.android.com/apk/res/android命名空间的,它是属于http://schemas.android.com/apk/res/[your-package-name]命名空间的。下面就是使用自定义属性的示例代码: "http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.example.customviews"<com.example.customviews.charting.PieChart
custom:showText="true"
custom:labelPosition="left" </LinearLayout>
上面我们定义了custom的命名空间别名,当然你也可以使用其它的别名。 当 XML 布局中的 View 对象被创建的时候,它的属性会被封装进 AttributeSet 对象传进此 View 的构造方法。虽然我们可以直接从 AttributeSet 对象读取属性值,但是更好的方法是将 AttributeSet 对象传给obtainStyledAttributes()方法,这个方法会返回一个包含了属性数组的TypedArray对象。下面就是 PieChart 类如何读取属性的: public PieChart(Context context);
TypedArray a = context.getTheme().
obtainStyledAttributes(attrsRstyleablePieChart0);
try {
mShowText=agetBoolean(RPieChart_showTextfalse);
mTextPos = agetIntegerPieChart_labelPosition} finally {
arecycle();
属性可以控制 View 的样子,但是只有 View 初始化以后才可以读取它的属性。因此,为了提供动态的行为,需要为每一个自定义属性提供Getter和Setter方法。下面就是 PieChart 的 showText 相关的代码片段:
public boolean isShowText({
return mShowText;
}
void setShowText(boolean showText{
mShowText = showText;
invalidate();
requestLayout();
注意,为了保证 View 处于正确的状态,上面的代码调用了invalidate()和requestLayout()两个方法。这样,你就可以在自定义的 View 类中根据自定义的属性控制 View 的行为了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |