Использование layout_gravity = "bottom" для размещения в нижней части LinearLayout - PullRequest
10 голосов
/ 29 июля 2011

Я хотел бы разместить макет в нижней части LinearLayout, но я не могу заставить его работать. Я знаю, что могу использовать RelativeLayout для этого, но я должен быть в состоянии использовать LinearLayout, не так ли?

РЕДАКТИРОВАТЬ: На самом деле это более запутанно, чем я думал. Компоновка ниже упрощена. На самом деле я использую фрагменты на устройствах до версии 3.0 со слоем совместимости.

Я использовал Hierarchy Viewer для изучения происходящего и обнаружил, что в мой макет был добавлен android.support.v4.app.NoSaveStateFrameLayout, и для этого макета для layout_height установлено значение wrap_content. Похоже, это и является причиной моей проблемы, но я еще не выяснил, как ее исправить.

В частности, почему это не работает? Разве не будет layout_gravity поместить его внизу?

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

        ... stuff here ...

        <LinearLayout 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:orientation="horizontal">

            ... more stuff here ...

     </LinearLayout>
</LinearLayout>

Кстати, изменение layout_height на fill_parent или установка layout_weight тоже, похоже, не работает. Я просто хочу лучше понять, что происходит, потому что явно упускаю что-то важное. Спасибо.

Ответы [ 5 ]

17 голосов
/ 29 июля 2011

Прежде всего, хороший вопрос.

Android ведет себя странно, что можно сказать странно в такой ситуации.

если вы выбрали горизонтальную ориентацию родительского линейного макета, вы можете установить его дочерний компонент снизу, установив его layoug_gravity = bottom. Предположим, что вы добавили 2 текстовых представления в этом горизонтальном линейном макете, а layout_gravity второго текстового представления имеет значение bottom, тогда он будет установлен снизу, но он будет работать так, как если бы он был установлен снизу в другом столбце, чем в первом текстовом представлении. ПРИМЕЧАНИЕ : вы можете установить layout_gravity = "left" или "right", если его родительское линейное расположение расположено горизонтально, но вы не можете увидеть его результат.

И наоборот, если вы выбрали вертикальную ориентацию родительского линейного слоя, вы можете установить его дочерний компонент слева или справа с помощью layout_gravity. но второе текстовое представление будет показано, вы можете сказать следующую строку с левой или правой гравитации, как вы установили. ПРИМЕЧАНИЕ вы можете установить layout_gravity = "top" или "bottom", если его линейный макет вертикальный, но вы не можете видеть его результат.

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

Странно, но верно !!! Постарайтесь понять это поведение. :)

10 голосов
/ 29 июля 2011

Итак, я решил проблему. Это решение из двух частей:

Во-первых, способ сделать это без использования LinearLayout состоит в том, чтобы придать вес элементу выше, чтобы он занимал все пустое пространство. Кстати, вы можете увидеть этот пример в демоверсиях API: http://developer.android.com/resources/samples/ApiDemos/res/layout/linear_layout_3.html

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

        ... stuff here ...
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:weight="1"/>
        <LinearLayout 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            ... more stuff here ...

     </LinearLayout>
</LinearLayout>

Это само по себе не решило мою проблему, так как у меня был NoSaveStateFrameLayout с layout_width = "wrap_content" в качестве родительского представления, и поэтому мне нужно было сначала исправить это. Я использую код, основанный на замечательном Google I / O App , и когда я искал код для NoSaveStateFrameLayout, я нашел это:

// For some reason, if we omit this, NoSaveStateFrameLayout thinks we are
// FILL_PARENT / WRAP_CONTENT, making the progress bar stick to the top of the activity.
mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
        ViewGroup.LayoutParams.FILL_PARENT));

Спасибо за потрясающий комментарий Google !!! Я добавил это в свой источник, и все отлично заработало!

Мораль истории: Просмотр иерархии и комментарии ваших друзей.

7 голосов
/ 04 ноября 2016

Просто добавьте пробел между тем, что вы хотите внизу, и всем остальным:

        <Space
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
0 голосов
/ 27 июня 2014

Может быть так, что согласно https://stackoverflow.com/a/13366783/513038, вам нужно установить родительский LinearLayout на android:baselineAligned="false".Работал в моем случае.

0 голосов
/ 29 июля 2011

LinearLayout будет просто складывать вещи по мере их размещения. Так как он вертикальный, он будет размещать элементы один за другим по вертикали. Можете ли вы изменить андроид: гравитацию linearLayout, а не layout_gravity вложенного и посмотреть, работает ли это.

Конечно, RelativeLayout должен быть первым, но вы заявили, что не хотите этого делать. Есть ли причина для этого?

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