web-dev-qa-db-ja.com

Android素材:ステータスバーの色は変わりません

材料設計をテストするためのシンプルなアプリを開発しています。私はcom.Android.support:appcompat-v7:21.0.0を使用していますが、私のアクティビティは次のようになります:

public class MyActivity extends ActionBarActivity {
   ...
}

レイアウトは次のように定義されます:

<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"
    tools:context=".MyActivity">

    <Android.support.v7.widget.Toolbar
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@+id/toolbar"
        Android:layout_width="match_parent"
        Android:layout_height="128dp"
        Android:minHeight="?attr/actionBarSize"
        Android:background="?attr/colorPrimaryDark"/>
</LinearLayout>

今、私はテーマを材料ガイドラインに従って定義しました:

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary500</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark700</item>
</style>

Pre Android 5のステータスバーの色を変更してcolorPrimaryDarkに設定したいのですが、方法が見つかりません。私は使用してみました:

getWindow().setStatusBarColor(..)

ただし、setStatusBarの色はレベル21から使用できます。テーマでcolorPrimaryDarkを定義してappcompactを使用すると、ステータスバーの色が変わらないのはなぜですか。誰でも助けることができますか?

53
FrancescoAzzola

ステータスバーは、オペレーティングシステムが所有するシステムウィンドウです。 5.0より前のAndroidデバイスでは、アプリケーションに色を変更する権限がないため、これはAppCompatライブラリが古いプラットフォームバージョンでサポートできるものではありません。 AppCompatでできる最善の方法は、ActionBarおよびアプリケーション内のその他の一般的なUIウィジェットの色付けをサポートすることです。

61
Alex Lockwood

ステータスバーの色付けは5.0未満ではサポートされていませんが、4.4では、回避策を使用してより暗い色を実現できます。

ステータスバーを半透明にする

<item name="Android:windowTranslucentStatus">true</item>

次に、AppCompatのツールバーをアプリバーに使用して、システムウィンドウに適合することを確認します。

<Android.support.v7.widget.Toolbar
    Android:id="@+id/toolbar"
    ...
    Android:fitsSystemWindows="true"/>

ツールバーをアクティビティのツールバーとして設定してください:

protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ...
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

ツールバーはステータスバーの下に伸びており、ステータスバーの半透明性により、より暗いセカンダリカラーに見えます。希望の色ではない場合、この組み合わせにより、ステータスバーの下に、選択した背景色を表示するビューを収めることができます(ただし、ステータスバーによって暗く表示されます)。

4.4のみによるEdgeケースの回避策のようなものですが、そこに行きます。

61
Tom
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    getWindow().setStatusBarColor(getResources().getColor(R.color.actionbar));
}

このコードをアクティビティのonCreateメソッドに入れます。これは私を助けました。

39
user998953

他の人も言及しているように、これはアクティビティのonCreate()に以下を追加することで簡単に解決できます:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.primary_dark));
    }

ただし、ここで追加したい重要な点は、場合によっては上記でもステータスバーの色が変わらないことです。たとえば、MikePenzライブラリをNavigation Drawerに使用すると、暗黙的にステータスバーの色がオーバーライドされるため、次のコードを手動で追加して動作させる必要があります。

.withStatusBarColorRes(R.color.status_bar_color)

13
MehrAmoon

ステータスバーの色付けは、AppCompat v7:21.0.0ではサポートされていません。

Android developer blog post から

古いプラットフォームでは、AppCompatは可能な限り色のテーマをエミュレートします。現時点では、これはアクションバーと一部のウィジェットの色付けに限定されています。

これは、AppCompatライブラリがLollipop以上のステータスバーのみを色付けすることを意味します。

10
Anup Cowkur

AppCompatActivityに切り替え、25 dp paddingTopをツールバーに追加してオンにします

<item name="Android:windowTranslucentStatus">true</item>

次に、ウィルツールバーが上に移動します

8
alvarlagerlof

このソリューションは、Lollipop、KitKat、およびいくつかのLollipop以前のデバイス(SamsungおよびSony)のステータスバーの色を設定します。 SystemBarTintManager はKitKatデバイスを管理しています;)

@Override
protected void onCreate( Bundle savedInstanceState ) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    hackStatusBarColor(this, R.color.primary_dark);
}

@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
public static View hackStatusBarColor( final Activity act, final int colorResID ) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
        try {

            if (act.getWindow() != null) {

                final ViewGroup vg = (ViewGroup) act.getWindow().getDecorView();
                if (vg.getParent() == null && applyColoredStatusBar(act, colorResID)) {
                    final View statusBar = new View(act);

                    vg.post(new Runnable() {
                        @Override
                        public void run() {

                            int statusBarHeight = (int) Math.ceil(25 * vg.getContext().getResources().getDisplayMetrics().density);
                            statusBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, statusBarHeight));
                            statusBar.setBackgroundColor(act.getResources().getColor(colorResID));
                            statusBar.setId(13371337);
                            vg.addView(statusBar, 0);
                        }
                    });
                    return statusBar;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    else if (act.getWindow() != null) {
        act.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        act.getWindow().setStatusBarColor(act.getResources().getColor(colorResID));
    }
    return null;
}

private static boolean applyColoredStatusBar( Activity act, int colorResID ) {
    final Window window = act.getWindow();
    final int flag;
    if (window != null) {
        View decor = window.getDecorView();
        if (decor != null) {
            flag = resolveTransparentStatusBarFlag(act);

            if (flag != 0) {
                decor.setSystemUiVisibility(flag);
                return true;
            }
            else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KitKat) {
                act.findViewById(Android.R.id.content).setFitsSystemWindows(false);
                setTranslucentStatus(window, true);
                final SystemBarTintManager tintManager = new SystemBarTintManager(act);
                tintManager.setStatusBarTintEnabled(true);
                tintManager.setStatusBarTintColor(colorResID);
            }
        }
    }
    return false;
}

public static int resolveTransparentStatusBarFlag( Context ctx ) {
    String[] libs = ctx.getPackageManager().getSystemSharedLibraryNames();
    String reflect = null;

    if (libs == null)
        return 0;

    final String SAMSUNG = "touchwiz";
    final String SONY = "com.sonyericsson.navigationbar";

    for (String lib : libs) {

        if (lib.equals(SAMSUNG)) {
            reflect = "SYSTEM_UI_FLAG_TRANSPARENT_BACKGROUND";
        }
        else if (lib.startsWith(SONY)) {
            reflect = "SYSTEM_UI_FLAG_TRANSPARENT";
        }
    }

    if (reflect == null)
        return 0;

    try {
        Field field = View.class.getField(reflect);
        if (field.getType() == Integer.TYPE) {
            return field.getInt(null);
        }
    } catch (Exception e) {
    }

    return 0;
}

@TargetApi(Build.VERSION_CODES.KitKat)
public static void setTranslucentStatus( Window win, boolean on ) {
    WindowManager.LayoutParams winParams = win.getAttributes();
    final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
    if (on) {
        winParams.flags |= bits;
    }
    else {
        winParams.flags &= ~bits;
    }
    win.setAttributes(winParams);
}
2
bapho

Make Theme.AppCompa tスタイルの親

<style name="AppTheme" parent="Theme.AppCompat">
     <item name="Android:colorPrimary">#005555</item>
     <item name="Android:colorPrimaryDark">#003333</item>
</style>

そして、getSupportActionBar().getThemedContext()onCreate()に入れます。

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        getSupportActionBar().getThemedContext();
}
0
Ausama