it-swarm.com.ru

Ящик навигации Android и windowActionBarOverlay = true

Я пытаюсь реализовать новый Android Navigation Drawer в своем приложении. Я создал BaseActivity.Java, который обрабатывает настройки Drawer и слушателей, и у меня есть две субактивности, которые расширяют этот базовый класс. Во втором упражнении я планирую использовать другой стиль панели действий, используя следующие атрибуты:

<item name="Android:windowActionBarOverlay">true</item>
<item name="Android:background">@Android:color/transparent</item>

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

Я достиг всего этого, но теперь проблема в том, что, поскольку контент расширяется, чтобы использовать дополнительное пространство использования ActionBar в качестве наложения, сам Navigation Drawer тоже расширяется и перекрывает ActionBar, создавая довольно ужасный выглядит макет: 

enter image description here

То, что я хотел бы сделать, это фактический контент (структура фрейма, который будет заполнен фрагментом), чтобы занять дополнительное пространство, но навигационный ящик по-прежнему должен находиться под панелью действий, подобно приложению Play Music: 

enter image description here

Любые идеи о том, что я могу сделать, чтобы это произошло? 

EDIT Итак, с помощью Ахмада я установил marginTop только для ListView. Вот макет: 

<!-- The navigation drawer -->
<ListView Android:id="@+id/left_drawer"
          Android:layout_marginTop="?android:attr/actionBarSize"
<!-- This was added after seeing the crazy effect, but does nothing -->
          Android:layout_marginBottom="0dp"
          Android:layout_marginLeft="0dp"
          Android:layout_marginRight="0dp"
          Android:layout_width="240dp"
          Android:layout_height="fill_parent"
          Android:layout_gravity="start"
          Android:choiceMode="singleChoice"
          Android:background="?attr/listviewBackground"
          />

И теперь, это прекрасно работает для верхней стороны, но по какой-то причине в нижней части обзора также есть поле, которое вообще не имеет никакого смысла для меня. Вот скриншот

Не уверен, что вызывает это :(

25
daniel_c05

Если кто-то заинтересован в другом, возьмите этот вопрос. Вот что случилось. 

Я попытался установить только поле в верхней части списка, как это: 

Android:layout_marginTop="?android:attr/actionBarSize"

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

Итак, я внимательно посмотрел на приложение Play Music и заметил, что на самом деле это не поле, а отступы, и, кроме того, они используют собственный фон, который заполняет пространство, заданное заполнением, прозрачным цветом. 

Вот что я сделал: 

  • Установите Padding в верхней части ListView, а не на полях: 

    Android:paddingTop="?android:attr/actionBarSize"

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

  • Создайте собственный чертеж, который имеет прозрачную верхнюю часть, а затем остальную часть сплошного цвета: 

Это выглядит как-то так: 

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<item>
    <shape  Android:shape="rectangle">
        <solid Android:color="#80000000" />
    </shape>
</item>

<item Android:top="@dimen/action_bar_default_height">
    <shape
            Android:shape="rectangle">
        <solid Android:color="@color/light_gray" />
    </shape>
</item>

Обратите внимание, что я пытался использовать ?android:attr/actionBarSize для рисования, но это заставило приложение закрыться. Вместо этого я искал grepcode и нашел несколько файлов измерений с разными размерами для панели действий, поэтому я добавил их в файлы измерений моего собственного проекта. 

  • Для значений: 48dp
  • Для ценностей земли: 40dp
  • Для значений-sw600dp: 56dp

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

enter image description here

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

14
daniel_c05

И теперь, это прекрасно работает для верхней стороны, но по какой-то причине в нижней части обзора также есть поле, которое вообще не имеет никакого смысла для меня. Вот скриншот.

Если вы установите гравитацию ListView на start | bottom , это решит вашу проблему. Никакой дополнительной маржи внизу не добавлено. Похоже, гравитация DrawerLayout по умолчанию это начало | центр

<ListView
    Android:id="@+id/left_drawer"
    Android:layout_marginTop="?android:attr/actionBarSize"
    Android:layout_width="240dp"
    Android:layout_height="match_parent"
    Android:layout_gravity="start|bottom"/>
17
kofi

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

Просто добавьте это в ваш родительский макет:

Android:layout_marginTop="?android:attr/actionBarSize"

Атрибут actionBarSize относится, как вы уже догадались, к размеру ActionBar. Вы не можете установить абсолютное значение в качестве запаса, поскольку ActionBar не всегда имеет одинаковый размер на всех устройствах Android (он больше на планшетах, меньше на мобильных устройствах). 

Правка:

Установите поле на ListView.

<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <FrameLayout
        Android:id="@+id/content_frame"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

    <ListView
        Android:id="@+id/left_drawer"
        Android:layout_marginTop="?android:attr/actionBarSize"
        Android:layout_width="240dp"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"/>
</Android.support.v4.widget.DrawerLayout>

Приложение Google Music делает то же самое:

enter image description here

8
Ahmad

Я решил эту проблему, используя paddingTop :

<FrameLayout
    Android:id="@+id/menu_frame"
    Android:layout_width="240dp"
    Android:layout_height="match_parent"
    Android:layout_gravity="start"
    Android:paddingTop="?attr/actionBarSize" >

    <ListView 
        Android:id="@+id/left_drawer_list"
        Android:layout_width="240dp"
        Android:layout_height="match_parent" />

</FrameLayout>

Надеюсь, это поможет

4
Vadim Bryl

Я создал рабочую демонстрацию, следуя вышеприведенному руководству, и протестировал на 2.x до 5.x 

Вы можете клонировать из Github

Важная вещь для игры в основной деятельности 

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    res = this.getResources();

    this.setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setHomeButtonEnabled(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop)
    { 
        ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout)
                findViewById(R.id.linearLayout);
        scrimInsetsFrameLayout.setOnInsetsCallback(this);
    } 

и перезвонить 

@Override
public void onInsetsChanged(Rect insets) {
      Toolbar toolbar = this.toolbar;
        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
                toolbar.getLayoutParams();
        lp.topMargin = insets.top;
        int top = insets.top;
        insets.top += toolbar.getHeight();
        toolbar.setLayoutParams(lp);
        insets.top = top; // revert
}

Абсолютно тема для V21 делает волшебство 

 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

    <!-- API 21 theme customizations can go here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/accent_material_light</item>
    <item name="windowActionModeOverlay">true</item>
    <item name="Android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="Android:statusBarColor">@Android:color/transparent</item>
    <item name="Android:windowTranslucentStatus">true</item>
</style>
0
Vipin Sahu