web-dev-qa-db-fra.com

barre d'état complètement transparente et barre de navigation sur sucette

J'essaie de créer un lanceur Android. Je souhaite obtenir une barre d'état et une barre de navigation complètement transparentes, voici mon fichier XML de thème.

<resources>
    <style name="Theme" parent="Android:Theme.Material.Wallpaper.NoTitleBar">
        <item name="Android:statusBarColor">@Android:color/transparent</item>
        <item name="Android:navigationBarColor">@Android:color/transparent</item>
        <item name="Android:windowTranslucentStatus">false</item>
        <item name="Android:windowTranslucentNavigation">false</item>
    </style>
</resources>

les deux derniers éléments ne fonctionnent pas, il y a toujours une ombre sur Lollipop.

Voici à quoi cela ressemble (notez qu'il y a réellement une ombre sur la barre d'état et la barre de navigation): enter image description here

ce que je veux réaliser (nova launcher):

enter image description here

comment rendre la barre d'état et la barre de navigation "transparentes" au lieu de "translucides"?

39
renzhn

Mise à jour

Vous pouvez obtenir le même effet par programme sur KitKat et après en définissant la valeur FLAG_LAYOUT_NO_LIMITS drapeau à l'intérieur du Window.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
            Window w = getWindow(); // in Activity's onCreate() for instance
            w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
        }

Si vous définissez une ressource d'arrière-plan ( telle qu'une couleur ou une image ) dans votre mise en page, vous verrez la couleur ou l'image "sous" la barre d'état.

<item name="Android:windowDrawsSystemBarBackgrounds">true</item>
<item name="Android:statusBarColor">@color/primary_dark</item>

Réponse originale

Ça ressemble à Android:windowTranslucentStatus et Android:windowTranslucentNavigation devrait être true au lieu de false

<resources>
    <style name="Theme" parent="Android:Theme.Material.Wallpaper.NoTitleBar">
        <item name="Android:statusBarColor">@Android:color/transparent</item>
        <item name="Android:navigationBarColor">@Android:color/transparent</item>
        <item name="Android:windowTranslucentStatus">true</item>
        <item name="Android:windowTranslucentNavigation">true</item>
    </style>
</resources>

En outre, votre structure d'activité/conteneur transparente a besoin de cet ensemble de propriétés:

Android:fitsSystemWindows="true"

Source

118
Machado

J'utilise ceci car il garde la hauteur de la barre d'état et de la barre de navigation

<!-- Base application theme. -->
<style name="theme" parent="Android:Theme.Material.Wallpaper.NoTitleBar">
    <item name="Android:navigationBarColor">#00000000</item>
    <item name="Android:statusBarColor">#00000000</item>
</style>

Cela nécessite toutefois API 21+

5
denixtry

Le code suivant est un exemple de ce que j'utilise dans mon projet:

styles.xml

<style name="FadingActionBarTheme" parent="@Android:style/Theme.Holo.Light.DarkActionBar">
    <item name="Android:actionBarStyle">@style/FadingActionBarWidget</item>
</style>

<style name="FadingActionBarWidget.Transparent">
    <item name="Android:background">@Android:color/transparent</item>
</style>

<style name="FadingActionBarTheme.TranslucentActionBar">
    <item name="Android:icon">@drawable/ic_ab_icon</item>
    <item name="Android:actionBarStyle">@style/FadingActionBarWidget.Transparent</item>
    <item name="Android:windowActionBarOverlay">true</item>
    <item name="Android:windowContentOverlay">@null</item>
</style>

AndroidManifest.xml

<activity
    Android:name=".MyActivity"
    Android:label="@string/app_name"
    Android:theme="@style/FadingActionBarTheme.TranslucentActionBar">
</activity>
3
Lennon Petrick

Vous devez ajouter Android:windowDrawsSystemBarBackgrounds drapeau à votre thème

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

Ou appelez ceci dans onCreate ()

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
3
Wayne

code de travail à 100%

Barres StatusBar et NavigationBar totalement transparentes

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    transparentStatusAndNavigation();
}


private void transparentStatusAndNavigation() {
    //make full transparent statusBar
    if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
        setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, true);
    }
    if (Build.VERSION.SDK_INT >= 19) {
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        );
    }
    if (Build.VERSION.SDK_INT >= 21) {
        setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, false);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        getWindow().setNavigationBarColor(Color.TRANSPARENT);
    }
}

private void setWindowFlag(final int bits, boolean on) {
    Window win = getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();
    if (on) {
        winParams.flags |= bits;
    } else {
        winParams.flags &= ~bits;
    }
    win.setAttributes(winParams);
}
2
Ahamadullah Saikat

Pour dessiner votre mise en page sous la barre d'état:

valeurs/styles.xml

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

values-v21/styles.xml

<item name="Android:windowDrawsSystemBarBackgrounds">true</item>
<item name="Android:statusBarColor">@color/colorPrimaryDark</item>

Utilisez CoordinatorLayout/DrawerLayout qui prend déjà en charge le paramètre fitsSystemWindows ou créez votre propre présentation de la manière suivante:

public class FitsSystemWindowConstraintLayout extends ConstraintLayout {

    private Drawable mStatusBarBackground;
    private boolean mDrawStatusBarBackground;

    private WindowInsetsCompat mLastInsets;

    private Map<View, int[]> childsMargins = new HashMap<>();

    public FitsSystemWindowConstraintLayout(Context context) {
        this(context, null);
    }

    public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        if (ViewCompat.getFitsSystemWindows(this)) {
            ViewCompat.setOnApplyWindowInsetsListener(this, new Android.support.v4.view.OnApplyWindowInsetsListener() {
                @Override
                public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
                    FitsSystemWindowConstraintLayout layout = (FitsSystemWindowConstraintLayout) view;
                    layout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
                    return insets.consumeSystemWindowInsets();
                }
            });
            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            TypedArray typedArray = context.obtainStyledAttributes(new int[]{Android.R.attr.colorPrimaryDark});
            try {
                mStatusBarBackground = typedArray.getDrawable(0);
            } finally {
                typedArray.recycle();
            }
        } else {
            mStatusBarBackground = null;
        }
    }

    public void setChildInsets(WindowInsetsCompat insets, boolean draw) {
        mLastInsets = insets;
        mDrawStatusBarBackground = draw;
        setWillNotDraw(!draw && getBackground() == null);

        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                if (ViewCompat.getFitsSystemWindows(this)) {
                    ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) child.getLayoutParams();

                    if (ViewCompat.getFitsSystemWindows(child)) {
                        ViewCompat.dispatchApplyWindowInsets(child, insets);
                    } else {
                        int[] childMargins = childsMargins.get(child);
                        if (childMargins == null) {
                            childMargins = new int[]{layoutParams.leftMargin, layoutParams.topMargin, layoutParams.rightMargin, layoutParams.bottomMargin};
                            childsMargins.put(child, childMargins);
                        }
                        if (layoutParams.leftToLeft == LayoutParams.PARENT_ID) {
                            layoutParams.leftMargin = childMargins[0] + insets.getSystemWindowInsetLeft();
                        }
                        if (layoutParams.topToTop == LayoutParams.PARENT_ID) {
                            layoutParams.topMargin = childMargins[1] + insets.getSystemWindowInsetTop();
                        }
                        if (layoutParams.rightToRight == LayoutParams.PARENT_ID) {
                            layoutParams.rightMargin = childMargins[2] + insets.getSystemWindowInsetRight();
                        }
                        if (layoutParams.bottomToBottom == LayoutParams.PARENT_ID) {
                            layoutParams.bottomMargin = childMargins[3] + insets.getSystemWindowInsetBottom();
                        }
                    }
                }
            }
        }

        requestLayout();
    }

    public void setStatusBarBackground(Drawable bg) {
        mStatusBarBackground = bg;
        invalidate();
    }

    public Drawable getStatusBarBackgroundDrawable() {
        return mStatusBarBackground;
    }

    public void setStatusBarBackground(int resId) {
        mStatusBarBackground = resId != 0 ? ContextCompat.getDrawable(getContext(), resId) : null;
        invalidate();
    }

    public void setStatusBarBackgroundColor(@ColorInt int color) {
        mStatusBarBackground = new ColorDrawable(color);
        invalidate();
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mDrawStatusBarBackground && mStatusBarBackground != null) {
            int inset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
            if (inset > 0) {
                mStatusBarBackground.setBounds(0, 0, getWidth(), inset);
                mStatusBarBackground.draw(canvas);
            }
        }
    }
}

main_activity.xml

<FitsSystemWindowConstraintLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true">

    <ImageView
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        Android:fitsSystemWindows="true"
        Android:scaleType="centerCrop"
        Android:src="@drawable/toolbar_background"
        app:layout_constraintBottom_toBottomOf="@id/toolbar"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Android.support.v7.widget.Toolbar
        Android:id="@+id/toolbar"
        Android:layout_width="0dp"
        Android:layout_height="?attr/actionBarSize"
        Android:background="@Android:color/transparent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        Android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar">

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:gravity="center"
            Android:text="Content"
            Android:textSize="48sp" />
    </LinearLayout>
</FitsSystemWindowConstraintLayout>

Résultat :

result

1
Decam Developer

Pour ceux qui veulent une barre d’état et une barre de navigation complètement transparentes sur KitKat et dans les versions supérieures, il existe un petit conflit qui consiste à utiliser windowTranslucentNavigation avec @Machado answer pour Lollipop et pour éviter ce conflit, séparez les styles.

styles.xml

<style name="LockScreenStyle" parent="@Android:style/Theme.Wallpaper.NoTitleBar">
    <item name="Android:windowTranslucentStatus" tools:targetApi="KitKat">true</item>
    <item name="Android:windowTranslucentNavigation" tools:targetApi="KitKat">true</item>
</style>

styles.xml (v21)

<style name="LockScreenStyle" parent="@Android:style/Theme.Wallpaper.NoTitleBar">
    <item name="Android:windowDrawsSystemBarBackgrounds">true</item>
</style>

MyClass.Java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
        Window w = getWindow(); // in Activity's onCreate() for instance
        w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
            w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        }
    }
0
Dasser Basyouni