Android Navigation Drawer и windowActionBarOverlay = true
Я пытаюсь внедрить новый Android-навигатор в моем приложении. Я создал BaseActivity.java, который обрабатывает настройку ящика и слушателей, и у меня есть две субактивности, которые расширяют этот базовый класс. Во втором действии я планирую использовать другой стиль панели действий, используя следующие attrs:
<item name="android:windowActionBarOverlay">true</item>
<item name="android:background">@android:color/transparent</item>
чтобы сделать панель действий прозрачной и сделать контент богаче, поскольку в моем макете есть заголовок изображения.
Я достиг только этого, но теперь проблема заключается в том, что, поскольку контент расширяется, чтобы использовать дополнительное пространство для использования ActionBar в качестве наложения, сам ящик навигации также расширяется, и он перекрывает ActionBar, создавая довольно ужасно выглядящий макет:
![enter image description here]()
То, что я хотел бы сделать, - это фактическое содержимое (фрейм-макет, который будет заполнен фрагментом), чтобы заняться дополнительным пространством, но ящик навигатора по-прежнему находится под панелью действий, аналогично Play Музыкальное приложение:
![enter image description here]()
Любые идеи о том, что я могу сделать, чтобы это произошло?
РЕДАКТИРОВАТЬ Итак, согласно помощи Ахмада, я устанавливаю 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"
/>
И теперь, он отлично работает для верхней стороны, но по какой-то причине также имеет место в нижней части представления, что совершенно не имеет для меня никакого смысла. Вот скриншот.
Не уверен, что это заставляет: (
Ответы
Ответ 1
В случае, если кто-то заинтересован в другом вопросе на этот вопрос. Вот что случилось.
Я попытался установить только край в верхней части списка, например:
android:layout_marginTop="?android:attr/actionBarSize"
Но, как упоминалось в отредактированном вопросе, у этого было странное поведение, когда на дне также был край, несмотря на то, что он не был установлен в файле ресурсов макета.
Итак, я внимательно смотрел приложение Play Music и заметил, что это не на самом деле маржа, а скорее прокладка, и, кроме того, они используют настраиваемый фон, который заполняет пространство, заданное заполнением прозрачным цветом.
Вот что я сделал:
-
Устанавливаем заполнение в верхней части списка 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
в drawable, но это заставило силу приложения закрыть. Вместо этого я просмотрел grepcode и нашел несколько файлов dimen с разными размерами для панели действий, поэтому я добавил их в свои собственные файлы проекта dimen.
- Для значений: 48dp
- Для значений-land: 40dp
- Для значений-sw600dp: 56dp
И после этого, я думаю, я отлично смотрю, заметьте на скриншоте, как список и панель действий не перекрываются, а прозрачная часть списка - это только правильный размер.
![enter image description here]()
Надеюсь, что это поможет любому, кто задавался вопросом, как этого добиться.
Ответ 2
И теперь, он отлично работает для верхней стороны, но по какой-то причине также имеет место в нижней части представления, что совершенно не имеет для меня никакого смысла. Вот скриншот.
Если вы установите гравитацию ListView на start | bottom, она решит вашу проблему. Никакой дополнительный запас не добавляется внизу. Похоже, что сила DrawerLayout по умолчанию - начало | center
<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"/>
Ответ 3
Вы можете установить маркер в верхней части макета, чтобы контент рисовал себя ниже ActionBar.
Просто добавьте это в родительский макет:
android:layout_marginTop="?android:attr/actionBarSize"
Атрибут actionBarSize
относится, как вы уже догадались, к размеру ActionBar
. Вы не можете установить абсолютное значение в качестве поля, так как ActionBar
не всегда имеет одинаковый размер на всех устройствах Android (он больше на планшетах, меньше на устройствах телефонной трубки).
Edit:
Задайте значение поля 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]()
Ответ 4
Я решил эту проблему, используя 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>
Надеюсь, что поможет
Ответ 5
Я создал рабочую демонстрацию, следуя приведенному выше руководству, и протестировал ее на 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>