Android SDK ADTを使っての開発時、他のプロジェクト・パッケージのリソースは少なくともビルド時にはプロジェクトから見えているにも関わらず、表題のようにレイアウトエディタでは参照できないようだ。
例えば、以下のような色リソースを/framework_project/res/values/color.xmlに記述しておく。(これはフレームワークで提供するビューで使用するため、アプリケーションのプロジェクトからは直接参照されない。)
- framework_project/res/values/color.xml
<resources> <color name="calendar_background">#f0ffffff</color> <color name="calendar_foreground">#ff000000</color> <color name="calendar_dark">#6456648f</color> <color name="calendar_hilite">#ffffffff</color> <color name="calendar_light">#64c6d4ef</color> <color name="calendar_holiday">#ffFF0000</color> <color name="calendar_saturday">#ff0000FF</color> <color name="calendar_selected">#64ffcc00</color> </resources>
framework_projectに配置するビュー(CalendarView)は以下のように参照している。
- framework_project/src/view/CalendarView.java
public class CalendarView extends LinearLayout {
public CalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
Resources res = this.getResources();
int c_backgroud = res.getColor(R.color.calendar_background);
int c_foregroud = res.getColor(R.color.calendar_foreground);
int c_dark = res.getColor(R.color.calendar_dark);
int c_hilite = res.getColor(R.color.calendar_hilite);
int c_light = res.getColor(R.color.calendar_light);
int c_holidaty = res.getColor(R.color.calendar_holiday);
int c_saturday = res.getColor(R.color.calendar_saturday);
int c_selected = res.getColor(R.color.calendar_selected);
}
:
}
このビューをprojectAのActivityで使うためには、以下のようにレイアウト用のXMLに記述するだろう。
- project_a/res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<view.CalendarView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="top|center"
android:orientation="vertical">
</view.CalendarView>
</LinearLayout>これで一見よさそうに見えるが、レイアウトエディタで開くと上手くいかない。
android.content.res.Resources$NotFoundException: Could not resolve resource value: 0x7F050000.
at com.android.layoutlib.bridge.BridgeResources.throwException(BridgeResources.java:546)
at com.android.layoutlib.bridge.BridgeResources.getColor(BridgeResources.java:150)
at view.CalendarView.(CalendarView.java:69)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(Unknown Source)
at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(Unknown Source)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:198)
at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:126)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
at android.view.LayoutInflater.inflate(LayoutInflater.java:296)
at com.android.layoutlib.bridge.Bridge.computeLayout(Bridge.java:396)
:
ADTのレイアウトエディタは実際にビューのインスタンスを生成してエディタ上に描画している、いわゆる「ライブ」なコンポーネントを扱うが、そのコンテキストとリソースは特殊なもの※1を使用していおり、今回の例のように、他のプロジェクトで定義されたビューが参照している、同じく他のパッケージのリソースを参照することはできないようだ。
実行時は、以前に書いたように、他のパッケージのリソースを共有参照する方法により、色だろうが文字だろうが取得できるのはずだが、デザイン時はその方法が使えないので、例えば色の場合ならばリソースに頼らないでデザイン時の規定値を用意してやるか、又はXMLを通してプロパティ(Attributes)として外部から設定する必要があるだろう。
結論として、レイアウトエディタ使用時つまりデザイン時に参照できるの自プロジェクト以外のリソースはandroid.Rで参照されるリソースだけ※2ということになる。これは是非解決して貰いたい制限だ。
※1:com.android.layoutlib.bridge.BridgeContextとcom.android.layoutlib.bridge.BridgeResourcesクラスがそれだ。
※2:1com.android.layoutlib.bridge.BridgeContextはそのコンストラクタでプロジェクトのリソースとAndroid SDKが用意しているリソースを引数にとる。このためandroid.R〜は参照できる。
- com.android.layoutlib.bridge.BridgeContext.java
public BridgeContext(Object projectKey, DisplayMetrics metrics,
IStyleResourceValue currentTheme,
Map> projectResources,
Map> frameworkResources,
Map styleInheritanceMap,
IProjectCallback customViewLoader, ILayoutLog logger) {
