37

よく知られているTYPE_SYSTEM_OVERLAY方法を使用して、常に他のビューの上にある全画面オーバーレイを作成しています。

ステータス バーが別のアプリによって非表示になっている場合、オーバーレイ ビューの各のサイズが自動的に変更されます (垂直方向に拡張されますMoto Atrix2 API15) AVD。オーバーレイは、他のすべてのビューの「上にとどまる」ように見えます。ステータス バーが再び表示されると、オーバーレイのサイズが再び自動的に縮小されます (垂直方向のピクセルが少なくなり、基本的にステータス バーの高さが差し引かれます)。API 1017

これは望ましい動作であり、多くの異なるエミュレーターや少なくとも 1 つのデバイス メーカー ( motorola )、おそらくそれ以上で動作するため、これは例外または欠陥のある動作ではないと考える傾向がありますが、私はアクセスできません。addtl devices.

問題: & でSamsung GS2 (API15)テスト済みでKindle Fire (API10?)は、ステータス バーが別のアプリ (フル スクリーン アプリの背後にあるステータス バー) によって非表示になっている場合、オーバーレイのサイズが自動的に変更されません (ステータス バーがかつてあったスペースを埋めます)。これらのデバイスでは、ビューが初めて作成された後、ビューの onSizeChanged オーバーライドからイベントを取得しません。

関連するコードは次のとおりです。

params = new WindowManager.LayoutParams( 
    1, WindowManager.LayoutParams.MATCH_PARENT, 
    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 
    PixelFormat.TRANSPARENT);
wm.addView(sizeLayout, params);

sizeLayout には onSizeChanged オーバーライドがあります。

windowmanager layoutparamSYSTEM_ALERT、FLAG_LAYOUT_IN_SCREEN など、見つけることができるほぼすべてのものをいじってみました。これがわかるまで寝ません!

編集 11/30/12 : @deviant からこれを見つけました: https://stackoverflow.com/a/9195733/1851478これは基本的に私が行っていることですが、system_overlay を自動的にサイズ変更しない特定のデバイスに問題が残ります。おそらく、バグを発生させる必要があります。

詳細情報: ビュー ツリーの上部に全画面表示のアプリがあるときに再描画を強制した場合 (または単にオーバーレイ アプリをロードした場合)、オーバーレイはステータス バーが通常占有するスペースに描画されません (ただし、ステータスバーは描画時に表示されていないため、フルスクリーンの最前面ウィンドウの上にオーバーレイが「オーバーレイ」されていないように見えます(そして、私は多くのフルスクリーンアプリを作成してテストしましたそれらを全画面表示にするためのさまざまな方法)。これらのデバイスでは、(ステータス バーが表示されていなくても) オーバーレイをステータス バーの上に描画する唯一の方法は、 flag を使用するFLAG_LAYOUT_IN_SCREENことですが、レイアウトのサイズは決して変更されず、常にフル スクリーンであり、したがって、これが一部のデバイスでは機能するが他のデバイスでは機能しない理由の元の問題に戻ります。

編集 12/12/12 :これ以上の運はありませんでした。ビューで getLocalVisibleRect を使用しようとしましたが、残念ながら、私のアプリは SystemUI ビューを所有していないため、オーバーレイの下にあるものを検出できません。カスタム ROM でこれを行うことができると思いますが、ルートなしのソリューションが必要です。

マーケットプレイスの他のアプリでも、上記の動作していない電話のステータス バーを検出するのと同じ問題が発生していることがわかります。例: クールなツール、オメガ ステータスバー & ステータスバー +. 報奨金が発生しました。

編集 12/19/12写真追加。動作中のデバイスでは、灰色の領域が黒い領域 (現在全画面表示になっているアプリ) も「カバー」し、黒い領域が実際には画面全体を覆っていることに注意してください。全画面表示 (動作中/非動作中のデバイス、および表示されているかどうかに応じて、ステータス バーの高さをマイナスまたはプラスします)。

ここに画像の説明を入力 ここに画像の説明を入力

4

2 に答える 2

3

うまくいけば、あなたがここで何をしているのか理解できますが、私のアプリ (TEAM BatteryBar) でも同様の問題がありました。(ルートの最小限の権限なし)

API11より下のすべてのフルスクリーンを検出できませんでした(API11より上の一部の(主にSamsung)デバイスでは断続的です)。そのため、別のレイアウト パラメータを使用して WindowManager に 2 番目のレイアウトを追加してカスタム リスナーを作成し、onLayout をオーバーライドして、ウィンドウ サイズを確認して statusBar がまだ存在するかどうかを確認しました。そこから、メイン ビューに対して必要なことを行うことができます。

私はそれを片付けようとしていましたが、うまくいきませんでした:P コードは 1 年以上前のもので、最初に Android のコーディングを始めたときのものです。思考の糧です。それが役に立てば幸い。

これは、私のgithubのレポにあるコードで、アプリの使用方法をアプリから直接コピーして貼り付けています。ここに小さなスニペット

wm.addView(sizeLayout, params);// add your view

// then add the next one
Screendetect mDetector;
mDetector = new Screendetect(this);
mDetector.setOnFullScreenListener(new OnFullScreenListener() {
            @Override
            public void fsChanged(boolean FS_Bool) {
                // TODO rethink this to be better.... bit hacky...
                if (FS_Bool) {
                    Log.d("battbardetect", "Statusbar hidden");
                    FS_vissible(); // do what ever you need to
                } else if (!FS_Bool) {
                    Log.d("battbardetect", "Statusbar Vissible"); 
                    FS_hidden(); // do what ever you need to
                }
            }
        });
wm.addView(mDetector, params);
于 2013-01-07T09:51:58.310 に答える
1

これは、システムが可視性を非表示に設定するダイアログウィンドウでタイトルバーを非表示にする場合と同じ問題である可能性があると思います。これにより、ダイアログウィンドウが誤って中央に配置されます。

そのために、これが私がそれを修正する方法です。これは状況に応じて機能する場合がありますが、ステータスバー識別子の名前に合わせて調整する必要がある場合があります。

Window window = dialog.getWindow();
View view = window.getDecorView();
int topPanelId = getResources().getIdentifier("topPanel", "id", "android");
LinearLayout topPanel = (LinearLayout) view.findViewById(topPanelId);
topPanel.setVisibility(View.GONE);
于 2013-01-02T05:51:22.380 に答える