加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

xml namespace in android

发布时间:2020-12-16 08:35:59 所属栏目:百科 来源:网络整理
导读:使用 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= "

使用 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 的官网,下面举几个常用的例子:

  • tools:ignore这个属性可以用于任意 XML 元素,是以逗号分隔的 Lint 工具检查项目的 ID,它会忽略此元素及其子元素中相应的 Lint 检查。
<string name="show_all_apps" tools:ignore="MissingTranslation">All</string>

Used by: Lint

    targetApi这个属性和 Java 类中的@TargetApi注解类似,用于指定 XML 元素运行的 API 等级,可以使用 API 等级的整数或者名称表示。
<GridLayout tools:targetApi="ICE_CREAM_SANDWICH" >

locale用于资源文件的根节点,指定资源的语言或者地区。

<resources tools:locale="es" Used by: Lint,Studio (关闭非英语资源文件的拼写检查)

    context通常用于 XML 布局文件的根节点,告诉工具这个布局文件是被哪个 Activity 使用(设计阶段,并非运行时)。这样做可以告诉 Layout Editor 此布局文件可以使用关联 Activity 的 theme,我们就可以看到对应 theme 下此布局实时渲染的效果。
<android.support.v7.widget.GridLayout ".MainActivity" />

Used by: Layout Editor in Studio & Eclipse,Lint

    layout我们通常都是动态使用 Fragment 类的,其实也可以直接在布局文件中使用 fragment 标签,此时,可以使用这个属性查看 Fragment 的对应布局的渲染效果。注意,这只是作为设计阶段的辅助,运行时你可以加载其它任意布局文件。
<fragment android:name="com.example.master.ItemListFragment" tools:layout="@android:layout/list_content" Used by: Layout Editor in Studio & Eclipse

    listitem | listheader | listfooter这个属性可以用于 AdapterView 的子类,包括 ListView,GridView 和 ExpandableListView 等,告诉工具在设计阶段列表渲染使用的 item 布局,header 和 footer 的布局。
<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

    menu这个属性告诉工具 Action Bar 使用的菜单资源文件。
<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类,并提供接受ContextAttributeSet作为参数的构造方法,这样就可以在XML布局中直接使用自定义 View 了。

class PieChart extends View { public PieChart(Context context, AttributeSet attrs) { super(contextattrs); } }

如果我们想要自定义属性,并且可以在 XML 布局文件中直接使用,请遵守以下 4 条:

  • <declare-styleable>资源元素下定义自定义属性
  • 在 XML 布局中声明属性值
  • 在运行时获取属性值
  • 在 View 对象上应用属性值

首先,让我们来自定义属性,在res/values/文件夹下添加attrs.xml文件,文件的内容如下:

<resources> <declare-styleable "PieChart"> <attr "showText" format="boolean" /> "labelPosition" "enum"> <enum "left" value="0"/> "right" "1"</attr> </declare-styleable> </resources>

上面的代码定义了两个自定义属性,showTextlabelPosition,它们都属于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 初始化以后才可以读取它的属性。因此,为了提供动态的行为,需要为每一个自定义属性提供GetterSetter方法。下面就是 PieChart 的 showText 相关的代码片段:

public boolean isShowText({ return mShowText; } void setShowText(boolean showText{ mShowText = showText; invalidate(); requestLayout(); 注意,为了保证 View 处于正确的状态,上面的代码调用了invalidate()requestLayout()两个方法。这样,你就可以在自定义的 View 类中根据自定义的属性控制 View 的行为了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读