Androidで透明ウィンドウつづき


昨日の透明ウィンドウはSurfaceViewを使ったやり方でなんともスマートでなかった。
そこで他のやり方を探してたらAPIDemosの中にまさに透明ウィンドウのサンプルを見つけた。
TranslucentとTranslucent Fancyてやつ。透明というか半透明だけど気にしない。


そこで早速ソースを見てみると普通の文字を表示させるソースとなんら変わりない。
試しにコピペしてみたけどやっぱりウィンドウは透明にならない。


そこで周辺のファイルを調べてみるとstyles.xmlとAndroidManifest.xmlに秘密があることがわかった。


styles.xml内でポイントとなるのは次の二行。

#44ff0000
@drawable/translucent_background

一行目で背景となるdrawableを作っている。色の指定は#aarrggbbで行っているので初め二つの値で透明度を指定している。
二行目では一行目で作ったdrawableを背景として設定している。
ここで直接色の指定をしたがダメだった。drawableで指定しないといけないみたい。
逆に言えばdrawableならなんでも登録できる。画像を背景に使いたい場合は便利だ。


次にAndroidManifest.xmlの話。
これは中を見てもらえばわかるけどアプリケーションの色々を設定するファイル。
透明ウィンドウを作るには次のがポイント。

ここのandroid:themeにstyles.xml内で作った透明ウィンドウを指定すればよい。


ちなみにstyles.xmlって名前はただサンプルと合わせて
この名前にしただけなので違うファイル名でも平気なはずです。


そんなわけで昨日のやつを今回のやり方で作ったのが次のデモ。
半透明にして色を赤にしてみました。
SurfaceViewを使わないとソースがすごいスッキリするので透明にしたい場合はこっちの方がいいっぽい。


以下動作画面とソース。

ソース

TranslucentTest.java

package net.swelt.android.translucenttest;

import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.widget.AbsoluteLayout;

public class TranslucentTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(new SampleView(this));
    }
    
    public class SampleView extends AbsoluteLayout {
    	private DisplayObject mKirby;
    	
    	public SampleView(Context context) {
    		super(context);
    		
    		mKirby = new DisplayObject(context);
    		this.addView(mKirby);
    		
    		Bitmap bmp = BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable.kirby_t);
    		mKirby.setBitmap(bmp);
    		mKirby.move((320 - mKirby.getImageWidth())/2, (240 - mKirby.getImageHeight())/2);
    	}
    	    	
    	@Override
    	public void onDraw(Canvas canvas) {
    		mKirby.draw(canvas);
    	}
    	
    	@Override
    	public boolean onMotionEvent(MotionEvent event) {    		
    		switch( event.getAction() ) {
    		case MotionEvent.ACTION_DOWN:
    		case MotionEvent.ACTION_MOVE:
    			int x = (int)(event.getX() - mKirby.getImageWidth()/2);
    			int y = (int)(event.getY() - mKirby.getImageHeight()/2);
    			mKirby.move(x, y);    			
    			return true;
    		}
    		return true;
    	}
    }
}


styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<!-- drawable -->
	<drawable name="translucent_background">#44ff0000</drawable>
	
	<!-- style -->
	<style name="Theme" parent="android:Theme.Dark">
	</style>
		
	<style name="Theme.Transparent">
        <item name="android:windowBackground">@drawable/translucent_background</item>
        <item name="android:windowNoTitle">true</item>
	</style>
</resources>


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.swelt.android.translucenttest">
    <application android:icon="@drawable/icon">
        <activity class=".TranslucentTest"
        	android:label="@string/app_name"
        	android:theme="@style/Theme.Transparent">
        	
            <intent-filter>
                <action android:value="android.intent.action.MAIN" />
                <category android:value="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>