Как использовать центр представления как контрольную точку внутри RelativeLayout

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

Мое решение было простым, позиционировало что-то в этом центре и давало ему размеры 1px, поэтому его фактический центр родительского RelativeLayout . Не поймите меня неправильно, это работает, и у меня не было никаких проблем с ним, но если есть более эффективная практика, я бы хотел знать об этом.

Что касается графического представления того, что я говорю, позвольте мне добавить несколько иллюстраций.

Введите описание изображения здесь

Это первое изображение имеет текстовый TextView расположенный в центре RelativeLayout и я дал ему ширину 0dp. Это позволяет мне, как вы можете видеть на следующем изображении, разместить что-нибудь относительно этого центра. Моя точка зрения заключается в том, что мне кажется странным, что вы не можете этого сделать без необходимости добавления дополнительного представления в центр, поскольку я могу видеть такие свойства, как Layout to left of или Layout to right of но без Layout to center of ,

Введите описание изображения здесь

Таким образом, scennario может быть немного больше в строю, « это еще не сломано, но я боюсь, что он будет появляться в любую минуту ». Тогда, с другой стороны, если это правильный способ сделать это, и я помогаю кому-то, изучая новую вещь, это также работает для меня.

Почему я задаю вопросы, на которые не отвечают !? Я так устраиваю щедрость здесь.

Наиболее разумная вещь, которая пока еще (по моему мнению), заключается в том, что я заменяю свой LinearLayout на View которое, как я предполагаю, занимает немного меньше памяти, даже если оно незначительно меньше. Поэтому я благодарю @yorkw за это. Я удивлен, что никто этого не спрашивал раньше.

Просто уточнить, так как кажется, что есть недоразумение относительно того, что я на самом деле после. Я не хочу, чтобы что-то принимало половину родительской ширины / высоты. Я просил использовать его в качестве ориентира (это то, что я сказал в названии), поэтому я могу делать такие вещи, как позиционировать изображение слева от центра, не добавляя линейный макет, который занимает половину, а гравитация остается Или что-то еще.

Обновить

Поскольку API 14 имеет доступное Space которое представляет собой легкий подкласс View который может быть более подходящим для такого рода взлома.

Solutions Collecting From Web of "Как использовать центр представления как контрольную точку внутри RelativeLayout"

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

  • Рассчитайте ширину контейнера как ширину пикселя вашего, содержащего класс RelativeLayout (вызовите этот MyRelativeLayout)
  • Создайте экземпляр MyRelativeLayout.LayoutParams с именем leftHalfWidgetLayoutParams
  • Установите leftHalfWidgetLayoutParams.width = containerWidth / 2, либо используя аргумент конструктора, когда он создан выше, либо после факта. После того, как этот факт необходим, если вы хотите настроить его позже (например, в переопределении onSizeChanged () в MyRelativeLayout).
  • Каждый раз, когда вы устанавливаете или изменяете leftHalfWidgetLayoutParams.width, вызывайте leftHalfWidget.setLayoutParams (leftHalfWidgetLayoutParams).
  • Вызовите requestLayout (), если требуется перерисовать MyRelativeLayout каждый раз при изменении ширины

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

Теперь я понимаю, что это теряет часть «магии», когда RelativeLayout делает все автоматически, и именно там ваш подход действительно приятнее. Но RelativeLayout по-прежнему будет применять относительные позиции ваших виджетов, а также может, учитывая добавленное ограничение ширины, которое будет добавлено к параметрам макета вашего leftHalfWidget, поэтому вы не будете переопределять или отказываться от своей общей Вклад в этом отношении.

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

Я хотел бы указать, что если ваш левый виджет всегда будет занимать левую половину контейнера, то я не понимаю, почему горизонтальный LinearLayout (вместо RelativeLayout) на верхнем уровне (с весом 0,5 Для вашего левого виджета с одинаково взвешенной правой стороной RelativeLayout для оставшейся правой половины), не было бы хорошим решением. В этом случае «относительный» материал будет происходить только внутри этой правой половины, поэтому зачем использовать RelativeLayout на верхнем уровне, когда LinearLayout может выполнять работу более сжато? Но, возможно, вы хотите использовать RelativeLayout с левой стороны, чтобы иметь дело с вертикальными отношениями, и поэтому у вас может быть более одного элемента управления в этой левой части.

Для достижения того, что вы делаете, я использую LinearLayout, layout_width = 0dip и layout_weight = 50. Но он не является оптимальным, поскольку он гнездяет другой макет внутри линейного макета. Мне было бы интересно узнать, доступно ли еще лучшее решение.

Я думаю, что лучше использовать LinearLayout. С атрибутом «layout_weight», я думаю, LinearLayout может решить множество проблем. Использование LinearLayout также нуждается в еще одном пустом представлении внутри LinearLayout, но я думаю, что это лучше, я люблю LinearLayout 🙂 Вот мой код

 <LinearLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:background="@drawable/your_image"> <Button android:layout_height="fill_parent" android:layout_width="0dip" android:layout_weight="1.0"/> <View android:layout_height="fill_parent" android:layout_width="0dip" android:layout_weight="1.0" android:visibility="invisible"/> </LinearLayout> 

Наконец, извините за моего бедного английского.

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

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ff0000" android:weightSum="2" > <Button android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="#00ff00" android:text="@string/hello" /> </LinearLayout> 

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

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

Приятная картина

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

Вы можете использовать PercentRelativeLayout библиотеки поддержки .

  1. Включите его в свой проект: compile 'com.android.support:percent:23.4.0'

  2. Используйте PercentRelativeLayout вместо вашего RelativeLayout

  3. Сделайте свою ширину кнопки 50% от ее родителя: app:layout_widthPercent="50%"

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