setContentViewと、WindowManagerのテスト


2014年4月11日現在、私が理解している内容です。
間違っている場合があります。


setContentViewと、WindowManagerで、画面表示するテスト

今回はandroidの画面表示の挙動の実験です。

androidの画面に何か表示するのに、「setContentView」を使いますが、
「WindowManager」を使う方法もあるということのようです。

WindowManagerは、androidの警告表示などのアラートダイアログを出すような一段高い階層の画面表示をしてくれます。
もし、適当に使うとandroidが操作ができなくなる危険があるので、注意しましょう。
それはさておき、WindowManagerを使うとどうなるか、さわりだけテストしてみました。


WindowManagerで、画面表示をするには、以下のようにします。

ウィンドウに背景色をつける

//ウィンドウのパラメータを設定 WindowManager.LayoutParams params1 = new WindowManager.LayoutParams( 300, //横のサイズ 400, //縦のサイズ WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, //一番手前に表示 WindowManager.LayoutParams.FLAGS_CHANGED, //背景をぼかす PixelFormat.TRANSLUCENT); //透過する Window win1 = getWindow(); win1.setAttributes(params1); //ウインドウにパラメータを渡す ColorDrawable c; //新しい色のデータをつくる準備 c = new ColorDrawable(0x8800ff00); //半透明で緑色 win1.setBackgroundDrawable(c); //ウィンドウの背景色を半透明で緑色にする


ウィンドウにレイアウトを設定する

L_layout1 = new LinearLayout(this); //新しいレイアウトを作る L_layout1.setBackgroundColor(Color.argb(128, 0, 0, 255)); //背景を半透明の青にする //新しいボタンを作る Button button1 = new Button(this); //ボタンに文字を表示 button1.setText("GO BACK"); //ボタンをレイアウトに追加 L_layout1.addView(button1); //----------------------------------------- //ウィンドウのパラメータを設定 WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, //横幅を中身に合わせる WindowManager.LayoutParams.WRAP_CONTENT, //縦幅を中身に合わせる 0, //エラーが出る場合はとりあえず"0"でいいかも WindowManager.LayoutParams.FLAGS_CHANGED, //背景をぼかす PixelFormat.TRANSLUCENT); //透過する WindowManager windowManager1 = (WindowManager) getSystemService(WINDOW_SERVICE); windowManager1.addView(L_layout1, params); //ウィンドウに、レイアウトとパラメータを渡す




AndroidManifest.xmlの確認

今回の実験をする前に、AndroidManifest.xmlに、次の記述があることを、確認しましょう。
ウィンドウを半透明にして、全画面表示にする設定と、
Activity_Sub1アクティビティの設定。


android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen <activity android:label="@string/app_name" android:name=".Activity_Sub1"/>



<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.test02" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"> <activity android:name="com.example.test02.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:label="@string/app_name" android:name=".Activity_Sub1"/> </application> </manifest>




ウィンドウ表示のテストいろいろ

アクティビティの画面遷移のこととか」のコードを改造した実験です。
まず、赤いウィンドウと緑のウィンドウが出てきます。
このとき、背景がぼけているのが、おわかりでしょうか?
「WindowManager.LayoutParams.FLAGS_CHANGED」のフラグを立てるとこのような事ができるわけですね。

「CHANGE」ボタンを押すと、青いウィンドウのActivity_Sub1画面が出てきます。
「GO BACK」ボタンか、端末の「戻る」キーで、Activity_Sub1画面が消えます。


ちなみに、android2.3.3のエミュレータでは重なって見えますが、
android4.4.2のエミュレータでは、青い画面が表示された時、下の赤画面が消されるみたいですので、
重なって見えることがありません。
実際にアプリにするときは、挙動がおかしくならないように注意が必要ですね。


ウィンドウは小さいのですが、背景のアプリは操作できません。
後ろのアプリを操作したりするためには、「サービス」という別のしくみが必要です。
サービスを使うと、小さなウィンドウが浮いた状態で、後ろのアプリを操作できたりします。
本来は、サービスと組み合わせて、WindowManagerを使います。


背景がぼけています。
赤い画面と緑の画面が別々に表示されています。



Activity_Sub1の、青い画面を出すと、赤い画面もぼけて表示されました。



AndroidManifest.xmlで、あえて、透過の設定である、
「android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"」を削除すると、このように見えます。
ウィンドウらしく、タイトルバーが見えています。



はじめに「android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"」で、
フルスクリーンを指定していましたが、ステータスバーがずっと出ています。
ウィンドウのサイズが小さいからでしょうか?



赤いレイアウトを表示していたウィンドウに、代わりにボタンを表示してみる。
ボタンの大きさについて何も設定してないので、ウィンドウ全体に表示されてます。
MainActivity.javaで、
「Red_layout1.addView(button1);」を削除して、
「windowManager1.addView(button1, params2);」を記述すると、こんな感じ。



緑のウィンドウに、ボタンを表示してみる。
ボタンの大きさについて何も設定してないので、ウィンドウ全体に表示されてます。
「Red_layout1.addView(button1);」を削除して、
「setContentView(button1);」を記述すると、こんな感じ。



緑のウィンドウに赤いレイアウトを重ねてみる。
レイアウトにボタンを乗せてから表示すると、ボタンの大きさは自動的にそれなりに設定されるようです。
「windowManager1.addView(Red_layout1,params2);」を削除して、
setContentView(Red_layout1);を記述すると、こんな感じ。
赤と緑がまざった色になりました。



Activity_Sub1.java

package com.example.test02; import android.app.Activity; import android.graphics.Color; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.LinearLayout; public class Activity_Sub1 extends Activity { private LinearLayout L_layout1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //--------------------------------------------------- //ウィンドウを作る //ウィンドウサイズ指定 WindowManager.LayoutParams para1 = new WindowManager.LayoutParams( 250,200, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, //一番手前に表示 WindowManager.LayoutParams.FLAGS_CHANGED, //背景をぼかす PixelFormat.TRANSLUCENT); //ウィンドウは画面中央に表示されるので、画面中央からのウィンドウの相対位置指定 para1.x = 50; para1.y = 100; //ウインドウにデータを渡す Window win1 = getWindow(); win1.setAttributes(para1); //----------------------------------------- //青い画面のレイアウトを作って、ウィンドウにセットする //新しいレイアウトを作る L_layout1 = new LinearLayout(this); //レイアウトの背景を青にする L_layout1.setBackgroundColor(Color.argb(128, 0, 0, 255)); //レイアウトをウィンドウにセットする setContentView(L_layout1,para1); //----------------------------------------- //新しいボタンを作る Button button1 = new Button(this); //ボタンに文字を表示 button1.setText("GO BACK"); //ボタンをレイアウトに追加 L_layout1.addView(button1); //----------------------------------------- //レイアウト上のボタンの表示位置指定 LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(100, 50, 0, 0); button1.setLayoutParams(layoutParams); //----------------------------------------- //ボタンが押されたかどうか監視する button1.setOnClickListener( new OnClickListener() { //ボタンが押されたら何かする @Override public void onClick(View v) { //この画面を終了 finish(); } }); //----------------------------------------- } }


MainActivity.java

package com.example.test02; import android.os.Bundle; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.app.Activity; import android.content.Intent; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //--------------------------------------------------- //緑色のウィンドウを作る //ウィンドウのパラメータ指定 WindowManager.LayoutParams params1 = new WindowManager.LayoutParams( 350,200, //縦横サイズ指定 WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, //一番手前に表示 WindowManager.LayoutParams.FLAGS_CHANGED, //背景をぼかす PixelFormat.TRANSLUCENT); //ウィンドウは画面中央に表示されるので、画面中央からのウィンドウの相対位置指定 params1.x = -50; params1.y = 200; Window win1 = getWindow(); win1.setAttributes(params1); //ウインドウにパラメータを渡す ColorDrawable c; //新しい色のデータをつくる準備 c = new ColorDrawable(0x4400ff00); //半透明で緑色 win1.setBackgroundDrawable(c); //ウィンドウの背景色を半透明で緑色にする //-------------------------------------------------- //赤いレイアウトを作る LinearLayout Red_layout1 = new LinearLayout(this); //レイアウトの背景を赤にする Red_layout1.setBackgroundColor(Color.argb(128, 255, 0, 0)); //----------------------------------------- //新しいボタンを作る Button button1 = new Button(this); //ボタンに文字を表示 button1.setText("CHANGE"); //ボタンをレイアウトに追加 Red_layout1.addView(button1); //ボタンを緑色のウィンドウに追加 //setContentView(button1); //赤いレイアウトを、緑色のウィンドウに追加 //setContentView(Red_layout1); //-------------------------------------------------- //緑のウインドウに赤いレイアウトを重ねる //赤いレイアウトを表示するウィンドウのパラメータ指定 WindowManager.LayoutParams params2 = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT); params2.width = 200; //横幅 params2.height = 400; //縦幅 params2.flags = WindowManager.LayoutParams.FORMAT_CHANGED; params2.format = PixelFormat.TRANSLUCENT; //赤いウィンドウを半透明にする params2.alpha = 128; //ボタンが半透明になる //ウィンドウマネージャーを使う WindowManager windowManager1 = (WindowManager) getSystemService(WINDOW_SERVICE); //ウィンドウに、赤いレイアウトを追加して描画 windowManager1.addView(Red_layout1,params2); //ボタンをウィンドウに設定 //windowManager1.addView(button1, params2); //----------------------------------------- //ボタンが押されたかどうか監視する button1.setOnClickListener( new OnClickListener() { //ボタンが押されたら何かする @Override public void onClick(View v) { //インテントに、この画面と、別の画面を指定する Intent intent = new Intent(MainActivity.this, Activity_Sub1.class); //インテントで指定した別の画面に遷移する startActivity(intent); } }); //----------------------------------------- } }














戻る