17 -2 -6
外部 ライ ブラ リー の利 と用 作成 17第 章
ライブラリーが定義しているカスタム属性を知るには
UIコンポーネントを提供するライブラリーでは、カスタム属性を定義している場合 が多いです。ライブラリーが定義しているカスタム属性を知る方法として以下が挙げ られます。
・ ドキュメントを読む
・ ソースを読む
基本的にまずはドキュメントを探して読むことになるでしょう。例えば「Android-Bootstrap」の「BootstrapButton」の使い方は以下のページに解説がありま す。
・ Bootstrap Button:https://github.com/Bearded-Hen/Android-Bootstrap/wiki/Bootstrap-Button
「Android-Bootstrap」には比較的ていねいなドキュメントが揃っていますが、
中にはドキュメントがなかったり、カスタム属性についての記述が不足しているライブ ラリーもあります。参考になるドキュメントがない場合は、ライブラリーのソースを読んで
調べることになります。
ソースを読んでカスタム属性を理解する
Eclipseにインポートした「Android-Bootstrap」の中を覗いて、「Bootstrap Button」クラスのカスタム属性について調べてみましょう。「Android-Bootstrap」
の「res/values/attrs.xml」を開いてください(図23)。
図22:カスタム 属性
「bb̲type」を「dang er」に変更した結果
リスト17に「attrs.xml」ファイルの冒頭部分を抜粋します。 「declare-styleable」要素の「name」属性に「BootstrapButton」という記述があります。
これは「BootstrapButton」のカスタム属性の宣言を表します。 「declare-styleable」要素の中に複数の「attr」要素を持っています。「attr」要素には属 性名と、それに対して指定できる値の種類を定義しています。
図23: 「Android-Bootstrap」の「att rs.xml」を開く
リスト17:AndroidBootstrap-attr.xml(冒頭部分)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="BootstrapButton">
<attr name="bb_type" format="string"/>
<attr name="bb_icon_left" format="string"/>
<attr name="bb_icon_right" format="string"/>
<attr name="bb_roundedCorners" format="boolean"/>
<attr name="bb_text_alignment" format="string"/>
<attr name="bb_size" format="string"/>
<attr name="bb_text_gravity" format="string"/>
<attr name="android:textSize"/>
<attr name="android:text"/>
<attr name="android:enabled"/>
<attr name="android:layout_width"/>
</declare-styleable>
<!-- 省略 -->
外部 ライ ブラ リー の利 と用 作成 17第 章
これで「BootstrapButton」の持つカスタム属性はわかりました。次はこれらの 属性がどのように使われているかを調べます。すべて調べるのは大変なので、代表と して「bb̲type」属性がどのように使われているかを「BootstrapButton」クラスの ソースコードを読んで確認してみましょう。「BootstrapButton」クラスは「src/
com/beardedhen/androidbootstrap/BootstrapButton.java」で定義され ています(図24)。
「BootstrapButton.java」を開き、「bb̲type」をキーにしてソースコード内を検 索をすると、140行目に「bb̲type」属性を扱う処理が見つかります(リスト18)。
将来変更される可能性があるので、ソースコードのハッシュ値を記載しておきま す。「9067416920a2a9a000a77280010fdc580aaf06b1」
カスタム属性を定義すると、Rクラスの「styleable」にIDが追加されます。ID名 は「declare-styleable」要素で定義した「name」属性と「attr」要素の
「name」属性を「̲」(アンダースコア)でつないだものになります。このIDを使って
「TypedArray」クラスから指定された値を取り出すことができます。「Bootstrap Button」の「bb̲type」属性の場合は、「BootstrapButton̲bb̲type」という 名前になります。
図24:「BootstrapB utton.java」を開い て調べる
リスト18:BootstrapButton.java(140行目前後)
113:private void initialise( AttributeSet attrs ) { -省略
-121: TypedArray a = getContext().obtainStyledAttributes(attrs, 122: R.styleable.BootstrapButton);
-省略
-126: String bootstrapType = "default";
-省略
-140: if (a.getString(R.styleable.BootstrapButton_bb_type) != null) { 141: bootstrapType = a.getString(R.styleable.BootstrapButton_bb_type);
142: }
「TypedArray」クラスは「Context」クラスの「obtainStyledAttributes」メ ソッドで取り出します。この時引数に「AttributeSet」クラスのオブジェクトと「R.sty
leable.BootstrapButton」を渡します。「AttributeSet」オブジェクトは、View のコンストラクタで受け取ったものを使います。
Viewのコンストラクタが3種類あったことを覚えているでしょうか。11章の第1節で カスタムViewを作成する際に、「XMLより呼び出す際のコンストラクタ」として解説 したコンストラクタの引数に「AttributeSet」オブジェクトが渡ってきます。この「Att ributeSet」オブジェクトには、レイアウトファイルで定義した属性値が入っています。
「bb̲type」の属性値は「String」なので、「TypedArray」クラスの「getStri ng」メソッドで取り出します。取り出した値は「bootstrapType」にセットしています。
次は「bootstrapType」がどこで使われているかを探します。「bootstrapTy pe」をキーにしてソースコード内を検索すると、240行目にリスト19のような実装が 見つかります。
241行目の「if」文は「roundedCorners」という変数名から「ボタンを角丸にす るかどうか」を判定していることがわかります。今回は特に角丸の指定はしていなかっ たので245行目の処理に進みましょう。245行目では「bbuttonTypeMap」という 変数の「get」メソッドに「bootstrapType」を渡しています。
「bbuttonTypeMap」は「Map
<
String, BootstrapTypes>
」クラスです。「get」メソッドで「BootstrapTypes」クラスのインスタンスを取り出せます。そのイン
リスト19:BootstrapButton.java(240行目前後)
26: private static Map<String, BootstrapTypes> bbuttonTypeMap;
-省略
-36: private boolean roundedCorners = false;
-省略
-125: BootstrapTypes type = null;
-省略
-240: //get the correct background type 241: if(roundedCorners == true)
242: {
243: type = bbuttonTypeMapRounded.get(bootstrapType);
244: } else {
245: type = bbuttonTypeMap.get(bootstrapType);
246: } 247:
248: //set up as default 249: if (type == null) 250: {
251: type = BootstrapTypes.DEFAULT;
252: } 253:
254: //apply the background type
255: layout.setBackgroundResource(type.backgroundDrawable);
256: lblLeft.setTextColor(getResources().getColor(type.textColour));
257: lblMiddle.setTextColor(getResources().getColor(type.textColour));
258: lblRight.setTextColor(getResources().getColor(type.textColour));
外部 ライ ブラ リー の利 と用 作成 17第 章
スタンスを「type」という変数にセットし、その後255行目で利用しています。
次は「bbuttonTypeMap」をどのように初期化しているか、「BootstrapTyp es」クラスがどのようなクラスなのかを見ていきます。まずは「BootstrapTypes」クラ スです。「BootstrapTypes」クラスは84行目に定義されています(リスト20)。
「BootstrapTypes」クラスは「class」ではなく「enum」と宣言されています。
「enum」は列挙型を表します。
列挙型は通常のクラスと同じようにコンストラクタやフィールドやメソッドを持ちます。
ただしインスタンスは「enum」内に宣言した列挙子のみに限られるという特徴があり ます。あらかじめ宣言したもの、数しかインスタンスが存在しないことが保証されている ため、「switch」文で比較したり定数として扱うことができます。
「BootstrapTypes」クラスは、フィールドとして「backgroundDrawable」(背 景のdrawable)と「textColour」(文字色)を持った単純なクラスです。列挙子と して「DEFAULT」や「PRIMARY」などが宣言されています。列挙子を宣言す る際に、背景のdrawableと文字色のIDを渡しています。これによりボタンの色のバ リエーションを定義しています。
次は「bbuttonTypeMap」の初期化です。41行目のstaticイニシャライザー で、キーに対応する「BootstrapTypes」クラスをセットしていることがわかります(リ スト21)。
staticイニシャライザーは、クラスが初めてクラスローダーに読み込まれる時に一 度だけ実行されるブロックのことです。クラスがインスタンス化される時ではない点に 注意してください。
リスト20:BootstrapButton.java(84行目以降)
84: private enum BootstrapTypes 85: {
86: DEFAULT(R.drawable.bbuton_default, R.color.black), 87: PRIMARY(R.drawable.bbuton_primary, R.color.white), 88: SUCCESS(R.drawable.bbuton_success, R.color.white), 89: INFO(R.drawable.bbuton_info, R.color.white), 90: WARNING(R.drawable.bbuton_warning, R.color.white), 91: DANGER(R.drawable.bbuton_danger, R.color.white), 92: INVERSE(R.drawable.bbuton_inverse, R.color.white), -省略
-102: private int backgroundDrawable;
103: private int textColour;
104:
105: BootstrapTypes(int backgroundDrawable, int textColour) 106: {
107: this.backgroundDrawable = backgroundDrawable;
108: this.textColour = textColour;
109: } 110: }
これですべての情報がそろいました。「bb̲type」属性で指定した値は「bbutto nTypeMap」に登録された「BootstrapTypes」クラスを取り出すためのキーとし て利用されていました。「BootstrapTypes」は背景のdrawableと文字色を持つ クラスで、このクラスが持つ値を使ってViewの表示色などを変更していることがわか りました。
少し大変だったかと思います。しかしソースを読むことによって「bb̲type」属性 の役割がわかっただけでなく、「表示を属性値によって簡単に切り替える仕組み」
がどのように実現されているかもわかりました。また「bb̲type属性の値の種類が7 つあること」や「角丸表示の設定があること」や「enumクラスの使い方の参考」など も得られました。ソースコードを読むことで非常に多くの学びが得られます。
Androidアプリケーションで利用するライブラリーのほとんどはオープンソースで す。前項で「Android-Bootstrap」のカスタム属性を調べることができたのも
「Android-Bootstrap」がオープンソースだからです。オープンソースのソフトウェ アには「オープンソースライセンス」が定義されています。オープンソースのソフトウェア を利用する場合、「オープンソースライセンス」に記載されている条件に従う必要が あります。
オープンソースライセンスには沢山の種類があります。本項では近年のオープン ソースのライブラリーでよく利用されている「Apache License 2.0」、「MIT Lice nse」に加え、コピーレフトという思想に則った「GPLライセンス」について簡単に解 説します。
リスト21:BootstrapButton.java(41行目以降)
41: static{
42:
43: bbuttonTypeMap = new HashMap<String, BootstrapTypes>();
44:
45: bbuttonTypeMap.put("default", BootstrapTypes.DEFAULT);
46: bbuttonTypeMap.put("primary", BootstrapTypes.PRIMARY);
47: bbuttonTypeMap.put("success", BootstrapTypes.SUCCESS);
48: bbuttonTypeMap.put("info", BootstrapTypes.INFO);
49: bbuttonTypeMap.put("warning", BootstrapTypes.WARNING);
50: bbuttonTypeMap.put("danger", BootstrapTypes.DANGER);
51: bbuttonTypeMap.put("inverse", BootstrapTypes.INVERSE);
-省略