精华内容
下载资源
问答
  • XML 属性

    千次阅读 2008-03-21 15:07:00
    XML elements can have attributes in the start tag, just like HTML.XML 元素可以像HTML那样在起始标签内书写属性。Attributes are used to provide additional information about elements.属性是用来提供与元素...

    XML elements can have attributes in the start tag, just like HTML.
    XML 元素可以像HTML那样在起始标签内书写属性。

    Attributes are used to provide additional information about elements.
    属性是用来提供与元素相关的附加信息的。


    XML Attributes
    XML属性

    XML elements can have attributes.
    XML 元素可以有属性。

    From HTML you will remember this: <IMG SRC="computer.gif">. The SRC attribute provides additional information about the IMG element.
    在HTML教程中,你一定还记得这个:<IMG SRC="computer.gif">, SRC 属性提供了与 IMG 元素相关的附加信息。

    In HTML (and in XML) attributes provide additional information about elements:
    在HTML(以及XML)中,属性是提供与元素相关的附加信息的。

    <img src="computer.gif">
    <a href="demo.asp">

    Attributes often provide information that is not a part of the data. In the example below, the file type is irrelevant to the data, but important to the software that wants to manipulate the element:
    属性通常提供除数据部分以外的信息,在下面的案例中,文件类型与数据不相关,但对处理元素的软件却很重要:

    <file type="gif">computer.gif</file>

     


     

    Quote Styles, "female" or 'female'?
    引号类型,"female" 还是 'female'?

    Attribute values must always be enclosed in quotes, but either single or double quotes can be used. For a person's sex, the person tag can be written like this:
    属性值必须书写在引号里,单引和双引都可以用。以某人性别为例,人物标签可以这样书写:

    <person sex="female">

    or like this:
    或者这样

    <person sex='female'>

    Note: If the attribute value itself contains double quotes it is necessary to use single quotes, like in this example:
    注意:
    如果属性值本身包含双引号,那引用整句时就必须使用单引号,见下面的案例:

    <gangster name='George "Shotgun" Ziegler'>

    Note: If the attribute value itself contains single quotes it is necessary to use double quotes, like in this example:
    注意:
    如果属性值本身包含单引号,那引用整句时就必须使用双引号,见下面的案例:

    <gangster name="George 'Shotgun' Ziegler">

     


    Use of Elements vs. Attributes
    比较元素和属性的使用方法

    Data can be stored in child elements or in attributes.
    数据可以存储在子元素或属性中。

    Take a look at these examples:
    请看下面这些案例:

    <person sex="female">
    <firstname>Anna</firstname>
    <lastname>Smith</lastname>
    </person>

     

    <person>
    <sex>female</sex>
    <firstname>Anna</firstname>
    <lastname>Smith</lastname>

    </person>

    In the first example sex is an attribute. In the last, sex is a child element. Both examples provide the same information.
    在第一个案例中,性别是一个属性。在最后的案例中,性别是一个子元素。两个案例提供的信息一样。

    There are no rules about when to use attributes, and when to use child elements. My experience is that attributes are handy in HTML, but in XML you should try to avoid them. Use child elements if the information feels like data.
    至于何时使用属性或何时使用子元素并没有具体的规定。我的经验是:对于HTML中的属性来说,操作起来比较容易,但在XML中,你应该尽量避免用属性。如果信息中包含大量的数据,那么就尽量使用子元素。


    My Favorite Way
    我最喜欢的方法

    I like to store data in child elements.
    我喜欢将数据存储在子元素中。

    The following three XML documents contain exactly the same information:
    以下三份XML文档都包含相同的信息:

    A date attribute is used in the first example:
    第一个案例中使用了日期属性:

    <note date="12/11/2002">
    <to>Tove</to>
    <from>Jani</from>

    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
    </note>

    A date element is used in the second example:
    第二个案例中使用了日期元素:

    <note>
    <date>12/11/2002</date>

    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
    </note>

    An expanded date element is used in the third: (THIS IS MY FAVORITE):
    第三个案例中使用了扩展日期元素(这是我们常用的方法):

    <note>
    <date>
    <day>12</day>
    <month>11</month>

    <year>2002</year>
    </date>
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>

    <body>Don't forget me this weekend!</body>
    </note>

     


    Avoid using attributes?
    避免使用属性?

    Should you avoid using attributes?
    你真的应该避免使用属性吗?

    Some of the problems with using attributes are:
    使用属性会带来的一些问题:

    • attributes cannot contain multiple values (child elements can)
      属性不能含有多重值(子元素可以)
    • attributes are not easily expandable (for future changes)
      属性不易扩展(这里说的可扩展性是针对将来的属性变化来讲的)
    • attributes cannot describe structures (child elements can)
      属性不能描述结构(如果是子元素的话可以描述结构)
    • attributes are more difficult to manipulate by program code
      属性不易被程序代码处理
    • attribute values are not easy to test against a Document Type Definition (DTD) - which is used to define the legal elements of an XML document
      属性值不易被文本类型定义(DTD)测试,DTD是用来定义XML文档中的合法元素的

    If you use attributes as containers for data, you end up with documents that are difficult to read and maintain. Try to use elements to describe data. Use attributes only to provide information that is not relevant to the data.
    如果你使用属性作为储存数据的容器,那么最终生成的文件将不易于阅读和长时间持续地使用。试着使用元素对数据进行描述;仅在提供一些与数据无关的信息是才使用属性。

    Don't end up like this (this is not how XML should be used):
    不要这样结尾(XML不应该这样使用):

    <note day="12" month="11" year="2002"

    to="Tove" from="Jani" heading="Reminder"
    body="Don't forget me this weekend!">
    </note>

     


    An Exception to my Attribute Rule
    我的属性使用规则之例外

     

    Rules always have exceptions.
    规则常有例外。

    My rule about attributes has one exception:
    我的属性使用规则有一个例外。

    Sometimes I assign ID references to elements. These ID references can be used to access XML elements in much the same way as the NAME or ID attributes in HTML. This example demonstrates this:
    有时我把ID参数赋值给元素。这些ID参数可用来访问XML元素,这与HTML中的 NAME 或 ID  属性存取XML元素的方式大致相同。以下的案例可以说明问题:

    <messages>

    <note id="p501">
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>

    <body>Don't forget me this weekend!</body>
    </note>

    <note id="p502">
    <to>Jani</to>

    <from>Tove</from>
    <heading>Re: Reminder</heading>
    <body>I will not!</body>
    </note>

    </messages>

    The ID in these examples is just a counter, or a unique identifier, to identify the different notes in the XML file, and not a part of the note data.
    这些例子中ID只是一个“计数器”,或者可以称之为一个特别的“识别器”,用于识别XML文件中不同的note信息,但它们不是note数据的一部分。

    What I am trying to say here is that metadata (data about data) should be stored as attributes, and that data itself should be stored as elements.
    我想着重强调的是,metadata(元数据:与数据相关的数据)应该以属性方式储存,而数据本身应该以元素方式储存。

    展开全文
  • delphi解析xml属性节点

    2018-10-16 14:00:18
    delphi解析xml属性节点,根据不同节点获取属性值,与获取节点值不同的方式
  • C#读取XML属性解决方法

    千次阅读 2018-11-19 10:12:15
    C#读取XML属性解决方法 Xml示例:&lt;ESBReturn xmlns='http://123'&gt; &lt;ESBHeader Status='1' Remarks='1' ReturnTime='2018/11/14 14:42:54' /&gt; &lt;ESBBody&gt; &lt;...

    C#读取XML属性解决方法

    Xml示例<ESBReturn xmlns='http://123'> <ESBHeader Status='1' Remarks='1' ReturnTime='2018/11/14 14:42:54' /> <ESBBody> <BusinessResponse> <![CDATA[<rows><row PatientCode='ABC323' PatientName='宝之' ScreeningScore='4' ScreeningApprise='NRS2002评分结果:4分,患者具有营养风险,应开始制定营养治疗计划(包括治疗膳食,经口营养补充,肠内营养及肠外营养)。' IsRisk='True' ScreenDate='2018/7/27 23:05:38'></row></rows>]]> </BusinessResponse> </ESBBody> </ESBReturn>

    读取节点row当中的 PatientCode、PatientName。。。中的值

    var xml = new XmlDocument();
    xml.LoadXml(@"xml")
    var xmlrow = new XmlDocument();
     xmlrow.LoadXml(xml.InnerText);
     //读取此节点上的属性,返回一个List
    XmlNodeList elemlist = xmlrow.GetElementsByTagName("row");
     for (int i = 0; i < elemlist.Count; i++)
                    {
                        string PatientCode = elemlist[i].Attributes["PatientCode"].Value;
                        string PatientName = elemlist[i].Attributes["PatientName"].Value;
                        string Score = elemlist[i].Attributes["ScreeningScore"].Value;
                        string Apprise = elemlist[i].Attributes["ScreeningApprise"].Value;
                    }
    
    展开全文
  • android中只要View类及其子类有xml属性吗,还有其他什么类有xml属性呢,它们的xml属性实际是它们的常量吗
  • Android自定义View读取XML属性详解

    千次阅读 2016-04-20 14:09:56
    今天研究了一下自定义View中XML属性的解析。首先,我们在声明自定义View时,会直接声明构造函数:public XCustomView(Context context, AttributeSet attrs)构造函数接受了一个context变量和一个attrs变量,我们使用...

    今天研究了一下自定义View中XML属性的解析。

    首先,我们在声明自定义View时,会直接声明构造函数:

    public XCustomView(Context context, AttributeSet attrs)

    构造函数接受了一个context变量和一个attrs变量,我们使用attrs就可以解析XML属性了。
    这里通常使用的方法是声明一个TypedArray变量,通过context.obtainStyledAttributes方法来获取attrs中的属性;实际这里直接使用attrs来解析也是可以的,但会稍麻烦一些。

    自定义View的声明

    假设我们的自定义View类名是XCustomView,对应的,先声明一些自定义属性:
    CustomViewStyleable.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="XCustomView">
            <attr name="testAttrFirst" format="integer"/>
            <attr name="testAttrSecond" format="string"/>
        </declare-styleable>
    </resources>

    简单定义两个属性,其值分别为整形和字符串类型。

    接下来简单写一个Activity的布局文件,在以前使用eclipse时,在指定我们自定义属性的名字时,需要在xmlns后指定包名;在Android Studio环境下,由于整个项目使用gradle构建,因此包名根据设置可以在编译时产生变化,IDE此时提示我们不要硬编码将包名设置进去,只需要使用特殊字段来标识就可以:

    xmlns:custom_name=”http://schemas.android.com/apk/res-auto”

    只需要将custom_name替换为我们自定义的名字即可。
    整个activity布局是这样的:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:xcustom="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.example.customviewstudy.MainActivity">
    
        <com.example.customviewstudy.XCustomView
            android:id="@+id/custom_view"
            android:layout_width="100dp"
            android:layout_height="200dp"
            xcustom:testAttrFirst="12345"
            xcustom:testAttrSecond="HelloCustomView"/>
    
    </LinearLayout>

    我们为XCustomView控件指定了5个属性,其中有两个是自定义属性。

    TypedArray获取方法

    接下来,首先来看使用TypedArray的方法:

    public class XCustomView extends View {
        public static final String TAG = "CustomView-TAG";
    
        public XCustomView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.XCustomView);
    
            int testAttrFirstValue = array.getInt(R.styleable.XCustomView_testAttrFirst, 100);
            Log.d(TAG, "testAttrFirstValue: " + testAttrFirstValue);
            String testAttrSecondValue = array.getString(R.styleable.XCustomView_testAttrSecond);
            Log.d(TAG, "testAttrSecondValue: " + testAttrSecondValue);
    
            array.recycle();
        }
    }

    使用context.obtainStyledAttributes方法来生成TypedArray。
    这个函数接收两个参数:
    构造函数中的AttributeSet类型变量 attrs,
    int[]型数组,需传入刚才自定义的xml文件对应变量 R.styleable.XCustomView,这里传入其他的数组(如R.styleable.View),不会报任何错误,不过后面也就解析不出自定义属性了。

    得到TypedArray变量后,通过一系列get方法就可以获取到相应属性了,例如
    int testAttrFirstValue = array.getInt(R.styleable.XCustomView_testAttrFirst, 100);
    其中需要自定义属性所对应的R变量R.styleable.XCustomView_testAttrFirst,以及给定一个默认值(100)。
    最后不要忘记TypedArray使用后要通过recycle方法回收,否则会引起内存泄漏。
    上面代码运行后输出:

    D/CustomView-TAG: testAttrFirstValue: 12345
    D/CustomView-TAG: testAttrSecondValue: HelloCustomView

    AttributeSet获取方法

    下面来看看AttributeSet直接获取的方法:

    public class XCustomView extends View {
        public static final String TAG = "CustomView-TAG";
    
        public XCustomView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            for (int i =0; i < attrs.getAttributeCount(); i++) {
                Log.d(TAG, "attrs get No." + i + " attr name: " + attrs.getAttributeName(i) + ", value: " + attrs.getAttributeValue(i));
            }
            Log.d(TAG, "attrs get first value: " + attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto", "testAttrFirst", 100));
            Log.d(TAG, "attrs get second value: " + attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "testAttrSecond"));
            Log.d(TAG, "attrs count: " + attrs.getAttributeCount());
    
        }
    }
    1. 通过getAttributeCount方法,就可以获得控件总共的属性数量;
    2. getAttributeName来获取对应index处的属性名称,以sting返回。
    3. attrs.getAttributeValue来获取相应index处属性的值,以string返回。

    除了这种遍历的方法,还可以指定获取特定属性。
    例如getAttributeIntValue方法,他接受三个参数:

    public int getAttributeIntValue(String namespace, String attribute, int defaultValue);

    namespace代表自定义属性的命名空间,同xml种的方法,在studio工程中,自定义属性仅需要传入

    http://schemas.android.com/apk/res-auto

    attribute是对应属性名称,在这里是我们声明的testAttrFirst;
    defaultValue为默认值,当没有获取到xml中的数值时,就返回这个默认值。

    上面的代码运行后输出:

    D/CustomView-TAG: attrs get No.0 attr name: id, value: @2131492944
    D/CustomView-TAG: attrs get No.1 attr name: layout_width, value: 100.0dip
    D/CustomView-TAG: attrs get No.2 attr name: layout_height, value: 200.0dip
    D/CustomView-TAG: attrs get No.3 attr name: testAttrFirst, value: 12345
    D/CustomView-TAG: attrs get No.4 attr name: testAttrSecond, value: HelloCustomView
    D/CustomView-TAG: attrs get first value: 12345
    D/CustomView-TAG: attrs get second value: HelloCustomView
    D/CustomView-TAG: attrs count: 5

    总结

    1.使用TypedArray获取,需要AttributeSet与int[]两个参数,int[]数组需要与当前自定义View类型匹配,否则就无法解析出自定义属性。
    使用TypedArray后切记不要忘记调用recycle回收。
    2.使用AttributeSet获取需要提供自定义属性的命名空间,在studio工程中,只需要传入特殊值http://schemas.android.com/apk/res-auto即可。
    获取具体属性及取值直接调用AttributeSet的接口即可。

    展开全文
  • 为View添加自定义XML属性Android中的各种Widget都提供了很多XML属性,我们可以利用这些XML属性在layout文件中为Widget的属性赋值。如下所示: android:layout_width="wrap_content" android:layout_height="wrap_...

    为View添加自定义XML属性

    Android中的各种Widget都提供了很多XML属性,我们可以利用这些XML属性在layout文件中为Widget的属性赋值。

    如下所示:

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!" />

    我们可以通过TextView所提供的XML属性android:text为TextView的文本赋值。

    我们在自定义View的时候也会经常需要自定义View的XML属性。

    假设我们有一个自定义的View,其类名是com.ispring.attr.MyView,其中com.ispring.attr是应用程序的包名。

    要想自定义XML属性,总的来说包括三步:

    1. 在xml资源文件中定义各种attr,指定attr的数据类型。
    2. 在自定义View的构造函数中解析这些从XML中定义的属性值,将其存放到View对应的成员变量中。
    3. 在layout文件中为自定义View的XML属性赋值。

    首先,我们在res/values目录下新建了一个名为attrs_my_views.xml文件,文件名是什么不重要,只要是xml文件就行。我们在该文件中定义MyView所支持的XML属性。该文件的根结点是<resources>,我们在<resources>节点下可以添加多个<attr>节点,在<attr>节点中通过name指定XML属性名称,通过format指定XML属性值的类型,如下图所示:
    这里写图片描述

    由上图我们可知,format支持的类型有enum、boolean、color、dimension、flag、float、fraction、integer、reference、string。

    当我们指定了XML属性的名称和属性值的类型之后,我们就可以在layout文件中通过XML属性为其赋值了。如下图所示:
    这里写图片描述

    我们通过<com.ispring.attr.MyView>在layout中引入了MyView,为了能够使用自定义属性,我们通常要指定一个自定义的命名空间以区别于Android的命名空间xmlns:android,我们自定义命名空间的名字可以是任意的,通常我一般用xmlns:app。我的App的命名空间是com.ispring.attr,如果用Eclipse开发,那么可以这样定义命名空间xmlns:app=http://schemas.android.com/apk/res/com.ispring.attr,但是在Android Studio中这样定义命名空间会有问题。Android Studio使用Gradle进行build,而Gradle不允许自定义的命名空间以包名结尾,在Android Studio中可以这样定义命名空间xmlns:app="http://schemas.android.com/apk/res-auto",这样定义的命名空间自动指向当前App的命名空间。

    在正确定义app的命名空间之后,我们就可以用app:customAttr为MyView的customAttr属性赋值了。如果我们将customAttr的format定义为boolean的,那么此处就只能填写true或者false,填写其他类型的值会报错。

    下面再对attr的format的类型进行一下说明。

    • boolean
      boolean表示attr是布尔类型的值,取值只能是true或false。

    • string
      string表示attr是字符串类型。

    • integer
      integer表示attr是整数类型,取值只能是整数,不能是浮点数。

    • float
      float表示attr是浮点数类型,取值只能是浮点数或整数。

    • fraction
      fraction表示attr是百分数类型,取值只能以%结尾,例如30%、120.5%等。

    • color
      color表示attr是颜色类型,例如#ff0000,也可以使用一个指向Color的资源,比如@android:color/background_dark,但是不能用0xffff0000这样的值。

    • dimension
      dimension表示attr是尺寸类型,例如取值16px、16dp,也可以使用一个指向<dimen>类型的资源,比如@android:dimen/app_icon_size

    • reference
      reference表示attr的值只能指向某一资源的ID,例如取值@id/textView

    • enum
      enum表示attr是枚举类型,在定义enum类型的attr时,可以将attr的format设置为enum,也可以不用设置attr的format属性,但是必须在attr节点下面添加一个或多个enum节点。如下所示:

      <attr name="customAttr">
          <enum name="man" value="0" />
          <enum name="woman" value="1" />
      </attr>

      这样attr的属性值只能取man或woman了。

    • flag
      flag表示attr是bit位标记,flag与enum有相似之处,定义了flag的attr,在设置值时,可以通过|设置多个值,而且每个值都对应一个bit位,这样通过按位或操作符|可以将多个值合成一个值,我们一般在用flag表示某个字段支持多个特性,需要注意的是,要想使用flag类型,不能在attr上设置format为flag,不要设置attr的format的属性,直接在attr节点下面添加flag节点即可。如下所示:

      <attr name="customAttr">
          <flag name="none" value="0" />
          <flag name="bold" value="0x1" />
          <flag name="italic" value="0x2" />
          <flag name="underline" value="0x4" />
      </attr>

      <attr>节点下通过定义多个<flag>表示其支持的值,value的值一般是0或者是2的N次方(N为大于等于0的整数),对于上面的例子我们在实际设置值是可以设置单独的值,如none、bold、italic、underline,也可以通过|设置多个值,例如app:customAttr="italic|underline"

      MyView直接继承自View,我想让MyView可以显示文本,即我传递文本给MyView,MyView能画出来,就相当于非常简单的TextView。

    因此,我的attrs_my_view.xml如下所示:

    <resources>
        <attr name="customText" format="string" />
        <attr name="customColor" format="color" />
    </resources>

    我们定义了两个XML属性,customText是一个string类型,表示MyView要显示的文本,customColor是color类型,表示文本的颜色。

    对项目进行编译之后会生成R.java文件,R.java文件对应着R类。如果是Android Studio项目,那么R文件的目录是app\build\generated\source\r\debug\com\ispring\attr\R.java,在该文件中有内部类public static final class attr,在R.attr中会发现有customTextcustomColor,如下图所示:

    这里写图片描述

    R.attr.customTextR.attr.customColor分别是属性customTextcustomColor的资源ID。

    在使用MyView时,我们可以在layout文件中为MyView设置customText和customColor两个XML属性。layout文件如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.ispring.attr.MainActivity">
    
        <com.ispring.attr.MyView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:customText="Hello World!"
            app:customColor="#FF0000FF"
            />
    
    </RelativeLayout>

    运行效果如下所示:
    这里写图片描述

    可以看出在界面上显示了蓝色的“Hello World!”文本,说明MyView的自定义属性起作用了。

    我们看一下MyView的具体实现,MyView的代码如下所示:

    package com.ispring.attr;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.text.TextPaint;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class MyView extends View {
        //存储要显示的文本
        private String mCustomText;
        //存储文本的显示颜色
        private int mCustomColor = 0xFF000000;
        //画笔
        private TextPaint mTextPaint;
        //字体大小
        private float fontSize = getResources().getDimension(R.dimen.fontSize);
    
        public MyView(Context context) {
            super(context);
            init(null, 0);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs, 0);
        }
    
        public MyView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(attrs, defStyle);
        }
    
        private void init(AttributeSet attrs, int defStyle) {
            //首先判断attrs是否为null
            if(attrs != null){
                //获取AttributeSet中所有的XML属性的数量
                int count = attrs.getAttributeCount();
                //遍历AttributeSet中的XML属性
                for(int i = 0; i < count; i++){
                    //获取attr的资源ID
                    int attrResId = attrs.getAttributeNameResource(i);
                    switch (attrResId){
                        case R.attr.customText:
                            //customText属性
                            mCustomText = attrs.getAttributeValue(i);
                            break;
                        case R.attr.customColor:
                            //customColor属性
                            //如果读取不到对应的颜色值,那么就用黑色作为默认颜色
                            mCustomColor = attrs.getAttributeIntValue(i, 0xFF000000);
                            break;
                    }
                }
            }
    
            //初始化画笔
            mTextPaint = new TextPaint();
            mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
            mTextPaint.setTextSize(fontSize);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            if(mCustomText != null && !mCustomText.equals("")){
                mTextPaint.setColor(mCustomColor);
                //将文本绘制显示出来
                canvas.drawText(mCustomText, 0, fontSize, mTextPaint);
            }
        }
    }

    我们在MyView中定义了两个成员变量mCustomText和mCustomColor。MyView的几个构造函数都会调用init方法,我们重点看一下init方法。

    • 传递给init方法的是一个AttributeSet对象,可以把它看成一个索引数组,这个数组里面存储着属性的索引,通过索引可以得到XML属性名和属性值。

    • 通过调用AttributeSet的getAttributeCount()方法可以获得XML属性的数量,然后我们就可以在for循环中通过索引遍历AttributeSet的属性名和属性值。AttributeSet中有很多getXXX方法,一般必须的参数都是索引号,说几个常用的方法:

      • 通过AttributeSet的public abstract String getAttributeName (int index)方法可以得到对应索引的XML属性名。

      • 通过AttributeSet的public abstract int getAttributeNameResource (int index)方法可以得到对应索引的XML属性在R.attr中的资源ID,例如R.attr.customText、R.attr.customColor。

      • 如果index对应的XML属性的format是string,那么通过AttributeSet的public abstract String getAttributeName (int index)方法,可以得到对应索引的XML属性的值,该方法返回的是String。除此之外,AttributeSet还有getAttributeIntValue、getAttributeFloatValue、getAttributeListValue等方法,返回不同类型的属性值。

    • 我们通过attrs.getAttributeNameResource(i)得到获取attr的资源ID,然后对attrResId进行switch判断:

      • 如果是R.attr.customText,表示当前属性是customText,我们通过attrs.getAttributeValue(i)读取customText属性值,并将其赋值给成员变量mCustomText。

      • 如果是R.attr.customColor,表示当前属性是customColor,由于Android中用一个4字节的int型整数表示颜色,所以我们通过attrs.getAttributeIntValue(i, 0xFF000000)读取了customColor的颜色值,并将其赋值给成员变量mCustomColor。

    • 我们重写了MyView的onDraw方法,通过执行mTextPaint.setColor(mCustomColor)把画笔设置成mCustomColor的颜色,通过执行canvas.drawText(mCustomText, 0, fontSize, mTextPaint)将mCustomText绘制到界面上。这样,MyView就使用了customText和customColor这两个XML属性。


    使用<declare-styleable>和obtainStyledAttributes方法

    我们上面定义的customText和customColor这两个<attr>属性都是直接在<resources>节点下定义的,这样定义<attr>属性存在一个问题:不能想通过style或theme设置这两个属性的值。

    要想能够通过style或theme设置XML属性的值,需要在<resources>节点下添加<declare-styleable>节点,并在<declare-styleable>节点下定义<attr>,如下所示:

    <resources>
        <declare-styleable name="MyView">
            <attr name="customText" format="string" />
            <attr name="customColor" format="color" />
        </declare-styleable>
    </resources>

    需要给<declare-styleable>设置name属性,一般name设置为自定义View的名字,我们此处设置为MyView。

    <declare-styleable>下面定义的<attr>属性与直接在<resources>定义的<attr>属性其实本质上没有太大区别,无论哪种方式定义<attr>,都会在R.attr类中定义R.attr.customText和R.attr.customColor。不同的是,<declare-styleable name="MyView">节点会在R.styleable这个内部类中有如下定义:
    这里写图片描述

    R.styleable.MyView是一个int数组,其值为0x7f010038和 0x7f010039。0x7f010038就是属性R.attr.customText,0x7f010039就是属性R.attr.customColor。也就是R.styleable.MyView等价于数组[R.attr.customText, R.attr.customColor]。R.styleable.MyView的作用会在下面介绍。

    我们同样可以在R.styleable中发现R.styleable.MyView_customColor和R.styleable.MyView_customText这两个ID。<declare-styleable name="MyView">中的name加上里面的<attr>属性的name就组成了R.styleable中的MyView_customColor和MyView_customText,中间以下划线连接。如下图所示:

    这里写图片描述

    其中R.styleable.MyView_customColor对应R.attr.customColor,R.styleable.MyView_customText对应R.attr.customText。MyView_customColor和MyView_customText的作用在下面介绍。

    <declare-styleable>中定义的<attr>在MyView中需要通过调用theme的obtainStyledAttributes方法来读取解析属性值。obtainStyledAttributes有三个重载方法,签名分别如下所示:

    • public TypedArray obtainStyledAttributes (int[] attrs)

    • public TypedArray obtainStyledAttributes (int resid, int[] attrs)

    • public TypedArray obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)

    我们先看第三个最复杂的方法,在MyView中使用方法如下所示:

    private void init(AttributeSet attributeSet, int defStyle) {
            //首先判断attributeSet是否为null
            if(attributeSet != null){
                //获取当前MyView所在的Activity的theme
                Resources.Theme theme = getContext().getTheme();
                //通过theme的obtainStyledAttributes方法获取TypedArray对象
                TypedArray typedArray = theme.obtainStyledAttributes(attributeSet, R.styleable.MyView, 0, 0);
                //获取typedArray的长度
                int count = typedArray.getIndexCount();
                //通过for循环遍历typedArray
                for(int i = 0; i < count; i++){
                    //通过typedArray的getIndex方法获取指向R.styleable中对应的属性ID
                    int styledAttr = typedArray.getIndex(i);
                    switch (styledAttr){
                        case R.styleable.MyView_customText:
                            //如果是R.styleable.MyView_customText,表示属性是customText
                            //通过typedArray的getString方法获取字符串值
                            mCustomText = typedArray.getString(i);
                            break;
                        case R.styleable.MyView_customColor:
                            //如果是R.styleable.MyView_customColor,表示属性是customColor
                            //通过typedArray的getColor方法获取整数类型的颜色值
                            mCustomColor = typedArray.getColor(i, 0xFF000000);
                            break;
                    }
                }
                //在使用完typedArray之后,要调用recycle方法回收资源
                typedArray.recycle();
            }
    
            ...
        }

    我们在res/valeus/styles.xml文件中定义了如下style:

    <style name="RedStyle">
            <item name="customText">customText in RedStyle</item>
            <!-- 红色 -->
            <item name="customColor">#FFFF0000</item>
        </style>

    然后我们在layout文件中将MyView的style属性设置为上面的style,如下所示:

    <com.ispring.attr.MyView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:customText="customText in AttributeSet"
            style="@style/RedStyle"
            />

    运行效果如下所示:
    这里写图片描述

    我们虽然没有直接设置MyView的customText和customColor两个属性,但是通过设置style属性之后,在效果上RedStyle中所定义的属性值应用到了MyView上了。

    下面我们就来解释一下init方法:

    • 首先我们通过getContext().getTheme()获取到了当前MyView所在的Activity的theme。

    • 然后调用方法theme.obtainStyledAttributes(attributeSet, R.styleable.MyView, 0, 0),该方法返回一个TypedArray对象。TypedArray是一个数组,通过该数组可以获取应用了style和theme的XML属性值。上面这个方法有四个参数,后面两个参数都是0,大家暂且忽略不计,后面会介绍。第一个参数还是AttributeSet对象,第二个参数是一个int类型的数组,该数组表示想要获取的属性值的属性的R.attr中的ID,此处我们传入的是R.styleable.MyView,在上面我们已经提到其值等价于[R.attr.customText, R.attr.customColor],表示我们此处想获取customText和customColor这两个属性的值。

    • 如果在layout文件中直接为MyView设置了某些XML属性,那么这些XML属性及其属性值就会出现在AttributeSet中,那么Android就会直接使用AttributeSet中该XML属性值作为theme.obtainStyledAttributes()的返回值,比如在上面的例子中,我们通过app:customText="customText in AttributeSet"设置了MyView的XML属性,最终运行的效果显示的也是文本”customText in AttributeSet”。

    • 如果在layout文件中没有为MyView设置某个XML属性,但是给MyView设置了style属性,例如style="@style/RedStyle",并且在style中指定了相应的XML属性,那么Android就会用style属性所对应的style资源中的XML属性值作为theme.obtainStyledAttributes()的返回值。比如在上面的例子中,我们在layout文件中没有设置app:customColor的值,但是在其style属性所对应的RedStyle资源中将customColor设置成了红色#FFFF0000,最终文本也是以红色显示在界面上的。

    通过以上描述,我们可以知道,View的style属性对应的style资源中定义的XML属性值其实是View直接在layou文件中定义XML属性值的替补值,是用于补漏的,AttributeSet(即在layout中直接定义XML属性)的优先级高于style属性中资源所定义的属性值。


    obtainStyledAttributes方法之defStyleAttr

    我们再看一下方法obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)中的第三个参数defStyleAttr,这个参数表示的是一个<style>中某个属性的ID,当Android在AttributeSet和style属性所定义的style资源中都没有找到XML属性值时,就会尝试查找当前theme(theme其实就是一个<style>资源)中属性为defStyleAttr的值,如果其值是一个style资源,那么Android就会去该资源中再去查找XML属性值。可能听起来比较费劲,我们举个例子。

    我们更改了values/styles.xml文件,如下所示:

    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <item name="myViewStyle">@style/GreenStyle</item>
        </style>
    
        <style name="GreenStyle">
            <item name="customText">customText in GreenStyle</item>
            <item name="customColor">#FF00FF00</item>
        </style>
    
        <style name="HelloWorldStyle">
            <item name="customText">Hello World!</item>
        </style>
    
        <style name="RedStyle">
            <item name="customText">customText in RedStyle</item>
            <item name="customColor">#FFFF0000</item>
        </style>
    
    </resources>
    

    我们添加了HelloWorldStyle和GreenStyle,其中HelloWorldStyle只定义了customText的属性值,而GreenStyle同时定义了customText和customColor的值,其中customColor定义为绿色。

    在AppTheme中,我们设置了myViewStyle这个属性的值,如下所示:

    <item name="myViewStyle">@style/GreenStyle</item>

    myViewStyle这个属性是在values/attrs_my_view.xml中定义的,如下所示:

    <resources>
        <attr name="myViewStyle" format="reference" />
        <declare-styleable name="MyView">
            <attr name="customText" format="string" />
            <attr name="customColor" format="color" />
        </declare-styleable>
    </resources>

    myViewStyle被定义为一个reference格式,即其值指向一个资源类型,我们在AppTheme中将其赋值为@style/GreenStyle,即在AppTheme中,myViewStyle的就是GreenStyle,其指向了一个style资源。

    我们更改MyView代码,如下所示:

    //通过theme的obtainStyledAttributes方法获取TypedArray对象
                TypedArray typedArray = theme.obtainStyledAttributes(attributeSet, R.styleable.MyView, R.attr.myViewStyle, 0);

    注意,上面obtainStyledAttributes方法最后一个参数还是为0,可以忽略,但是第三个参数的值不再是0,而是R.attr.myViewStyle。

    然后我们更新layout文件,如下所示:

    <com.ispring.attr.MyView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            style="@style/HelloWorldStyle"
            />

    我们为MyView设置了style属性,其值为HelloWorldStyle。

    程序运行效果如下所示:
    这里写图片描述

    我们发现结果是绿色的“Hello World!”,我们解释一下原因。

    • 由于这次我们没有通过layout文件直接设置MyView的XML属性的值,所以AttributeSet本身是没有XML属性值的,我们直接忽略掉AttributeSet。

    • 我们通过style="@style/HelloWorldStyle"为MyView设置了style为HelloWorldStyle,HelloWorldStyle中定义customText的属性值为”Hello World!”,所以最终customText的值就是”Hello World!”,在界面上显示的也是该值。

    • HelloWorldStyle中并没有定义customColor属性值。我们将theme.obtainStyledAttributes()方法的第三个参数设置为R.attr.myViewStyle,此处的theme就是我们上面提到的AppTheme,Android会去AppTheme中查找属性为myViewStyle的值,我们之前提到了,它的值就是@style/GreenStyle,即GreenStyle,由于该值是个style资源,Android就会去该资源中查找customColor的值,GreenStyle定义了customColor的颜色为绿色,所以MyView最终所使用的customColor的值就是绿色。

    综上,我们发现,此处的第三个参数的作用是:当在AttributeSet和style属性中都没有找到属性值时,就去Theme的某个属性(即第三个参数)中查看其值是否是style资源,如果是style资源再去这个style资源中查找XML属性值作为替补值。


    obtainStyledAttributes方法之defStyleRes

    最后我们看一下方法obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)中的第四个参数defStyleRes。与defStyleAttr类似,defStyleRes是前面几项的替补值,defStyleRes的优先级最低。与defStyleAttr不同的是,defStyleRes本身直接表示一个style资源,而theme要通过属性defStyleAttr间接找到style资源。

    我们添加了BlueStyle这个style,如下所示:

    <style name="BlueStyle">
        <item name="customText">customText in BlueStyle</item>
        <item name="customColor">#FF0000FF</item>
    </style>

    并将layout文件改为如下所示:

    <com.ispring.attr.MyView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />

    我们更改MyView代码如下所示:

    TypedArray typedArray = theme.obtainStyledAttributes(attributeSet, R.styleable.MyView, 0, R.style.BlueStyle);

    第三个参数设置为0,第四个参数不再是0,而是R.style.BlueStyle。运行界面如下所示:
    这里写图片描述

    只有第三个参数defStyleAttr为0或者该属性在theme中找不到时,才会使用第四个参数defStyleRes。如果第三个参数defStyleAttr不为0,但是theme的defStyleAttr所对应的属性值中的style没有定义任何XML属性值,那么第四个参数也不会defStyleRes被使用。


    总结

    • 可以不通过<declare-styleable>节点定义XML属性,不过还是建议将XML属性定义在<declare-styleable>节点下,因为这样Android会在R.styleable下面帮我们生成很多有用的常量供我们直接使用。

    • obtainStyledAttributes方法中,优先级从高到低依次是:直接在layout中设置View的XML属性值(AttributeSet) > 设置View的style属性 > defStyleAttr > defStyleRes

    希望本文对大家理解与使用自定义XML属性有所帮助!

    相关阅读:
    我的Android博文整理汇总

    展开全文
  • XML指南——XML 属性

    千次阅读 2005-04-12 13:08:00
    XML属性XML元素可以拥有属性。你一定还记得这样的HTML代码吧: 。src是img元素的属性,提供了关于img元素的额外信息。在HTML中 (在XML中也一样)元素的属性提供了元素的额外信息。书信提供的信息通常不是数据的一部分...
  • Android XML属性介绍

    千次阅读 2013-03-05 15:11:09
    在学习控件的过程中我们应该对一些常用的XML属性有更深入的理解,这有利于我们继续学习Android的高级技术。  1:android:id  如果要在代码或在XML布局文件中引用某个控件,该控件必须要设置android:id的属性-@id/...
  • JAVA解析XML属性和属性值

    千次阅读 2019-06-28 11:14:13
    这篇文章主要是来读取XML属性。 引入jar包:dom4j-1.6.1.jar 代码如下: import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; ...
  • ANDROID中XML属性xmlns和tools作用

    千次阅读 2015-04-07 22:34:15
    ANDROID中XML属性xmlns和tools作用在布局文件中可以看到:xmlns:android="" xmlns:tools="" tools:context=".xxxActivity" 三个属性;其中xmlns全称xmlnamespace(命名空间) 命名空间的意义: tools:context的作用 ...
  • SQL SERVER XML属性

    千次阅读 2019-06-10 18:37:23
    sql操作xml数据的时候,有时候有要得到其属性值的需求,例子如下: DECLARE @x XML SET @x=' <root> <部位 ID="59" 名称="头颅"> <检查方法 ID="1" 名称="正位" /> <检查方法 ID="2" ...
  • python批量修改xml属性

    万次阅读 2018-01-25 21:48:26
    如何批量修改指定文件夹下的xml文件的指定属性.分三步走,首先,我们先看看如何读写单个 的xml文件;第二步,来看看如何遍历指定文件夹下的所有文件,获取到所有文件的文件名;第三步,我们来看看一二之间 该如何衔接.好,...
  • 用view的XML属性实现超链接

    千次阅读 2012-05-23 11:26:26
    Android 应用的 layout(UI 布局)除了直接改写程序代码的方式外(动态布局),也能...该功能的实现非常简单,我们只需要改写两行XML属性而已。 每一个View都有许多属性,我们可以通过XML来描述每一个View的属性,从而
  • Android XML属性在文档中的位置

    千次阅读 2010-09-08 10:48:00
    Android XML属性比较多,全部记住不太现实,用的时候查文档是一条途径。如何迅速找到所需的XML属性?   Android包下面android.R.styleable 类包含下面所有组件相关的XML属性。   如: ...
  • duilib控件 XML属性列表

    热门讨论 2013-10-08 22:23:13
    介绍了所有控件的所有属性,不过有一点点遗漏,需要去源码里查看~
  • C# 获取xml属性名称

    千次阅读 2015-06-18 09:55:03
    工作需要,读取一个超大量的xml文件,从xml文件中,读取节点,以及节点下的属性名称,用属性名称进行建表操作。 在网上查找资料未果,于是自己寻找办法。 在XmlElement类下有一个属性是Attributes,返回值为...
  • 给自定义View添加xml属性

    万次阅读 2016-08-04 11:17:10
    android 自定义控件(底部icon点击效果)笔者之前的文章中仅仅介绍了如何使用自定义View以及为什么要使用自定义View等等,但是在实际操作中,我们还是希望自定义View之后,直接能够在xml中就对其进行操作
  • MusicXML 属性解析 一

    千次阅读 2015-10-28 11:15:18
    将整体乐曲元素和属性信息表示为一份XML 文档,他克服了另外两种格式----NIFF 格式(基于图片)和SMDL 格式(过于庞大)的兼容性差,结构复杂等许多缺点,目前他已经被很多应用软件的支持。目前很多音
  • Object-C使用XML属性列表进行归档

    千次阅读 2012-07-30 15:44:51
    在Object-C术语中,归档是指用...Mac OS X上的应用程序使用XML属性列表(或plists)来存储诸如默认参数选择、应用程序设置和配置信息这样的数据。因此,了解如何创建和读回这些数据是很有用的。然而,这些列表的归档
  • Android中 xml 属性 fill_parent、warp_content、match_parent区别
  • Android屏幕的灰色透明背景蒙版的简单控制,不需要设置xml属性
  • 博客《Animation 动画详解(一)——alpha、scale、translate、rotate、set的xml属性及用法》对应源码,博客地址:http://blog.csdn.net/harvic880925/article/details/39996643
  • 下午一直找python修改xml标签内的属性值应该是怎么修改,总是差那么一点点都写不对这个函数,找到的博客大部分没有写这一步。这里记录一下,顺便有两篇优秀的博客。 解决这个问题的思路是我认为一定会有一个set方法...
  • 1.首先自定一个写一个xml文件,属性标签都是自定义,如下图:2.然后通过php的函数simplexml_load_file()加载xml文件,然后计算该自定义标签的名字,获取长度循环获取属性3.如果需要把对象数组$xml 转换成普通对象,...
  • <Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/self_destruct" android:onClick="selfDestruct" />

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,233,657
精华内容 493,462
关键字:

xml属性