2014年11月4日火曜日

Android Resource

Androidアプリケーションのリソースに関するメモ


Androidアプリのリソース

Androidアプリのリソースとは、コードとは分離された静的なデータである。
主にresディレクトリ配下を使用する。

Javaのプログラムからresディレクトリに配置した静的なデータにアクセスする場合、
生成されるRオブジェクトを介して行う。

【参考】Rについて
http://developer.android.com/intl/ja/reference/android/R.html

●扱うことができる読み取り専用リソース


String:文字列
Drawble:ビットマップ、ベクタ画像
Style:UIスタイル、テーマ
Menu:メニュー項目
ColorStateList:状態に対応した色の管理
Value:プリミティブ型(http://goo.gl/aQRTSN)
Animation:アニメーション
Raw:音声・動画・画像などのRawデータ
Layout:画面レイアウト
XMLResource:任意のXMLファイル

●アニメーションの種類

Animationには大きく3種類あります。

・Tweenアニメーション:1つのイメージを連続的に変化させるタイプ。ある対象に対するアフィン変換+フェードイン、アウト
・Propertyアニメーション:FragmetnやDrawableなど様々なオブジェクトにアニメーションを提供する。背景変化、透過変化(API Level 11 HoneyComb)
・Frameアニメーション:順番にイメージを並べて表示するタイプ。パラパラ漫画のような効果。

□Alpha:フェードイン、アウト

<alpha>要素
・android:fromAlpha属性
 アニメーション開始時のアルファ値
・android:toAlpha属性
 アニメーション終了時のアルファ値

□Scale:拡大・縮小

<scale>要素(全ての属性を設定する必要はない)
・android:fromXScale属性
 アニメーション開始時の、横方向の拡大率です。1.0 を基準に拡大率を決定。
・android:toXScale属性
 アニメーション終了時の、横方向の拡大率です。1.0 を基準に拡大率を決定。
・android:fromYScale属性
 アニメーション開始時の、縦方向の拡大率です。1.0 を基準に拡大率を決定。
・android:toYScale属性
 アニメーション終了時の、縦方向の拡大率です。1.0 を基準に拡大率を決定。
・android:pivotX属性
 拡大の中心点のX座標です。指定しないと 上端。
・android:pivotY属性
 拡大の中心点のY座標です。指定しないと 左端。

□Translate:並行移動

自分の大きさに対する % を指定。%pは、親要素の大きさに対するパーセンテージ
<trnslate>要素
・android:fromXDelta属性
 アニメーション開始時の X 座標。-100 から 100 までの % 単位または %p 単位の数字か、単位のない任意の数字を設定可能。
・android:toXDelta属性
 アニメーション終了時の X 座標。-100 から 100 までの % 単位または %p 単位の数字か、単位のない任意の数字を設定可能。
・android:fromYDelta属性
 アニメーション開始時の Y 座標。-100 から 100 までの % 単位または %p 単位の数字か、単位のない任意の数字を設定可能。
・android:toYDelta属性
 アニメーション終了時の Y 座標。-100 から 100 までの % 単位または %p 単位の数字か、単位のない任意の数字を設定可能。

□Rotate:回転

<rotate>要素
・android:fromDegrees属性
 アニメーション開始時の角度。
・android:toDegrees属性
 アニメーション終了時の角度。
・android:pivotX属性
 回転の中心点の X 座標。
・android:pivotY属性
 回転の中心点の Y 座標。

□複合

<set>要素を使用することで、複数のアニメーションを組み合わせることが可能。

□共通

・android:duration属性
 アニメーションを再生する時間です。millisecond 単位で指定します。
・android:repeatMode属性
 アニメーションが終了した時に、アニメーションを最初から再開するか、最後から最初へ戻るようにするかを設定する。
この設定が有効になるのは、後述するandroid:repeatCount属性が 0 以上か、若しくは infinite に設定された時のみ。
デフォルト値では、アニメーションを最初から再開するように設定される。
・android:repeatCount属性
 アニメーションを繰り返す回数です。infinite と設定することで、無限に繰り返すようにもできる。
・android:startOffset属性
 アニメーションのスタートの遅延時間です。指定した時間(msec)だけ遅延させることができる。

ex)
<set
    xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 回転は無限回 -->
    <!-- アニメーションする View のちょうど真ん中を中心に一周する -->
    <rotate
        android:duration="1000"
        android:repeatCount="infinite"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"/>
    <!-- 平行移動は 1 回だけ -->
    <!-- アニメーションする View の親の 40% の位置に移動する -->
    <translate
        android:duration="1000"
        android:repeatCount="0"
        android:toXDelta="40%p"
        android:toYDelta="40%p"/>
</set>

適用はJavaコードで行う。

ex)
View textView = findViewById(R.id.TextView1);
// Animation Resource を読み込んで、Animation オブジェクトを得る
Animation animation = AnimationUtils.loadAnimation(this, R.anim.sample_animation);
// Animation オブジェクトを View に渡して、アニメーションを開始する
textView.startAnimation(animation);


これらは同じアニメーションでも、静的データを配置する場所が異なるので注意が必要。


●読み取り専用リソースの配置場所(リソースディレクトリ)


res/animator:Propertyアニメーション
res/anim:Tweenアニメーション
res/color:ColorStateList
res/drawable:Drawable
res/layout:Layout
res/menu:Menu
res/raw:Raw
res/values:Values、Strin、Style
res/xml:任意のXML、GAの設定ファイル

●リソースディレクトリの命名規則


<resources_name>-<configuration_qualifier>

ex) drawable-hdpi(hdp向けdrawable)、values-en(英語ロケール向けvalues)、drawable-land-xhdpi(横画面xhdpi向けdrawable)

●リソースにアクセスする

ResourceID:aaptが自動生成する。リソースファイルに問題があるとaaptがコンパイルと最適化に失敗し、IDを生成できない。
aaptが生成した結果は Rクラスに反映され、IDに対応したint型の整数値が割り当てられる。

・XMLの属性でIDを割り当てるもの
・ファイル名をIDとするもの

以下の記述でアクセスする。package_nameは任意である。

(package_name).R.(resource_type).{resource_di}

AndroidフレームワークのもっているRクラスは直接importせず、FQDNでアクセスする。

import android.R;
R.id.text_1

android.R.id.text_1;

●XMLからリソースにアクセスする

layoutなどの記述で頻繁に記載する方法です。

ex)
@android:id/text_1

上記は、リソースIDを用いてアクセスする例。リソースの種類によって書き方が異なる。(http://goo.gl/kA8cl1)


●リソースの記述方法

□String Resource

UIで使用する定型文は直接XMLに記述せずに、String Resourceで定義することが推奨される。

ex)

<resources>
    <string name="hello_world">Hello World</string>
    <string name="image_recognize">Image Recognize</string>
</resources>

XMLファイルで使う場合、前述の「XMLからリソースにアクセスする」を参考に。
Contextをもっているクラスでは、以下のように取り出すことができる。

ex)

String hello = getString(R.string.hello_world);

□String Array

文字列の配列を定義する。受け取る側は配列として受け取ることができる。

ex)

<resources>
    <string-array name="foo_bar">
        <item>Foo</item>
        <item>Bar</item>
    </string-array>
</resources>

ex) Contextをもっているクラスでの受け取り。

getResources().getStringArray(R.array.foo_bar);


同じ構造でint型を使用した、Integer Array がある。


□Format

プレースホルダを用いて、可変な文字列をリソースで提供する。後から文字列の一部を変更したい場合などに用いる。$dは数字を示す。文字列を渡したいときは$sとする。Formatterで定義される(http://developer.android.com/intl/ja/reference/java/util/Formatter.html)。


ex)
<resources>
    <string name="my_format">私は、%1$d社製のギターをもっている。</string>
    <string name="my_format_2">私は、%1$d社製のベースと、%2$d社製のギターをもっている。</string>
</resources>

ex) 受け取り側で値を設定する

String formatted = getString(R.string.my_format_2, 'Fender', 'Gibson');


□Plurals

複数形の表示。

ex)
<resources>
    <plurals name="my_guiters">
        <item quantity="zero">I don't have guiter.</item>
        <item quantity="one">I have a guiter.</item>
        <item quantity="other">I have %d guiters.</item>
    </plurals>
</resources>

quantity属性は、zero、one、two、few、many、other から選択する。

ex) 受け取り側

String quantity = getResources().getQuantityString(R.plurals.my_guiters, 2, 2);
日本語端末の場合は注意が必要で、単数・複数形を持たない日本語の場合、常にotherが使用される。otherが定義されていないと落ちる。
http://qiita.com/mstssk/items/6697db6947918e58593b

□Drawable Resource(グラフィックリソース png/jpeg/gif/9patch形式の画像/XML定義の図形/アニメーションGIFは非対応)

推奨:png、容認:jpeg、非推奨:gif

解像度ごとのディレクトリ階層で分けていない場合、あるいは該当する解像度のリソースディレクトリがない場合は、システムによって適宜拡大・縮小が行われるため、画像が鮮明でなくなる可能性がある。

Drawableに配置したリソースはアプリのビルドで最適化される。最適化されたくない、元の状態を保持したい場合は、Rawに配置すること。

Drawableには種類がある。Bitmap、9-patch、Layer List、State List、Level List、Transition、Inset、Clip、Scale、Shape である。順に見ていく。【参考】http://goo.gl/7kvVdY

Bitmap
pngやjpg、gif
9-patch
ストレッチ可能な領域を指定した画像でデータ
Layer List
複数のDrawable要素をレイヤ上に並べたXMLのグラフィックリソース<item>要素でDrawableへの参照を記述したり、各種Drawableを子にもつレイヤをつくったりする。
ex)
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 一番下のレイヤに配置する、グレーで塗りつぶされた四角形の Drawable を持つ item 要素 -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#f5f5f5"/>
        </shape>
    </item>
    <!-- 一番上のレイヤに配置する、薄茶色で塗りつぶされた四角形の Drawable を持つ item 要素 -->
    <!-- 上端から 30dp 分のオフセットが設定されている -->
    <item android:top="30dp">
        <shape android:shape="rectangle">
            <solid android:color="#deb887"/>
        </shape>
    </item>
</layer-list>

State List Drawable
UIの状態に応じたDrawable要素を管理する。ボタンのタップ、非タップで状態を変えたいときになどに使用。

ex)
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- View が押された状態の Drawable -->
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="#696969"/>
        </shape>
    </item>
    <!-- View が通常の状態の Drawable -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#f5f5f5"/>
        </shape>
    </item>
</selector>

Level List
一定の規定値に依存して、Drawable要素を管理する。例えば、カーソルによって変化する値によって表示状態を変えたい場合などに使用。

ex)
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Level が 最高 0 までの時の Drawable への参照 -->
    <item android:maxLevel="0" >
        <shape android:shape="rectangle">
            <solid android:color="#f5f5f5"/>
        </shape>
    </item>
    <!-- Level が 最高 1 までの時の -->
    <item android:maxLevel="1" >
        <shape android:shape="rectangle">
            <solid android:color="#696969"/>
        </shape>
    </item>
</level-list>


ex) 取り出し方(Drawable系共通)

Drawable drawable = getResources().getDrawable(R.drawable.hogehoge);

Transition
複数のDrawableのクロスフェードを管理する。例えばフェードインやフェードアウト効果に使用する。コード上で実行時間を与えるなどしてstartTransitionして実行する。

ex)
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 最初の状態 -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#f5f5f5"/>
        </shape>
    </item>
    <!-- 次の状態 -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#696969"/>
        </shape>
    </item>
</transition>

Inset
Drawableの中に別のDrawableを差し込むXMLリソース。ViewがView自身より小さい背景グラフィックを要求する時に便利。また、Drawableのマージン(画像の外側の余白)をつけることにも利用可能。

ex)
<inset
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:insetTop="10dp"
    android:insetLeft="10dp"/>


Clip
Drawableのレベルによって、別のDrawableを切り抜く。Levelを変換させることで、徐々に画像を表示させるなどが可能。

ex)
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:clipOrientation="horizontal"
    android:gravity="right"/>

コード側で、レベルをセットすることで切り抜き状態を変更する。

ex)
ClipDrawable clip = (ClipDrawable) clipView.getBackground();
clip.setLevel(1000);

Scale
大きさを変化させる。初期状態は0(0倍 = 表示されない)、コードでレベルを変化させる。

ex)
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:scaleGravity="center"
    android:scaleWidth="50%"
    android:scaleHeight="50%"/>

ex)
ScaleDrawable scale = (ScaleDrawable) scaleView.getBackground();
scale.setLevel(1);


Shape
色やグラデーション情報を含む、幾何学的図形をXMLで宣言するグラフィックリソース

ex)
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
        <!-- solid: 塗りつぶし -->
    <solid
        android:color="#f5f5f5"/>
        <!-- stroke: 枠線 -->
    <stroke
        android:width="1dp"
        android:color="#000000"/>
</shape>

●Style

Viewの各要素の属性値をまとめて、一定のフォーマットを基底するリソース。アプリ内で共通のUIを提供する際に活用する。

ex)
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="BigTextViewStyle" parent="@android:style/Widget.TextView">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textSize">22sp</item>
    </style>
</resources>

上記のように定義したStyleを、各Viewに設定することで、Viewのフォーマットを指定します。

ex)
<TextView
        style="@style/BigTextViewStyle"
        android:id="@+id/HelloWorld1"
        android:text="@string/hello_world"/>


●Styleの継承

システムで定義されたスタイルを継承する。style要素にparent属性を追加。parent属性には、継承したいスタイルを設定。

ex)
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="BigTextViewStyle" parent="@android:style/Widget.TextView">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textSize">22sp</item>
    </style>
</resources>

●parent属性以外の継承

名称で継承する。

ex)

  • <style name="BigTextViewStyle.Red">
  •     <item name="android:textColor">#FF0000</item>
  • </style>
  • <!-- BigTextViewStyle.Red を継承する -->
  • <style name="BigTextViewStyle.Red.Bold"> ←元のStyle名に.~で新しく定義するスタイルの名前を宣言する。
  •     <item name="android:textStyle">bold</item>
  • </style>


●Menu

メニュー(OptionMenu、ContextMenu)の各種項目。

・OptionMenu:デバイスのMenuキー。または、ActionBarの並びに入るメニュー。
・ContextMenu:UIの長押しで呼び出されるメニュー

□メニューのDefine


ex)
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item ← メニュー1つ文に相当する要素。子にmenu属性を配置して、submenuにできる。
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:showAsAction="never"
        android:title="@string/action_settings"/>
</menu>

□OptionMenu


以下のようなコードでメニューリソースにアクセスして、リソースファイルの状態を反映する。

ex)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(menu);
}

□ContextMenu

明示的にviewに対して、ContextMenuを割り当てることでリッスン可能。ただし、リスナーのコールバックはonCreateContextMenu()で受け付けるため、Activityへの参照を他のオブジェクトがもつことになる。そのため、適切なタイミングでコールバックを受け付けないようにライフサイクルを管理する必要がある。詳細は後述。


●Color State List

例えばボタンがタップされたとき、そうでないときの色を変化させるなどの際に使用する。
ただし、カラーリソースはbackgroundなどのグラフィックリソースへの参照が必要な属性には指定できない。

ex) sample_color_state_list.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- View が押された状態の Drawable -->
    <item android:color="#696969" android:state_pressed="true"/>
    <!-- View が通常の状態の Drawable -->
    <item android:color="#f5f5f5"/>
</selector>

ex)
<Button
    android:id="@+id/ColorStateListButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/sample_color_state_list"
    android:text="@string/hello_world"
    android:textSize="16sp"/>

●Value Resource

プリミティブ型を使用する。

ex)
<resources>
    <!-- 個別の値を定義する -->
    <integer name="DefaultEggs">1</integer>
    <integer name="DefaultBooks">3</integer>
    <integer name="DefaultPickaxe">100</integer>
</resources>

ex) 受け取る側
int eggs = getResources().getInteger(R.integer.DefaultEggs);

●Typed Array

様々な型を配列にできる。取り出すときは型に中ウイする。

ex)
<resources>
    <!-- String や Integer 以外のものでも配列にできる -->
    <array name="Drawables">
        <item>@drawable/ic_launcher</item>
    </array>
    <array name="Colors">
        <item>@color/Red</item>
        <item>@color/Green</item>
        <item>@color/Blue</item>
    </array>
    <!-- 異なる型のものを混ぜても良いが、Java のコード上で扱う際に、場所と型を気をつけないといけないので注意 -->
    <array name="MixedArray">
        <item>@drawable/ic_launcher</item>
        <item>@color/Blue</item>
    </array>
</resources>

ex) 取り出し側(Colors)
TypedArray colors = getResources().obtainTypedArray(R.array.Colors);
        int color2 = colors.getColor(0, Color.BLACK);


●Boolean

bool値

ex)
<resources>
    <bool name="isCompany">true</bool>
    <bool name="isPerson">false</bool>
</resources>

ex) 受け取り側
boolean bool = getResources().getBoolean(R.bool.isCompany);


●Dimension

寸法を指定する。Viewの大きさや文字サイズ。Javaコードで取り出すとFloat型になる。

ex)
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <!-- 文字の大きさも定義可能 -->
    <dimen name="TitleSize">16sp</dimen>
    <dimen name="BodySize">14sp</dimen>
</resources>

ex) 受け取り側
float titleDim = getResources().getDimension(R.dimen.TitleSize);

●Color

色コードを定義する。Javaコードで取り出すとint型整数値になる。

ex)
<resources>
    <color name="Red">#FF0000</color>
    <color name="Green">#00FF00</color>
    <color name="Blue">#0000FF</color>
</resources>

ex) 受け取り側
int color = getResources().getColor(R.color.Blue);

●ID

レイアウトのIDをまとめる。

ex)
<resources>
    <item type="id" name="HelloWorld"/>
    <item type="id" name="Hoge"/>
</resources>

●Raw(Binary)

最適化除外対象のバイナリデータ。
InpurStreamを使用してアクセスする。

ex)
InputStream in = getResources().openRawResource(R.raw.ファイル名);


●多様なデバイスへの対応

Contextを通してリソースへアクセスする設計により、リソースを使う側が端末に依存したリソースの取得を意識しないで済むようになっている。
configuration_qualifierは、各デバイスのリソースに関する特徴を決める部分であり、重要である。

□configuration_qualifierの仕様

以下の上から順にハイフン区切りでconfiguration_qualifierを連結し、リソースを定義する。

・Language and Region
 言語
 jaやenやfrなどと指定する
・Smallest Width
 ディスプレイの短辺の大きさ
 sw600dpやsw720dpなど、sw<N>dpの形式で、dpの単位で指定する
・Screen Orientation
 画面の向き
 landまたはport
・Screen Pixel Density
 ピクセル密度
 ldpi、mdpi、hdpi、xhdpi、xxhdpi、nodpi、tvdpiなどと指定する。
・Platform Version
 OS のバージョン
 v4、v7などと指定する。数字は API Level のものを使う。

ex)

values-en-v4:良い
values-v4-en:ダメ

●ロケール

端末で仕様している言語に応じてリソースを定義する。
言語コードISO 639-1、地域コードISO 3166-1-alpha-2 を使える。


●高解像度スクリーン

デフォルトで用意されており、頻繁に利用する。

・ldpi:drawable-ldpi
・mdpi:drawable-mdpi
・hdpi:drawable-hdpi
・xhdpi:drawable-xhdpi ← 現在主流である。
・xxhdpi:drawable-xxhdpi

●画面向き

向きによってリソースファイルを切り替えることが可能。

・縦:layout-land, drawable-land
・横:layout_port, drawable-port

0 件のコメント:

コメントを投稿