Android View(4)-View関連プロパティの詳細

17070 ワード

カスタムビューを使用すると、AttributeSet、TypedArray、declare-styleableなどのプロパティに遭遇する可能性がありますが、今日はこれらのプロパティがどういう意味なのかよく見てみましょう.
一.AttributeSet
1.sdkドキュメントがどのように述べられているかを見てみましょう.
A collection of attributes, as found associated with a tag in an XML document.
 Often you will not want to use this interface directly, instead passing it to Resources.
 Theme.obtainStyledAttributes() which will take care of parsing the attributes for you. 
 In particular, the Resources API will convert resource references 
 (attribute values such as "@string/my_label" in the original XML) to the desired type for you; 
 if you use AttributeSet directly then you will need to manually check for resource references 
 (with getAttributeResourceValue(int, int)) and do the resource lookup yourself if needed.
 Direct use of AttributeSet also prevents the application of themes and styles when retrieving attribute values.

xmlドキュメントでラベルと結合された属性セットです.通常、このインタフェースを直接使用するつもりはありません.代わりに、Resources.Theme.obtainStyledAttributes()という方法に渡します.この方法は、中の属性を解析します.具体的には、Resources APIは、変換リソース参照(属性値、例えば、 「@string/my_label」は元のxml)に必要なタイプです.AttributeSetを直接使用する場合は、リソースリファレンス(getAttributeResourceValue(int,int))とリソース検索を手動で確認する必要があります.アトリビュート値を取得するときに、AttributeSetを直接使用すると、アプリケーションのトピックとスタイルがブロックされる可能性があります.
This interface provides an efficient mechanism for retrieving data from compiled XML files, 
 which can be retrieved for a particular XmlPullParser through Xml.asAttributeSet(). 
 Normally this will return an implementation of the interface that works on top of 
 a generic XmlPullParser, however it is more useful in conjunction with compiled XML resources:
 XmlPullParser parser = resources.getXml(myResource);
 AttributeSet attributes = Xml.asAttributeSet(parser);

このインタフェースは、Xml.asAttributeSet()によって特定のXmlPullParserに渡されて取得されるコンパイルされたxmlファイルからデータを取得するための有効な機能を提供します.通常、汎用XmlPullParserベースのインタフェース実装が返されますが、コンパイルされたxmlリソースと組み合わせるとより便利です.
The implementation returned here, unlike using the implementation on top of a generic XmlPullParser, 
is highly optimized by retrieving pre-computed information that was generated by aapt 
when compiling your resources. For example, the getAttributeFloatValue(int, float)
 method returns a floating point number previous stored in the compiled resource 
 instead of parsing at runtime the string originally in the XML file.

This interface also provides additional information contained in the 
compiled XML resource that is not available in a normal XML file, 
such as getAttributeNameResource(int) which returns the resource 
identifier associated with a particular XML attribute name.

インプリメンテーションはここに戻って、汎用XmlPullParserの上で使用されるインプリメンテーションとは異なり、リソースをコンパイルするときにaaptから推定情報を取得するために高度に最適化されています.たとえば、getAttributeFloatValue(int,float)という方法は、実行時に元のxmlファイルの文字列を解析するのではなく、以前のコンパイル済みリソースに浮動小数点数を格納することを返します.
このインタフェースはまた、getAttributeNameResource(int)などの通常のxmlファイルでコンパイルされたxmlリソースに含まれていない追加情報を提供し、特定のxml属性名に関連付けられたリソース識別子を返します.
2.ソースコードをもう一度見てください.
public interface AttributeSet {
    /**
     * Returns the number of attributes available in the set.
     * 
     * @return A positive integer, or 0 if the set is empty.
     */
    public int getAttributeCount();
    ...
    /**
     * Return the integer value of attribute at 'index' that is formatted as an
     * unsigned value.  In particular, the formats 0xn...n and #n...n are
     * handled.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public int getAttributeUnsignedIntValue(int index, int defaultValue);
    /**
     * Return the float value of attribute at 'index'.
     * 
     * @param index Index of the desired attribute, 0...count-1.
     * @param defaultValue What to return if the attribute isn't found.
     * 
     * @return Resulting value.
     */
    public float getAttributeFloatValue(int index, float defaultValue);

    /**
     * Return the value of the "id" attribute or null if there is not one.
     * Equivalent to getAttributeValue(null, "id").
     * 
     * @return The id attribute's value or null.
     */
    public String getIdAttribute();
    /**
     * Return the value of the "class" attribute or null if there is not one.
     * Equivalent to getAttributeValue(null, "class").
     * 
     * @return The class attribute's value or null.
     */
    public String getClassAttribute();

    ...
}


これがAttributeSetインタフェースの定義です.
公式サイトの説明によると、AttributeSetはこのようにして得られたことがわかります.
XmlPullParser parser = resources.getXml(myResource);
 AttributeSet attributes = Xml.asAttributeSet(parser);

では、xml.asAttributeSet(XmlPullParser parser)がどのように実現されているかを見てみましょう.
 public static AttributeSet asAttributeSet(XmlPullParser parser) {
        return (parser instanceof AttributeSet)
                ? (AttributeSet) parser
                : new XmlPullAttributes(parser);
    }

AttributeSet実装を返します.
XmlPullAttributesは、XmlPullParserパラメータを伝達し、コードを具体的に見ると、AttributeSetインタフェースを実装します.
class XmlPullAttributes implements AttributeSet {
    public XmlPullAttributes(XmlPullParser parser) {
        mParser = parser;
    }
    public int getAttributeCount() {
        return mParser.getAttributeCount();
    }

    public String getAttributeName(int index) {
        return mParser.getAttributeName(index);
    }

    public String getAttributeValue(int index) {
        return mParser.getAttributeValue(index);
    }

    public String getAttributeValue(String namespace, String name) {
        return mParser.getAttributeValue(namespace, name);
    }

    public String getPositionDescription() {
        return mParser.getPositionDescription();
    }
    ...
    /*package*/ XmlPullParser mParser;
}


コードは比較的簡単で、渡されたパラメータXmlPullParserから対応する値を取得します.
ここで、上述したように、AttributeSetにはxmlファイルで定義した属性と属性値が含まれており、集合であることがわかります.
二.TypedArray
1.まずsdkファイルの紹介を見てみましょう.
Container for an array of values that were retrieved with 
obtainStyledAttributes(AttributeSet, int[], int, int) or obtainAttributes(AttributeSet, int[]). 
Be sure to call recycle() when done with them. The indices used to retrieve values from this
structure correspond to the positions of the attributes given to obtainStyledAttributes.

obtainStyledAttributes(AttributeSet,int[],int,int)またはobtainAttributes(AttributeSet,int[])から取得した配列コンテナ(両方のメソッドのパラメータにはAttributeSetがあります).使用済み時にrecycle()を呼び出すことを忘れないでください. 方法.このインデックスは、構造の対応する位置の属性から値兵を取得してobtainStyledAttributesに付与するために使用されます.
2.ソースコードの例.
public class TypedArray {

private final Resources mResources;
    /*package*/ XmlBlock.Parser mXml;
    /*package*/ int[] mRsrcs;
    /*package*/ int[] mData;
    /*package*/ int[] mIndices;
    /*package*/ int mLength;
    /*package*/ TypedValue mValue = new TypedValue();
  /**
     * Return the number of values in this array.
     */
    public int length() {
        return mLength;
    }
    
    /**
     * Return the number of indices in the array that actually have data.
     */
    public int getIndexCount() {
        return mIndices[0];
    }
    
    /**
     * Return an index in the array that has data.
     * 
     * @param at The index you would like to returned, ranging from 0 to
     * {@link #getIndexCount()}.
     * 
     * @return The index at the given offset, which can be used with
     * {@link #getValue} and related APIs.
     */
    public int getIndex(int at) {
        return mIndices[1+at];
    }
...
}

中にはgetの方法があります.
三.declare-styleable
1.まず、公式サイトがどのように紹介されているかを見てみましょう.
 To define custom attributes, add <declare-styleable> resources to your project.
 It's customary to put these resources into a res/values/attrs.xml file. 
 Here's an example of an attrs.xml file:

<resources>
   <declare-styleable name="PieChart">
       <attr name="showText" format="boolean" />
       <attr name="labelPosition" format="enum">
           <enum name="left" value="0"/>
           <enum name="right" value="1"/>
       </attr>
   </declare-styleable>
</resources>
This code declares two custom attributes, showText and labelPosition, that belong to 
a styleable entity named PieChart. The name of the styleable entity is, 
by convention, the same name as the name of the class that defines the custom view.
 Although it's not strictly necessary to follow this convention, many popular 
 code editors depend on this naming convention to provide statement completion.

カスタムプロパティを定義するには、プロジェクトにリソースを追加する必要があります.通常、これらのリソースはres/values/attrs.xmlファイルに配置されます.attrs.xmlファイルの例:...
このコードは2つのカスタム属性を宣言します.  showText  および  labelPositionは、PieChartというスタイルエンティティに属します.スタイルエンティティの名前です.通常、名前はカスタムViewのクラス名と同じです.これは厳密に従わなければならない制約ではありませんが、多くのポピュラーなコードエディタは、この命名規則に依存して構文を提供しています.
Android frameworkソースattrs.xmlのコードでどのように使用されているかを見てみましょう.
        <declare-styleable name="TextView">
        ...
        <!-- Text color. -->
        <attr name="textColor" />
        <!-- Color of the text selection highlight. -->
        <attr name="textColorHighlight" />
        <!-- Color of the hint text. -->
        <attr name="textColorHint" />
        <!-- Base text color, typeface, size, and style. -->
        <attr name="textAppearance" />
        <!-- Size of the text. Recommended dimension type for text is "sp" for scaled-pixels (example: 15sp). -->
        <attr name="textSize" />
        <!-- Sets the horizontal scaling factor for the text. -->
        <attr name="textScaleX" format="float" />
        <!-- Typeface (normal, sans, serif, monospace) for the text. -->
        <attr name="typeface" />
        <!-- Style (bold, italic, bolditalic) for the text. -->
        <attr name="textStyle" />
        <!-- Text color for links. -->
        <attr name="textColorLink" />
        <!-- Makes the cursor visible (the default) or invisible. -->
        <attr name="cursorVisible" format="boolean" />
        <!-- Makes the TextView be at most this many lines tall. -->
        <attr name="maxLines" format="integer" min="0" />
        <!-- Makes the TextView be at most this many pixels tall. -->
        <attr name="maxHeight" />
        <!-- Makes the TextView be exactly this many lines tall. -->
        <attr name="lines" format="integer" min="0" />
        <!-- Makes the TextView be exactly this many pixels tall.
             You could get the same effect by specifying this number in the
             layout parameters. -->
        <attr name="height" format="dimension" />
        <!-- Makes the TextView be at least this many lines tall. -->
        <attr name="minLines" format="integer" min="0" />
        <!-- Makes the TextView be at least this many pixels tall. -->
        <attr name="minHeight" />
        <!-- Makes the TextView be at most this many ems wide. -->
        <attr name="maxEms" format="integer" min="0" />
        <!-- Makes the TextView be at most this many pixels wide. -->
        <attr name="maxWidth" />
        <!-- Makes the TextView be exactly this many ems wide. -->
        <attr name="ems" format="integer" min="0" />
        <!-- Makes the TextView be exactly this many pixels wide.
             You could get the same effect by specifying this number in the
             layout parameters. -->
        <attr name="width" format="dimension" />
        <!-- Makes the TextView be at least this many ems wide. -->
        <attr name="minEms" format="integer" min="0" />
        <!-- Makes the TextView be at least this many pixels wide. -->
        <attr name="minWidth" />
        ...
    </declare-styleable>
	 <declare-styleable name="TextViewAppearance">
        <!-- Base text color, typeface, size, and style. -->
        <attr name="textAppearance" />
    </declare-styleable>
	...

 ラベルは、Viewを使用するときにプロパティを設定するために使用されるViewのプロパティを定義します.したがって、ビューのプロパティをカスタマイズするときに使用します.このラベルを使用してプロパティを設定する場合は、formatでプロパティのタイプを指定する必要があります.プロパティのタイプは次のようになります.
1. reference:    。
2. color:   。
3. boolean:   。
4. dimension:   。
5. float:   。
6. integer:   。
7. string:   。
8. fraction:   。
9. enum:   。
10. flag:    。

上記の説明を経て、この3つの一般的なプロパティまたはラベルについてよく知っています.次に、TextViewのソースコードを通じて、これらのプロパティが具体的にどのように使用されているかを見てみましょう.
四.TextView
1.ソースコード.
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
        ...
        public TextView(Context context,
                    AttributeSet attrs,
                    int defStyle) {
        super(context, attrs, defStyle);
         ...
         //   View   
        final Resources.Theme theme = context.getTheme();
        /*
         * Look the appearance up without checking first if it exists because
         * almost every TextView has one and it greatly simplifies the logic
         * to be able to parse the appearance first and then let specific tags
         * for this View override it.
         */
        //       ,  obtainStyledAttributes  TypedArray 
        TypedArray a = theme.obtainStyledAttributes(
                    attrs, com.android.internal.R.styleable.TextViewAppearance, defStyle, 0);
        TypedArray appearance = null;
		//  index       
        int ap = a.getResourceId(
                com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);
        a.recycle();//    ,  recycle()
        if (ap != -1) {
		//       TextView       
            appearance = theme.obtainStyledAttributes(
                    ap, com.android.internal.R.styleable.TextAppearance);
        }
		//         
        if (appearance != null) {
            int n = appearance.getIndexCount();
            for (int i = 0; i < n; i++) {
                int attr = appearance.getIndex(i);

                switch (attr) {
                case com.android.internal.R.styleable.TextAppearance_textColorHighlight:
                    textColorHighlight = appearance.getColor(attr, textColorHighlight);
                    break;
              
                case com.android.internal.R.styleable.TextAppearance_textColor:
                    textColor = appearance.getColorStateList(attr);
                    break;
              
                case com.android.internal.R.styleable.TextAppearance_textColorHint:
                    textColorHint = appearance.getColorStateList(attr);
                    break;
                
                case com.android.internal.R.styleable.TextAppearance_textColorLink:
                    textColorLink = appearance.getColorStateList(attr);
                    break;
               
                case com.android.internal.R.styleable.TextAppearance_textSize:
                    textSize = appearance.getDimensionPixelSize(attr, textSize);
                    break;

                case com.android.internal.R.styleable.TextAppearance_typeface:
                    typefaceIndex = appearance.getInt(attr, -1);
                    break;

                case com.android.internal.R.styleable.TextAppearance_textStyle:
                    styleIndex = appearance.getInt(attr, -1);
                    break;

                case com.android.internal.R.styleable.TextAppearance_textAllCaps:
                    allCaps = appearance.getBoolean(attr, false);
                    break;
                }
            }
            appearance.recycle();
       ...
}
}

コードは比較的多く、TextViewの3つのパラメータの構造方法(コードの中でnewの1つのTextViewであってもxmlレイアウトファイルの中でTextViewを使用しても、最終的には3つのパラメータを呼び出す構造方法)の1つのコードのみを羅列しており、AttributeSet attrsは外部から渡されている(Xml.asAttributeSet(parser);).TypedArrayはtheme.obtainStyledAttributes()メソッドで取得され、textViewのプロパティはattrs.xmlで定義されたプロパティから取得されます.
    これで、ソースコードでこれらの属性の解釈と使用を大まかに理解し、あなたも新しい認識を持っていると信じています.みんなに役に立つことを望みます!(本人のレベルは限られていますが、間違いがある場合は、ご指摘ください)