Android Полностью прозрачная строка состояния?


184

Я искал документацию, но нашел только это: Ссылка . Что используется, чтобы сделать бар прозрачным ? Я пытаюсь сделать строку состояния полностью прозрачной (как показано на рисунке ниже) и сделать ее обратно совместимой для APK <19: введите описание изображения здесь

Мой styles.xml:

<resources xmlns:tools="http://schemas.android.com/tools">

  <style name="AppTheme" parent="Theme.AppCompat.Light">
  <item name="android:actionBarStyle">@style/ThemeActionBar</item>
  <item name="android:windowActionBarOverlay">true</item>
  <!-- Support library compatibility -->
  <item name="actionBarStyle">@style/ThemeActionBar</item>
  <item name="windowActionBarOverlay">true</item>
  </style>

  <style name="ThemeActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid">
  <item name="android:background"> @null </item>
  <!-- Support library compatibility -->
  <item name="background">@null</item>
  <item name="android:displayOptions"> showHome | useLogo</item>
  <item name="displayOptions">showHome|useLogo</item>

  </style>

</resources>

Что я смог сделать:

введите описание изображения здесь

Ответы:


370

Все, что вам нужно сделать, это установить эти свойства в вашей теме:

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

Для вашей деятельности / макета контейнера, для которого вы хотите иметь прозрачную строку состояния, необходимо установить следующее свойство:

android:fitsSystemWindows="true"

Как правило, это невозможно выполнить на pre-kitkat, похоже, что вы можете это сделать, но какой-то странный код делает это так .

РЕДАКТИРОВАТЬ: Я бы порекомендовал эту библиотеку: https://github.com/jgilfelt/SystemBarTint для многих элементов управления цветом строки состояния перед леденцом на палочке.

После долгих размышлений я узнал, что ответом на полное отключение прозрачности или любого цвета, помещенного в строку состояния и панель навигации для леденца на палочке, является установка этого флага в окне:

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

Никакая другая тема не нужна, она производит что-то вроде этого:

введите описание изображения здесь


21
Я использовал код, а затем добавил изображение в качестве фона, а затем добавил android:fitsSystemWindows="true"в мой activity_main.xml. Панели системы являются полупрозрачными и не прозрачными.
Мухаммед Али

9
Ну, я считаю, что все, что вам нужно в этом случае, это добавить <item name="android:statusBarColor">@android:color/transparent</item>к вашей теме :)
Даниэль Уилсон,

7
Да, спасибо, за ваше терпение, я нахожусь почти на ходу, так как я пытался сделать это в течение последних нескольких часов xD. Приведенный выше код не работает, однако я установил android:windowTranslucentStatusзначение false, и строка состояния стала прозрачной. Теперь я сделал то же самое с панелью навигации и добавил, <item name="android:navigationBarColor">@android:color/transparent</item>но она делает серые обе панели. UGH!
Мухаммед Али

4
Чтобы заставить "AdjustPan" работать, используйте w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);вместо этого
Арда Кара

4
ПРИМЕЧАНИЕ: использование флага FLAG_LAYOUT_NO_LIMITS также поместит ваш макет под панель виртуальной навигации внизу. В общем, вы не хотите этого делать ... так же, как говорили другие люди :-(
kenyee


16

Вы можете использовать внешнюю библиотеку StatusBarUtil :

Добавьте на свой уровень модуля build.gradle:

compile 'com.jaeger.statusbarutil:library:1.4.0'

Затем вы можете использовать следующую утилиту для действия, чтобы сделать строку состояния прозрачной:

StatusBarUtil.setTransparent(Activity activity)

Пример:

прозрачная строка состояния на Lollipop и KitKat


Как это сделать для Navigation Drawer?
Reejesh PK

24
Библия только для того, чтобы решить это, как зажечь свечу огнеметом
Фелипе Кастильос

@FelipeCastilhos, да, может быть, но что, если вы делаете много разных вещей со строкой состояния и не хотите иметь дело с плохим API, предоставляемым Google?
Дэвид Роусон

@DavidRawson, это другой сценарий. Здесь речь идет только о добавлении прозрачности. Зачем добавлять много кода сторонних разработчиков в вашу кодовую базу только для того, чтобы справиться с этим?
Фелипе Кастильос

14

Работает для Android KitKat и выше (для тех, кто хочет прозрачно отображать строку состояния и не манипулирует навигационной панелью, потому что все эти ответы также будут прозрачной навигационной панелью!)

Самый простой способ добиться этого:

Поместите эти 3 строки кода в styles.xml (v19)->, если вы не знаете, как это сделать (v19), просто напишите их по умолчанию, styles.xmlа затем используйте alt+, enterчтобы автоматически создать его:

<item name="android:windowFullscreen">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:fitsSystemWindows">false</item>

А теперь перейдите в ваш MainActivityкласс и выведите этот метод из onCreate в классе:

public static void setWindowFlag(Activity activity, final int bits, boolean on) {

    Window win = activity.getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();
    if (on) {
        winParams.flags |= bits;
    } else {
        winParams.flags &= ~bits;
    }
    win.setAttributes(winParams);
}

Затем поместите этот код в onCreateметод Activity:

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
        setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
    }
    if (Build.VERSION.SDK_INT >= 19) {
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }
    //make fully Android Transparent Status bar
    if (Build.VERSION.SDK_INT >= 21) {
        setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }

Это оно!


1
Как показывает мой опыт в React Native ... Приведенные выше коды конфликтуют с отображением клавиатуры (AdjustResize). Итак, я просто делаю небольшие изменения: `` `if (Build.VERSION.SDK_INT> = 19) {getWindow (). GetDecorView (). SetSystemUiVisibility (View.SYSTEM_UI_FLAG_LAYOUT_STABLE); } `` `и в Компоненте` `` <StatusBar translucent = {true} backgroundColor = "transparent" /> `` `и в AppManisfes - MainActivity` `` android: windowSoftInputMode = "AdjustResize" `` `и остальные коды тем же. fyi: `` `реагировать-нативный": "0.61.5", `` `спасибо @parsa dadras
Руди Виджая

12

Полностью прозрачная панель состояния и панель навигации

@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);
}

Единственное решение, которое действительно работает для меня наряду с режимом киоска (закрепление экрана).
Бронтес

11

Чтобы нарисовать макет под строкой состояния:

Значения / styles.xml

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

Значения-V21 / styles.xml

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

Используйте CoordinatorLayout / DrawerLayout, который уже позаботится о параметре fitsSystemWindows, или создайте свой собственный макет так:

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>

Результат:

Скриншот:
Скриншот


11

Вы можете использовать код ниже, чтобы сделать строку состояния прозрачной. Смотрите изображения с красной подсветкой, которая поможет вам определить использование кода ниже

1]

Фрагмент кода Kotlin для вашего приложения для Android

Шаг: 1 Запишите код в методе создания

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
    setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true)
}
if (Build.VERSION.SDK_INT >= 19) {
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
if (Build.VERSION.SDK_INT >= 21) {
    setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false)
    window.statusBarColor = Color.TRANSPARENT
}

Шаг 2: Вам нужен метод SetWindowFlag, который описан ниже.

private fun setWindowFlag(bits: Int, on: Boolean) {
    val win = window
    val winParams = win.attributes
    if (on) {
        winParams.flags = winParams.flags or bits
    } else {
        winParams.flags = winParams.flags and bits.inv()
    }
    win.attributes = winParams
}

Фрагмент кода Java для вашего приложения для Android:

Шаг 1: Основной код активности

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
}
if (Build.VERSION.SDK_INT >= 19) {
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

if (Build.VERSION.SDK_INT >= 21) {
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
    getWindow().setStatusBarColor(Color.TRANSPARENT);
}

Шаг 2: метод SetWindowFlag

public static void setWindowFlag(Activity activity, final int bits, boolean on) {
    Window win = activity.getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();
    if (on) {
        winParams.flags |= bits;
    } else {
        winParams.flags &= ~bits;
    }
    win.setAttributes(winParams);
}

1
Я просто делюсь своим кодом с нашим сообществом разработчиков, чтобы помочь. Code
CodeInsideCofee

6

Используйте android:fitsSystemWindows="false"в вашем топ-макете


6
это влияет и на панель навигации
Ebrahim Karimi

5

Вот расширение в kotlin, которое делает свое дело:

fun Activity.setTransparentStatusBar() {
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        window.statusBarColor = Color.TRANSPARENT
    }
}

4

Используя этот код в своем XML, вы сможете увидеть временную шкалу в вашей деятельности:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

3

Есть три шага:

1) Просто используйте этот сегмент кода в свой метод @OnCreate

@OnCreate{
  // FullScreen
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 
  WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

если вы работаете с фрагментом, вы должны поместить этот сегмент кода в метод @OnCreate своей деятельности.

2) Обязательно установите прозрачность в /res/values-v21/styles.xml:

<item name="android:statusBarColor">@android:color/transparent</item>

Или вы можете установить прозрачность программно:

getWindow().setStatusBarColor(Color.TRANSPARENT);

3) В любом случае вы должны добавить сегмент кода в styles.xml

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

ПРИМЕЧАНИЕ. Этот метод работает только с API 21 и выше.


2

Вы также можете просмотреть мой пример с анимированным аватаром и анимированным текстом.

CollapsingAvatarToolbarSample

Читайте мой пост на Medium

Итак, позвольте мне объяснить, как это работает. Я создал собственный вид, реализованный AppBarLayout.OnOffsetChangedListener . Внутри HeadCollapsing Custom View я основал текст и изображение в AppBarLayout.

class HeadCollapsing(context: Context, attrs: AttributeSet?) : 
 FrameLayout(context, attrs), AppBarLayout.OnOffsetChangedListener {

  private fun findViews() {
            appBarLayout = findParentAppBarLayout()

            avatarContainerView = findViewById(R.id.imgb_avatar_wrap)

            titleToolbarText =  findViewById<AppCompatTextView>(id)

        }

  private fun findParentAppBarLayout(): AppBarLayout {
    val parent = this.parent
    return parent as? AppBarLayout ?: if (parent.parent is AppBarLayout) {
        parent.parent as AppBarLayout
    } else {
        throw IllegalStateException("Must be inside an AppBarLayout")
    }
}

  ...

     override fun onOffsetChanged(appBarLayout: AppBarLayout, offset:Int) {
           ...
           //Calculate expanded percentage
           val expandedPercentage = 1 - -offset / maxOffset
           updateViews(expandedPercentage)
     }
}

Затем измените просмотры через рассчитанный процент. Например, как меняется вид текста:

         when {
                inversePercentage < ABROAD -> {
                    titleToolbarText?.visibility = View.VISIBLE
                    titleTolbarTextSingle?.visibility = View.INVISIBLE
                }

                inversePercentage > ABROAD -> {
                    titleToolbarText?.visibility = View.INVISIBLE
                    titleTolbarTextSingle?.visibility = View.VISIBLE
                    titleTolbarTextSingle?.let {
                        animateShowText(it)
                    }
                }
            }

Чтобы определить, когда нужно свернуть изображение, оживить созданный объект Pair

private var cashCollapseState: kotlin.Pair<Int, Int>? = null

с состояниями: TO_EXPANDED_STATE, TO_COLLAPSED_STATE, WAIT_FOR_SWITCH, SWITCHED

  companion object {
        const val ABROAD = 0.95f
        const val TO_EXPANDED_STATE = 0
        const val TO_COLLAPSED_STATE = 1
        const val WAIT_FOR_SWITCH = 0
        const val SWITCHED = 1
    }

затем создана анимация для аватара с состоянием:

 when {
                cashCollapseState != null && cashCollapseState != state -> {
                    when (state.first) {
                        TO_EXPANDED_STATE -> {
                          // do calculates
                        }
                        TO_COLLAPSED_STATE -> {

                    ValueAnimator.ofFloat(avatarContainerView.translationX, translationX).apply {
                        addUpdateListener {
                            avatarContainerView.translationX = it.animatedValue as Float
                        }

                        duration = 350
                        (state.first == TO_COLLAPSED_STATE).apply {
                            if (this) interpolator = LinearInterpolator()
                        }
                        start()
                    }
                //SWITCH STATE CASE
                cashCollapseState = kotlin.Pair(state.first, SWITCHED)
            }

            else -> {
                cashCollapseState = kotlin.Pair(state.first, WAIT_FOR_SWITCH)
            }

2

Вы можете попробовать это.

private static void setStatusBarTransparent(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        activity.getWindow(). setStatusBarColor(Color.TRANSPARENT);
    } else {
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    }
}

1

Хотя все ответы, приведенные выше, распространяются вокруг одной и той же фундаментальной идеи, вы можете заставить ее работать с простыми макетами, используя один из приведенных выше примеров. Однако я хотел изменить цвет фона, используя скользящую навигацию по фрагментам в полноэкранном режиме (кроме панели вкладок) и поддерживая регулярную навигацию, вкладки и панели действий.

Внимательно прочитав статью Антона Хадуцкого, я лучше понял, что происходит.

У меня есть DrawerLayoutс ConstraintLayout(т.е. контейнер), который имеет Toolbar, включают в себя для основного фрагмента и BottomNavigationView.

Установка DrawerLayoutимея fitsSystemWindowsистина не является достаточным, вам необходимо установить как DrawerLayoutи ConstraintLayout. Предполагая прозрачную строку состояния, цвет строки состояния теперь совпадает с цветом фона ConstraintLayout.

Тем не менее, включенный фрагмент все еще имеет вставку строки состояния, поэтому анимация другого «полноэкранного» фрагмента поверх элемента не меняет цвет строки состояния.

Немного кода из упомянутой статьи в Activity«s onCreate:

ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { view, insets ->
        insets.replaceSystemWindowInsets(
                insets.systemWindowInsetLeft,
                0,
                insets.systemWindowInsetRight,
                insets.systemWindowInsetBottom
        )
    }

И все хорошо, за исключением того, что теперь Toolbarне учитывается высота строки состояния. Еще несколько со ссылкой на статью, и у нас есть полностью рабочее решение:

val toolbar = findViewById<Toolbar>(R.id.my_toolbar)
    ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { view, insets ->
        val params = toolbar.layoutParams as ViewGroup.MarginLayoutParams
        params.topMargin = insets.systemWindowInsetTop
        toolbar.layoutParams = params
        insets.replaceSystemWindowInsets(
                insets.systemWindowInsetLeft,
                0,
                insets.systemWindowInsetRight,
                insets.systemWindowInsetBottom
        )
    }

Main_activity.xml (обратите внимание, что поле marginTop Toolbarдля предварительного просмотра будет заменено кодом):

<?xml version="1.0" encoding="utf-8"?>
    <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        >

    <androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/green"
        android:fitsSystemWindows="true"
        tools:context=".MainActivity">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/my_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_constraintTop_toTopOf="@id/container"
            android:layout_marginTop="26dp" 
            android:background="@android:color/transparent"
            ...>
            ...
        </androidx.appcompat.widget.Toolbar>

        <include layout="@layout/content_main" />
        ...
    </androidx.constraintlayout.widget.ConstraintLayout>
    ...
</androidx.drawerlayout.widget.DrawerLayout>

1

Я нашел, что возиться с styles.xml и действием слишком громоздко, поэтому создал общий метод утилит, который имеет следующие параметры

Ява

Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
window.setStatusBarColor(Color.TRANSPARENT);

Котлин DSL

activity.window.apply {
    clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
    addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
    decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    statusBarColor = Color.TRANSPARENT
}

И это все, что нужно для достижения прозрачной строки состояния. Надеюсь это поможет.


0

android:fitsSystemWindows="true"работают только на v21. Мы можем установить его в теме XML или в родительском макете, как LinearLayoutили в CoordinateLayout. Для ниже v21, мы не могли добавить этот флаг. Пожалуйста, создайте другую папку значений с другим style.xmlфайлом в соответствии с вашими потребностями.


0

Это сработало для меня:

<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>

0

Все, что нужно, это пойти в MainActivity.java


protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Window g = getWindow();
        g.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

        setContentView(R.layout.activity_main);

    }

Тем не менее, я получаю некоторые страшные ошибки, когда я начинаю прокручивать вниз.

0

в моем случае, поскольку у меня есть нижняя панель инструментов, у меня возникла проблема при тестировании предыдущих решений, кнопки системы Android покрыты моим нижним меню, которое я хочу добавить в упражнение:

protected void onCreate (Bundle saveInstanceState) {super.onCreate (saveInstanceState);

    // force full screen mode
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);


    setContentView(R.layout.main_activity_container);

0

Вы можете использовать этот код ниже.

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 
getWindow().setStatusBarColor(Color.TRANSPARENT);

Включите этот макет в ваш основной макет.

toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbarNav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        app:contentInsetEnd="0dp"
        app:contentInsetLeft="0dp"
        app:contentInsetRight="0dp"
        app:contentInsetStart="0dp">

        <RelativeLayout
            android:id="@+id/rlBackImageLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/main_background2">  //add your color here

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="@dimen/_40sdp"
                android:layout_marginTop="@dimen/_16sdp"
                android:orientation="horizontal">

                <ImageView
                    android:id="@+id/toolbarIcon"
                    android:layout_width="@dimen/_30sdp"
                    android:layout_height="@dimen/_30sdp"
                    android:layout_gravity="center"
                    android:layout_marginStart="@dimen/_10sdp"
                    android:padding="@dimen/_5sdp"
                    android:src="@drawable/nav_icon" />

                <TextView
                    android:id="@+id/txtTitle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:layout_marginEnd="@dimen/_30sdp"
                    android:fontFamily="@font/muli_semibold"
                    android:gravity="center"
                    android:textColor="#fff"
                    android:textSize="@dimen/_14ssp"
                    android:textStyle="bold"
                    tools:text="test Data" />

            </LinearLayout>

        </RelativeLayout>

    </androidx.appcompat.widget.Toolbar>

Примечание: вы можете заменить SDP и SSP на dp и sp соответственно.


0

в моем случае я вообще не вызываю «onCreate» (это собственное приложение реагировать, и это можно исправить также с помощью компонента ActB-Status StatusBar), можно также использовать это:

override fun onStart() {
        super.onStart()
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.statusBarColor = Color.TRANSPARENT
}

0

Это должно работать

// В Activity, например, onCreate ()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    Window w = getWindow();
    w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

0

Я нашел ответ во время исследования этой библиотеки: https://github.com/laobie/StatusBarUtil

поэтому вам нужно добавить следующие коды в вашу деятельность

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
    window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
    window.statusBarColor = Color.TRANSPARENT
} else {
    window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}

0

добавьте эти строки в свою активность перед setContentView ()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    Window w = getWindow();
    w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

добавьте эти 2 строки в ваш AppTheme

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

и последнее, что ваш minSdkVersion должен б 19

minSdkVersion 19

-1
 <item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
            <!--<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>-->

Не windowLightStatusBarиспользуйте вместо этогоstatusBarColor = @android:color/transparent


-1

Это только для уровня API> = 21. Это работает для меня. Вот мой код (Kotlin)

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<View>(android.R.id.content).systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.