Полупрозрачные системные панели и поля контента в KitKat

Я пытаюсь воспользоваться новыми полупрозрачными системными панелями KitKat, чтобы получить полноэкранное изображение на фоне моего приложения.

У меня проблемы с определением правильных настроек для получения желаемого поведения. Прямо сейчас у меня есть ViewPager с тремя Fragment, каждый из которых состоит из RelativeLayout, содержащего ImageView (для фонового изображения) и TextView для содержимого.

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

Если я просто использую android:Theme.Holo.Light.NoActionBar.TranslucentDecor в качестве темы, она отлично выглядит в портретной ориентации, но панель навигации перекрывает контент в альбомной ориентации (см. скриншоты ниже).

Первая попытка - портрет. Выглядит хорошо.Первая попытка — горизонтальная. Панель навигации перекрывает содержимое

Следуя рекомендации в документации, я добавил android:fitsSystemWindows = true в свою тему, но при этом возникают странные артефакты (см. ниже) Вторая попытка - портрет. Артефакты!!Вторая попытка - пейзаж. Артефакты!!

Как сделать так, чтобы он вел себя как во втором примере, но хорошо выглядел, без визуальных артефактов?


person Krzysztof Kozmic    schedule 26.12.2013    source источник


Ответы (5)


Я знаю, что это старо, но я только что столкнулся с той же проблемой и нашел простое решение, поэтому я хотел поделиться ею на случай, если кто-нибудь столкнется с этим в Google.

Кажется, существует ошибка Android, когда ViewPager (особенно ImageSwitcher) помещается в макет с атрибутом android:fitsSystemWindows="true". По какой-то причине на системных окнах появляются артефакты. :/

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

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    <!-- NOT HERE! android:fitsSystemWindows="true" -->
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageSwitcher
        android:id="@+id/background_image_switcher"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="0dp"
        android:layout_margin="0dp"
        android:background="@color/background_dark_navy"
        android:inAnimation="@android:anim/fade_in"
        android:outAnimation="@android:anim/fade_out"
        >

        <ImageView
            style="@style/BlurredBackgroundImage"
            />
        <ImageView
            style="@style/BlurredBackgroundImage"
            />

    </ImageSwitcher>

    <FrameLayout
        android:fitsSystemWindows="true" <!-- Here!!! -->
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- Fitted content here -->

    </FrameLayout>

Хитрость заключалась в том, чтобы не содержать ImageSwitcher в макете с атрибутом android:fitsSystemWindows="true", а вместо этого переместить атрибут android:fitsSystemWindows="true" в inner FrameLayout, содержащий фактический контент, который мне нужно было разместить (текст заголовка в вашем случае) . К сожалению, это позволяет представлению ImageSwitcher/ViewPager быть слегка обрезанным системными окнами, но если изображение используется как фоновое изображение, в любом случае это не имеет большого значения и является гораздо лучшим компромиссом, чем артефакты или сохранение всех различных размеров/стилей, которые могут отключать или не отключать навигацию (например, текущий выбранный ответ).

Я надеюсь, что это помогает кому-то!

person Rican7    schedule 10.07.2014
comment
Я зарегистрировал ошибку Android для этой проблемы. Не стесняйтесь пометить его, чтобы получать обновления о ходе его выполнения: code.google. com/p/android/issues/detail?id=73372 - person Rican7; 11.07.2014

Мое решение состояло в том, чтобы отключить полупрозрачную навигацию в ландшафтном режиме. Вы по-прежнему получаете полупрозрачную строку состояния, но она устраняет проблему, когда панель навигации непрозрачна и перекрывается в альбомной ориентации.

res/values-v19/styles.xml (эти значения есть в моей теме)

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

res/values-v19/bools.xml (включить полупрозрачную навигацию)

<bool name="translucentNavBar">true</bool>

res/values-land-v19/bools.xml (отключить полупрозрачную навигацию в альбомной ориентации)

<bool name="translucentNavBar">false</bool>

res/values-sw600dp-land-v19/bools.xml (включить полупрозрачную навигацию для планшетов в альбомной ориентации)

<bool name="translucentNavBar">true</bool>
person Tanner Perrien    schedule 27.12.2013
comment
+1 за умный обходной путь;) Это лучшее решение? Например, на планшетах панель навигации остается полупрозрачной и перемещает нижнюю часть экрана в книжной ориентации, поэтому я не хочу отключать ее там... - person Krzysztof Kozmic; 29.12.2013
comment
Это решение отключает панель навигации только в альбомной, а не в портретной ориентации. Я что-то неправильно понял? Из того, что я могу сказать, моя проблема была точно такой же, как ваша. Как бы то ни было, мне не нужно было использовать android:fitsSystemWindows - person Tanner Perrien; 29.12.2013
comment
Нет простите. Я имел в виду в альбомной ориентации. На планшетах панель навигации остается прозрачной и находится (логично) внизу экрана независимо от ориентации, поэтому проблема возникает только на телефонах. Так что было бы неплохо, если ваш обходной путь действительно является наименее худшим решением, применять его только к телефонам или, в более общем плане, к устройствам/ориентациям, где панель навигации становится непрозрачной. - person Krzysztof Kozmic; 29.12.2013
comment
Понятно! Я только что отредактировал свой ответ, чтобы отразить, как вы можете включить полупрозрачную навигацию для альбомной ориентации на планшетах. - person Tanner Perrien; 29.12.2013
comment
Разве это не должно быть res/values-sw600dp-land-v19/bools.xml? - person Lesik2008; 22.02.2014
comment
да. Обновлено. Спасибо! - person Tanner Perrien; 26.02.2014

Я сталкивался с подобными проблемами, но я не использовал ViewPager, так что это может не сработать. Я решил, выполнив некоторую вложенность, как описал Гейб: только внутренняя ViewGroup имеет форму fitSystemWindows="true", поэтому внешняя ViewGroup, отображающая фон, может располагаться под полупрозрачными полосами. Затем я также вызываю requestFitSystemWindows() при изменении ориентации. Опять же, ваш ViewPager может усложнять ситуацию, и мое решение не будет работать, но я надеюсь, что это поможет.

person danh32    schedule 03.01.2014

Поместите еще одну ViewGroup внутрь группы с изображением и подходит дляSystemWindows к истине

person Gabe    schedule 26.12.2013
comment
Эй, спасибо за вашу помощь. Я обновил вопрос, упомянув, что вокруг этого есть ViewPager. Каждый экран также имеет свой фон. Я попробовал вашу рекомендацию. Я добавил еще один RelativeLayout, но это не совсем то, что нужно. Я все еще получаю визуальные артефакты, хотя теперь они ведут себя по-другому. Вот запись экрана в портретной и альбомной ориентации, показывающая, что происходит (обратите внимание, насколько она непоследовательна): dl .dropboxusercontent.com/u/2887400/landscape_1.mp4 и dl.dropboxusercontent .com/u/2887400/portrait_1.mp4 - person Krzysztof Kozmic; 26.12.2013

Вы должны обернуть это внутри линейного макета и установить fitsSystemWindows в true.

person user3339439    schedule 29.07.2014