web-dev-qa-db-ja.com

Android、透明なステータスバーを正しく作成する方法

Android 4.4+で透明なステータスバーを作成しようとしています。独自のスタイルを定義して透明にする方法を知っています。

<style name="Theme.MyTheme" parent="Theme.MyTheme.Base">
    <item name="Android:windowTranslucentStatus">true</item>
    <item name="Android:windowTranslucentNavigation">true</item> </style>

私はここで見つけました: https://stackoverflow.com/a/20573595/26336

問題は、ステータスバーが透明の場合、アクションバーの色と一致せず、バックグラウンドのアクティビティが表示されることです。 transparent status bar error

ここで見つけたレイアウトでAndroid:fitsSystemWindows = "true"およびAndroid:clipToPadding = "false"を使用できることがわかりました http://mindofaandroiddev.wordpress.com/2013/12/28/making -the-status-bar-and-navigation-bar-transparent-with-a-listview-on-Android-4-4-KitKat /

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/background_darkRed"
Android:fitsSystemWindows="true"
Android:clipToPadding="false"    
tools:context="com.sandak.......">

<ScrollView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"> 
....

これにより、透明なステータスバーに関する一番上の問題が解決され、問題なく見えるようになります。 enter image description here

作業結果を達成するために考えられるすべてのバリアントを試しましたが、それを解決する方法がわかりません。私の唯一の有効なソリューションは、ルート要素に約60dpのトップパディングを設定することです。しかし、このソリューションはいため、デバイスによっては外観が異なる場合があり、機能しない場合があります。

Google Playで、背景が透明なOkで動作するアプリケーションをいくつか見つけたので、どのように動作させるのか興味があります。

例: https://play.google.com/store/apps/details?id=com.trello および他のいくつか

16
Sandak

// UPDATE:
OK、これはかなり古い答えです。これで、Materialテーマを使用してこれを処理でき、非常に簡単です。ターゲットAPIを21+に設定し、必要に応じてサポートライブラリを使用し、ステータスバーの色を直接指定できるマテリアルテーマでテーマを作成します

<style name="AppTheme"
        parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- colorPrimary is used for the default action bar background -->
        <item name="colorPrimary">@color/color_primary</item>

        <!-- colorPrimaryDark is used for the status bar -->
        <item name="colorPrimaryDark">@color/color_primary_dark</item>

        <!-- colorAccent is used as the default value for colorControlActivated
             which is used to tint widgets -->
        <item name="colorAccent">@color/accent_orange</item>
    </style>

================================================= ======================

古い回答:

OK、問題を解決したようです。これは最良かつ明確なソリューションではありませんが、実用的なソリューションです。将来の誰かがより良く、より明確な解決策を見つけたら、私に知らせてください、そして、私は私の答えを更新するか、またはあなたの答えを正しいものとしてマークします。しかし、今のところ、この小さなハックほど良い解決策はありません。

レイアウトのルート要素はRelativeLayoutでなければなりません。 ScrollViewやその他のレイアウトのようなメインレイアウトに従う必要があるよりも、重要ではありません。相対レイアウトタグを閉じる前の最後に、アクションバーと同じ背景を設定し、高さ(ステータスバーの高さ)を固定した空のLinearLayoutに従います。

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context="com.sandak....">
<ScrollView
    Android:fitsSystemWindows="true"
    Android:clipToPadding="false"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">
.... all your main views etc..
</ScrollView>
<LinearLayout
        Android:id="@+id/statusBarBackgroundLinearLayout"
        Android:layout_width="match_parent"
        Android:orientation="horizontal"
        Android:layout_height="30dp"
        Android:background="@color/background_darkRed"
        Android:clickable="false"
        Android:focusable="false">
     </LinearLayout>
</RelativeLayout>

[OK]をクリックすると、ステータスバーと同じ線形レイアウトの高さをコードで設定する必要があります。

private void setStatusBarBackground(View rootView) {
        setStatusBarLayout(rootView);
        statusBarHeight = getStatusBarHeight();
        setStatusBarLayoutHeight(statusBarHeight);
    }

    private void setStatusBarLayout(View rootView){
        statusBarBackgroundLinearLayout = (LinearLayout) rootView.findViewById(R.id.statusBarBackgroundLinearLayout);
        if (isPreKitkatDevice()) {
            hideStatusBarLayout();
        }
    }

    private int getStatusBarHeight() {
        int statusBarHeight = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "Android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }

    private boolean isPreKitkatDevice(){
        return Build.VERSION.SDK_INT < Build.VERSION_CODES.KitKat;
    }

    private void hideStatusBarLayout(){
        statusBarBackgroundLinearLayout.setVisibility(View.INVISIBLE);
    }        

    private void setStatusBarLayoutHeight(int height){
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) statusBarBackgroundLinearLayout.getLayoutParams();
        layoutParams.height = height;
    }

そして、onCreate()メソッドでsetStatusBarBackgroundを呼び出すだけです。これは、すべての異なる種類のデバイスの実用的なソリューションです。透明な背景が許可されていないKitKat以前のデバイスの場合、リニアレイアウトを非表示にする必要があります。

12
Sandak