XMLから属性値を読込む

Androidのビュー(View)における各種属性の初期化処理は、従来のJSC/Swingのように手続きで書くこともXMLで宣言的に書くこともできるが、重要なのは宣言的に書く方法だ。

標準的なビューはandroidネームスペースの語彙を使用して属性を設定できる。また、カスタムビューのようにAndroidネームスペース(パッケージ)に属さないビューは要素名に直接ビュークラスの完全修飾名を設定することで記述を行う。

  • project\layout\main.xml

    
       
       
    

この仕組みの一部を利用することで、カスタムビューも独自の属性をXMLに記述してビューに反映することができる。

拙作のCalendarViewではインフレート直後に表示する年月をXMLから読みこむことができるが、その属性値はXMLから"yyyy/mm"のフォーマットで入力された文字列を使用する。

    • CalendarView要素だけを抜粋
   
        date="2009/05"
   

Viewクラス及びそのサブクラスのコンストラクタは第二引数にAttributeSetインタフェースを取るコンストラクタを定義することが出来、それをオーバライドすることでXMLの属性を読込むことができる。

例えば上記のdate属性を読込むためには、CalendarViewのコンストラクタで以下のようなコードを書けば良い。

public CalendarView(Context context, AttributeSet attrs){
    super(context, attrs);
    //XMLから属性読み込み
    if ( attrs != null ) {
        try {
            String dateStr = attrs.getAttributeValue(null, "date");
            
            if ( dateStr != null && dateStr.length() > 0 ) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy/MM");
                Date date = format.parse(dateStr);
                this.setCalendar(date);
            }
            
        } catch (ParseException e) {
            //例外処理は省略
        }
    }
}

これでXMLから指定した年月をビュー内部のカレンダーに反映することが出来る。

ここまで書いて気がついたかもしれないが、上記のようにオリジナルな属性値をXMLに記述できるのならば、独自のネームスペースを使って、より分かり易く属性値を記述したいと思うだろう。事実、属性を読込むメソッド"getAttributeValue"の第一引数はネームスペースだ。

   
        kazz:date="2009/05"
   

しかし、この方法はネームスペースの宣言をするだけでは駄目で、このビューを定義しているパッケージと同一のパッケージのリソース中にattrs.xmlという名前で定義済みの"スタイル"の一部として属性の使用を宣言する必要がある。

Android SDKで提供されているLabelViewというカスタムビューに、独自のネームスペースでXML属性を宣言する例があり、やり方自体はこれを見て解ったのだが、正直面倒だし例によって他のパッケージから参照することができないようなので、私は使うのを諦めた。

  • ApiDemos\res\layout\custom_view_1.xml
app:text="Green" app:textColor="#ffffffff" />
  :
  • ApiDemos\res\values\attrs.xml

     
        
        
        
    


ちょっと癖はあるが、オリジナルのビューに対して追加した属性をXMLから読込んで設定できる仕組みがあるのは素晴らしいことだ。