2010年8月4日水曜日

layoutXMLファイルでViewのカスタム属性を定義

1. カスタム属性を定義する
res/values/attr.xmlで属性を定義する。
  <xml version="1.0" encoding="utf-8"?>
  <resources>
    <attr name="textValue1" format="string" />
    <attr name="textColor" format="color" />
  </resources>
attr.xmlを編集すると、R.attrクラス内に属性定数が自動的に作成される。
  public final class R {
      public static final class attr {
          public static final int textValue1=0x7f010000;
          public static final int textColor=0x7f010001;
      }
  }
定義した属性名は、AndroidManifest.xmlで設定されている名前空間 (=Rオブジェクトの名前空間) に属する。今回は com.testapp を想定。
ただ、組み込みで大量の属性が用意されている (R.attr) ため、大抵の場合は自前で用意しなくてもいい気がする。

2. 属性を設定する
res/layout/main.xmlでViewに属性を設定する。TestView要素の属性のうち、tes名前空間のものがユーザー定義、android名前空間のものが組み込み。
  <?xml version="1.0" encoding="utf-8"?>
  <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tes="http://schemas.android.com/apk/res/com.testapp"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      >
  <com.testapp.view.TestView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
     
      android:text="aaa"
      android:textSize="15pt"
     
      tes:textValue1="test1"
      tes:textColor="#FFFFFF"
    />
  <com.testapp.view.TestView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
     
      android:text="aaa"
      android:textSize="4pt"
     
      tes:textValue1="test2"
      tes:textColor="#FFFFFF"
    />
  </LinearLayout>

3. 属性を読み込む
res/values/attr.xmlで、属性の配列を定義する。
属性の配列は、複数の属性を一括して読み込むため?に、複数の属性をまとめたもの。

android:textおよびandroid:textSizeは、Viewクラスでは読み込めない属性なので、TestView側で読み込み処理を書く必要がある。よって、styleableオブジェクトに含める。
  <?xml version="1.0" encoding="utf-8"?>
  <resources>

    <attr name="textValue1" format="string" />
    <attr name="textColor" format="color" />

    <!--属性の配列の定義-->
    <declare-styleable name="TestViewSet">
   
      <!--組み込みの属性-->
      <attr name="android:text" />
      <attr name="android:textSize" />
     
      <!--ユーザー定義の属性-->
      <attr name="textValue1" />
      <attr name="textColor" />
     
    </declare-styleable>

    <!--複数定義可能なことを例示するために記載-->
    <declare-styleable name="TestViewSet2">
      <attr name="android:text" />
      <attr name="textColor" />
    </declare-styleable>
   
  </resources>
R.styleable内に定義した情報が反映されていることを確認する。
  public final class R {
    public static final class styleable {
       
      //context.obtainStyledAttributes用のattr値配列
      public static final int[] TestViewSet = {
        0x01010095, 0x0101014f, 0x7f010000, 0x7f010001
      };
     
      //obtainStyledAttributesで取得したTypedArray内での、各属性のindex値
      public static final int TestView_android_text = 1;
      public static final int TestView_android_textSize = 0;
      public static final int TestView_textColor = 3;
      public static final int TestView_textValue1 = 2;
     
      //複数定義すれば、複数作成される
      public static final int[] TestViewSet2 = {
        0x0101014f, 0x7f010001
      };
      public static final int ViewBase_android_text = 0;
      public static final int ViewBase_textColor = 1;
    };
  }
TestViewクラスで読み込む
  /**
   * コンストラクタ
   */
  public TestView(Context context, AttributeSet attrs, int defStyle)
  {
    super(context, attrs, defStyle);

    //このオブジェクト用の属性セットを取得
    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TestViewSet, defStyle, defStyle);

    //android:text(string)を取得
    ta.getString(R.styleable.TestViewSet_android_text);
   
    //android:textSize(dimension)を取得
    ta.getDimension(R.styleable.TestViewSet_android_textSize, 15f);
   
    //textVaelue1(string)を取得
    ta.getString(R.styleable.TestViewSet_textVaelue1);

    //textColor(color)を取得
    ta.getColor(R.styleable.TestViewSet_textColor, Color.BLUE);
  }

0 件のコメント:

コメントを投稿