layout_weight не работает с LinearLayout внутри Drawerlayout

Я борюсь с LinearLayout при использовании DrawerLayout. Это использует шаблон Android Studio для DrawerLayout:

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

<!-- As the main content view, the view below consumes the entire
     space available using match_parent in both dimensions. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:background="#00f"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
    <LinearLayout
        android:background="#f00"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0" />
    </LinearLayout>
</LinearLayout>

<!-- android:layout_gravity="start" tells DrawerLayout to treat
     this as a sliding drawer on the left side for left-to-right
     languages and on the right side for right-to-left languages.
     If you're not building against API 17 or higher, use
     android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
     the container. -->
<fragment android:id="@+id/navigation_drawer"
    android:layout_width="@dimen/navigation_drawer_width"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:name="com.test.testdrawerlayout.NavigationDrawerFragment"
    tools:layout="@layout/fragment_navigation_drawer" />

</android.support.v4.widget.DrawerLayout>

Предварительный просмотр в Android Studio показывает это:

http://imgur.com/UlPGzJS

Однако при работе на моем Nexus 5 отображается следующее:

http://imgur.com/w4QeGbB

Как видите, часть layout_weight="1" вообще не отображается. Однако, когда я создаю пустой проект с внутренним LinearLayout, макет работает (синий макет занимает большую часть экрана, а красный макет внизу, как и предварительный просмотр).

Любые идеи будут действительно оценены, так как я сейчас совершенно в тупике. Заранее спасибо.


person Farplaner    schedule 27.07.2014    source источник
comment
Я думаю, что для DrawerLayout вам лучше использовать frameLayout в качестве контейнера содержимого и поместить linearLayout в frameLayout. Тогда это должно работать.   -  person Charlesjean    schedule 27.07.2014
comment
Я попытался добавить frameLayout, чтобы обернуть LinearLayout. Произошло то же самое.   -  person Farplaner    schedule 27.07.2014
comment
ОМГ, именно то, что я хотел спросить!   -  person milosmns    schedule 12.12.2015
comment
Для меня простая раскладка с весами работала, а более сложная — нет. Я еще не изолировал сломанный кусок головоломки, но ни одно из приведенных ниже решений не сработало.   -  person Richard Le Mesurier    schedule 17.02.2016


Ответы (3)


Похоже, я использовал более старую платформу Android SDK. Как только я зашел в диспетчер SDK и установил API 19, все заработало (с новым проектом).

Может быть, это была ошибка в более старой реализации?

person Farplaner    schedule 27.07.2014
comment
Обязательно проверьте, работает ли он на более раннем API. Я бы по-прежнему рекомендовал вам посмотреть то, что я рассказал вам об использовании android:weightSum, потому что ваши linearlayouts могут оказаться проблематичными в будущем, если они не будут правильно спроектированы. - person ChallengeAccepted; 28.07.2014

Это определенно проблема Android (или, по крайней мере, проблема appcompat/design библиотеки). Я протестировал разные макеты внутри DrawerLayout и пришел к выводу, что проблема была в файле «content_layout» — том, который отображается под ящиком.

Работало только использование чистого простого FrameLayout. Никакого CoordinatorLayout, никаких фрагментов, никаких пользовательских макетов или сторонних макетов, только старый добрый FrameLayout с шириной и высотой "match_parent".

person milosmns    schedule 12.12.2015

  1. Внутри drawerlayout у вас должен быть FrameLayout, который содержит основной контент для вашего экрана, и в большинстве случаев у вас также должен быть 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">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
  1. Теперь поместите LinearLayout в FrameLayout. Думайте о FrameLayout как о «контейнере», который содержит ваш главный экран.

Обратите внимание, что в официальной документации Android указано, что

Основное представление содержимого (см. выше FrameLayout) должно быть первым дочерним элементом в DrawerLayout, поскольку порядок XML подразумевает z-упорядочение, а рисовальщик должен располагаться поверх содержимого.

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

Пожалуйста, отметьте это как ответ, если это решило вашу проблему. Спасибо.

ОБНОВЛЕНИЕ:

Хорошо, сначала удалите "xmlns:android="http://schemas.android.com/apk/res/android"" из вашего linearlayout. Это должно появиться только один раз и в основном корневом xml, в этом случае DrawerLayout.

Затем исправьте, как вы используете свои веса. Объявите атрибут android:weightSum. Думайте о weightSum как о пироге. В данном случае мы установили его тоже 5, так что у нас есть 5 кусков пирога. Все внутри этого макета с использованием атрибута android:layout_weight. Этот первый установлен на 4, что займет 4/5 экрана. Последний занимает 1/5 экрана внизу.

Убедитесь, что этот LinearLayout все еще заключен в FrameLayout. Ваш LinearLayout должен выглядеть так:

<LinearLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="5">
    <LinearLayout
        android:background="#00f"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="4"/>
    <LinearLayout
        android:background="#f00"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0" />
    </LinearLayout>
</LinearLayout>
person ChallengeAccepted    schedule 27.07.2014
comment
К сожалению, использование FrameLayout с моим LinearLayout внутри не сработало. То же самое произошло на моем Nexus 5. - person Farplaner; 27.07.2014
comment
@Farplaner Смотрите мой обновленный ответ, я думаю, что решил вашу проблему. Вы неправильно использовали атрибуты веса. Вы должны были использовать android:weightSum в родительском и android:layout_weight для вложенных дочерних макетов. Пожалуйста, отметьте это как этот ответ, если это сработало :) - person ChallengeAccepted; 27.07.2014
comment
Спасибо за обновленный ответ. Тем не менее, это все еще не сработало для меня. Что-то еще должно быть причиной моей проблемы, хотя. У меня это работает только сейчас с новым проектом, с новым API. Я не могу перейти к существующему проекту и изменить градацию API/синхронизации. - person Farplaner; 28.07.2014
comment
Обертывание всего в FrameLayout не решает эту проблему для меня. Использование weightSum тоже не исправляет. - person Richard Le Mesurier; 17.02.2016