AndroidのボタンをShapeDrawableで描画するには?
ベクター描画のオルタナティブ「Shape Drawable」
SVGでボタンを描画するのは、パフォーマンス的に問題があることがわかった。
琴線探査: AndroidのボタンをSVGで描画するには?
琴線探査: 続・AndroidのボタンをSVGで描画するには?(ローテクだけど高速版)
AndroidにはSVGと似たような方法でベクターのイメージを描画する方法がある。「Shape Drawable」だ。res/drawableフォルダにShapeを定義したXMLを配置すると参照、描画できる。
Drawable Resources | Android Developers
この方法がどれだけ速いか試してみよう。
ボタンとなるXMLを作成
まず、ボタンとなるShape DrawableのXMLを作成する。
res/drawableフォルダを作成する。その下に、次の2つのXMLを配置する。
roundbutton_up.xml
roundbutton_down.xml
ShapeDrawableResourceButtonクラス作成
ex.sdrbパッケージにShapeDrawableResourceButtonクラスを作成する。
ShapeDrawableResourceButton.java
SVGButtonのプログラムと比べると大幅に単純になっている。
XML読み込みの部分をResourcesクラスがやってくれるのと、画面密度によるスケーリングを自分で処理しなくて良いということが大きい。
レイアウトを編集
res/layout/main.xmlをこのように編集する。
実行結果
ボタンをクリックするとハイライトする。
同様の処理をSVGButtonで行った時は4000msec程度、SVGButtonNoDOMで行った時は1100msec程度、そして今回は何と100msec程度!SVGButtonNoDOMと比べても11倍も速い。圧倒的だ。
Eclipseプロジェクトファイル:ShapeDrawableResourceButton.zip (157KB)
問題点
まず問題なのは、このShapeDrawableを使う方法では複雑なグラフィックを表現できないことだ。基本的に四角、楕円、線、リングしか描けない(^^);
もう1つの問題は、Resourceから取得したDrawableの色などをプログラムで変更できないこと。DrawableのAPIドキュメントを見る限り、残念ながらできなさそう。
ただ、このスピードは捨てがたいなぁ。
SVGでボタンを描画するのは、パフォーマンス的に問題があることがわかった。
琴線探査: AndroidのボタンをSVGで描画するには?
琴線探査: 続・AndroidのボタンをSVGで描画するには?(ローテクだけど高速版)
AndroidにはSVGと似たような方法でベクターのイメージを描画する方法がある。「Shape Drawable」だ。res/drawableフォルダにShapeを定義したXMLを配置すると参照、描画できる。
Drawable Resources | Android Developers
この方法がどれだけ速いか試してみよう。
ボタンとなるXMLを作成
まず、ボタンとなるShape DrawableのXMLを作成する。
res/drawableフォルダを作成する。その下に、次の2つのXMLを配置する。
roundbutton_up.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#444444" /> <padding android:bottom="8dp" android:left="8dp" android:right="8dp" android:top="8dp" /> <corners android:radius="4dp" /> <stroke android:width="2dp" android:color="#FFFFFF" /> </shape>
roundbutton_down.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#999999" /> <padding android:bottom="8dp" android:left="8dp" android:right="8dp" android:top="8dp" /> <corners android:radius="4dp" /> <stroke android:width="2dp" android:color="#FFFFFF" /> </shape>
ShapeDrawableResourceButtonクラス作成
ex.sdrbパッケージにShapeDrawableResourceButtonクラスを作成する。
ShapeDrawableResourceButton.java
package ex.sdrb; import java.util.Date; import android.content.Context; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.TextView; public class ShapeDrawableResourceButton extends TextView { protected Drawable dUp; protected Drawable dDown; public ShapeDrawableResourceButton(Context context, AttributeSet attrs) { super(context, attrs); setClickable(true); // これをしないとタッチイベントがDOWNのみになる init(); } protected void init() { Log.v("init", "スタイリング開始"); long start = new Date().getTime(); // リソース取得 Resources res = getResources(); // UP用Drawable取得 dUp = (Drawable) res.getDrawable(R.drawable.roundbutton_up); // DONW用Drawable取得 dDown = (Drawable) res.getDrawable(R.drawable.roundbutton_down); // UP用Drawableを背景にセット setBackgroundDrawable(dUp); long end = new Date().getTime(); Log.v("init", "スタイリング終了 " + (end - start) + " msec"); } @Override public boolean onTouchEvent(MotionEvent event) { // タッチイベントによって表示するDrawableを変える String action = ""; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: action = "ACTION_DOWN"; setBackgroundDrawable(dDown); break; case MotionEvent.ACTION_UP: action = "ACTION_UP"; setBackgroundDrawable(dUp); break; } Log.v("onTouchEvent", "action = " + action); // 再描画リクエスト invalidate(); return super.onTouchEvent(event); } }
SVGButtonのプログラムと比べると大幅に単純になっている。
XML読み込みの部分をResourcesクラスがやってくれるのと、画面密度によるスケーリングを自分で処理しなくて良いということが大きい。
レイアウトを編集
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" android:padding="10dp" > <ex.sdrb.ShapeDrawableResourceButton android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:text="ShapeDrawableResourceButton" android:textColor="#FFFFFF" /> </LinearLayout>
実行結果
ボタンをクリックするとハイライトする。
同様の処理をSVGButtonで行った時は4000msec程度、SVGButtonNoDOMで行った時は1100msec程度、そして今回は何と100msec程度!SVGButtonNoDOMと比べても11倍も速い。圧倒的だ。
Eclipseプロジェクトファイル:ShapeDrawableResourceButton.zip (157KB)
問題点
まず問題なのは、このShapeDrawableを使う方法では複雑なグラフィックを表現できないことだ。基本的に四角、楕円、線、リングしか描けない(^^);
もう1つの問題は、Resourceから取得したDrawableの色などをプログラムで変更できないこと。DrawableのAPIドキュメントを見る限り、残念ながらできなさそう。
ただ、このスピードは捨てがたいなぁ。
コメント
コメントを投稿