Я работаю над макетом формы для Login Activity
в моем приложении Android. На рисунке ниже показано, как я хочу, чтобы это выглядело:
Я смог достичь этого макета с помощью следующего XML. Проблема в том, что он немного хакерский. Мне пришлось жестко закодировать ширину для главного EditText. В частности, я должен был указать:
android:layout_width="172dp"
Мне бы очень хотелось задать процентную ширину для хостового и портового EditText'ов. (Что-то вроде 80% для хоста, 20% для порта.) Возможно ли это? Следующий XML работает на моем Droid, но, похоже, не для всех экранов. Мне бы очень хотелось получить более надежное решение.
<!-- begin snippet: js hide: false -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/host_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/home"
android:paddingLeft="15dp"
android:paddingTop="0dp"
android:text="host"
android:textColor="#a5d4e2"
android:textSize="25sp"
android:textStyle="normal" />
<TextView
android:id="@+id/port_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/home"
android:layout_toRightOf="@+id/host_input"
android:paddingTop="0dp"
android:text="port"
android:textColor="#a5d4e2"
android:textSize="25sp"
android:textStyle="normal" />
<EditText
android:id="@+id/host_input"
android:layout_width="172dp"
android:layout_height="wrap_content"
android:layout_below="@id/host_label"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="4dp"
android:background="@android:drawable/editbox_background"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/port_input"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_below="@id/host_label"
android:layout_marginTop="4dp"
android:layout_toRightOf="@id/host_input"
android:background="@android:drawable/editbox_background"
android:inputType="number" />
<TextView
android:id="@+id/username_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/host_input"
android:paddingLeft="15dp"
android:paddingTop="15dp"
android:text="username"
android:textColor="#a5d4e2"
android:textSize="25sp"
android:textStyle="normal" />
<EditText
android:id="@+id/username_input"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/username_label"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="4dp"
android:background="@android:drawable/editbox_background"
android:inputType="textEmailAddress" />
<TextView
android:id="@+id/password_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/username_input"
android:paddingLeft="15dp"
android:paddingTop="15dp"
android:text="password"
android:textColor="#a5d4e2"
android:textSize="25sp"
android:textStyle="normal" />
<EditText
android:id="@+id/password_input"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/password_label"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="4dp"
android:background="@android:drawable/editbox_background"
android:inputType="textPassword" />
<ImageView
android:id="@+id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_centerVertical="false"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="15dp"
android:scaleType="fitStart"
android:src="@drawable/home" />
<Button
android:id="@+id/login_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/password_input"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:text=" login "
android:textSize="18sp" >
</Button>
</RelativeLayout>
<!-- end snippet -->
Вы ищете атрибут android:layout_weight
. Он позволит вам использовать проценты для определения макета.
В следующем примере левая кнопка занимает 70% пространства, а правая - 30%.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:text="left"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".70" />
<Button
android:text="right"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".30" />
</LinearLayout>
Это работает одинаково с любым видом представления, вы можете заменить кнопки на какой-либо EditText, чтобы соответствовать вашим потребностям.
Обязательно установите layout_width
в 0dp
, иначе ваши представления не будут масштабироваться должным образом.
Обратите внимание, что сумма весов не обязательно должна быть равна 1, просто мне так удобнее читать. Вы можете установить первый вес равным 7, а второй - 3, и это даст тот же результат.
Это не дает ответа на исходный вопрос, который был для 70/30 раскол, но в особом случае 50/50 раскол между компонентами есть способ: месте невидимой распорки в центре и использовать его для установки двух компонентов, представляющих интерес.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View android:id="@+id/strut"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerHorizontal="true"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignRight="@id/strut"
android:layout_alignParentLeft="true"
android:text="Left"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/strut"
android:layout_alignParentRight="true"
android:text="Right"/>
</RelativeLayout>
Как это довольно распространенный случай, это решение более чем любопытство. Это немного рубить, но эффективный, потому что пустой, нулевой размер распорки должен стоить очень мало.
В целом, хотя, это'ы лучше не ожидать слишком много от стокового Android макеты...
Как указал @EmJiHash PercentRelativeLayout рекомендуется уровень API 26.0.0
Ниже цитирую Гугл комментарий:
этот класс был устаревшим в API уровня 26.0.0. рекомендуется использовать ConstraintLayout и связанные макеты. Ниже показано, как повторяют функциональность процент макеты с ConstraintLayout
Google представила новый API под названием для Андроид.поддержка.процентов
Затем вы можете просто указать процент, чтобы взять на вид
Добавить компиляции зависимостей, например
compile 'com.android.support:percent:22.2.0
в этом, PercentRelativeLayout является то, что мы можем сделать в процентном соотношении макет
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
app:layout_marginTopPercent="25%"
app:layout_marginLeftPercent="25%"/>
</android.support.percent.PercentRelativeLayout>
Вы не можете использовать проценты для определения размеров представления внутри RelativeLayout. Лучше всего для этого использовать LinearLayout и веса или пользовательский макет.
Вы можете взглянуть на новая библиотека поддерживает процентов.
compile 'com.android.support:percent:22.2.0'
Вы можете использовать PercentRelativeLayout, это последние недокументированные дополнение к дизайн-поддержка библиотеки, дает возможность указать не только элементов относительно друг друга, но и доля свободного пространства.
подкласс уровень мельче, что поддерживает процентном размеры > и полях. Вы можете указать размер или запас ребенка с помощью атрибуты с "процентов" и суффикс.
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
app:layout_marginTopPercent="25%"
app:layout_marginLeftPercent="25%"/>
</android.support.percent.PercentFrameLayout>
Процент пакет содержит API для добавления и управления процент размеры в вашем приложении.
Чтобы использовать, вы должны добавить этот библиотека для зависимостей Gradle в список:
dependencies {
compile 'com.android.support:percent:22.2.0'//23.1.1
}
Обновление
как указал @EmJiHash PercentRelativeLayout и PercentFrameLayout является устаревшим в API уровня 26.0.0
рассмотреть возможность использования ConstraintLayout
Google представил новый API под названием для Андроид.поддержка.процентов
1)PercentRelativeLayout
2)PercentFrameLayout
Добавить компиляции зависимостей, например
compile 'com.android.support:percent:23.1.1'
Вы можете указать размер в процентах, так что вам обоим выгодно уровень мельче и процент
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
app:layout_widthPercent="40%"
app:layout_heightPercent="40%"
app:layout_marginTopPercent="15%"
app:layout_marginLeftPercent="15%"/>
</android.support.percent.PercentRelativeLayout/>
Я решил создать пользовательский вид:
public class FractionalSizeView extends View {
public FractionalSizeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FractionalSizeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width * 70 / 100, 0);
}
}
Это невидимые распорки можно использовать для выравнивания других взглядов в уровень мельче.
Поскольку PercentRelativeLayout была отменена в 26.0.0 и вложенные макеты например LinearLayout внутри уровень мельче негативно сказаться на производительности (понимание преимущества ConstraintLayout) самый лучший вариант для вас, чтобы достичь процент ширины, это заменить ваш уровень мельче с ConstraintLayout.
Это может быть решена двумя способами.
Решение № 1, Используя руководящие принципы в процентах смещение
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/host_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Host"
android:layout_marginTop="16dp"
android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/host_input" />
<TextView
android:id="@+id/port_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Port"
android:layout_marginTop="16dp"
android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/port_input" />
<EditText
android:id="@+id/host_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:inputType="textEmailAddress"
app:layout_constraintTop_toBottomOf="@+id/host_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/guideline" />
<EditText
android:id="@+id/port_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:inputType="number"
app:layout_constraintTop_toBottomOf="@+id/port_label"
app:layout_constraintLeft_toLeftOf="@+id/guideline"
app:layout_constraintRight_toRightOf="parent" />
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8" />
</android.support.constraint.ConstraintLayout>
Решение #2 Использование цепи с весовыми ширина для EditText
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/host_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Host"
android:layout_marginTop="16dp"
android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/host_input" />
<TextView
android:id="@+id/port_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Port"
android:layout_marginTop="16dp"
android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/port_input" />
<EditText
android:id="@+id/host_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:inputType="textEmailAddress"
app:layout_constraintHorizontal_weight="0.8"
app:layout_constraintTop_toBottomOf="@+id/host_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/port_input" />
<EditText
android:id="@+id/port_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:inputType="number"
app:layout_constraintHorizontal_weight="0.2"
app:layout_constraintTop_toBottomOf="@+id/port_label"
app:layout_constraintLeft_toRightOf="@+id/host_input"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
В обоих случаях вы получите что-то вроде этого
PercentRelativeLayout является устаревшим с версии 26.0.0 библиотеки поддержки.
Google представил новый макет под названием ConstraintLayout.
Добавить библиотеку в качестве зависимости в модуле построения уровня.файл Gradle:
dependencies {
compile 'com.android.support.constraint:constraint-layout:1.0.1'
}
просто добавьте в файл макета:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.constraint.ConstraintLayout>
Ограничения
Ограничения помогут вам сохранить виджеты выровнены. Вы можете использовать якоря, как, например, ограничение ручек показано ниже, для определения правила соответствия между различными виджетами.
Обтекание контента
: взгляд расширяется по мере необходимости в соответствии с его содержанием.Ограничения спички
: взгляд расширяется по мере необходимости, чтобы удовлетворить определение ее трудности после учета маржи. Однако, если данный размер есть только одно ограничение, затем расширяется, чтобы вместить свое содержимое. Используя этот режим на высоту или ширину, также позволяет установить соотношение размеров.Исправлена
: указать конкретный размер в текстовом поле ниже или при изменении вида в окне редактора.Внутри
: первый и последний взгляд прикреплены к ограничениям на каждом конце цепи, а остальные равномерно распределены.Упакованные
: мнения упакованы вместе (после поля учитываются). Затем вы можете отрегулировать всю цепочку'с уклоном (влево/вправо или вверх/вниз), меняя цепь's голова, вид смещения.Базовая линия
: выравнивание базовой целью базовой линии текста в другой вид.Ограничить ориентир
: вы можете добавить вертикальную или горизонтальную направляющую, к которой можно ограничить видом, и инструкция будет невидимым для пользователей приложения. Вы можете расположить направляющую в макете на основе либо ДП единицах или в процентах относительно макета'с краю.Вы можете узнать больше на официальном док.
Просто соединить два элемента хост и порт в независимом краю горизонтальной и используйте Android:layout_weight, чтобы сделать процент
Этого можно добиться с помощью весов макета. Вес определяет, как будут разделены невостребованные части экрана. Задайте каждому EditText ширину layout_width, равную 0, и некоторый пропорциональный вес. То есть, задайте одному вес 2, а другому - 1, если хотите, чтобы первый занимал в два раза больше места.
Любопытно, что здание на ответ от @olefevre, можно не только сделать 50/50 макеты с "невидимые распорки", но всякие макеты с участием степени двойки.
Например, вот такой макет, который режет ширину на четыре равные части (на самом деле три, с весами 1, 1, 2):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<View
android:id="@+id/strut"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:background="#000000" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/strut" >
<View
android:id="@+id/left_strut"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/strut"
android:layout_centerHorizontal="true"
android:background="#000000" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignRight="@+id/left_strut"
android:text="Far Left" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="@+id/left_strut"
android:text="Near Left" />
</RelativeLayout>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/strut"
android:layout_alignParentRight="true"
android:text="Right" />
</RelativeLayout>
Проверить https://github.com/mmin18/FlexLayout которые вы можете использовать процентов или Java выражение непосредственно в XML-макете.
<EditText
app:layout_left="0%"
app:layout_right="60%"
app:layout_height="wrap_content"/>
<EditText
app:layout_left="prev.right+10dp"
app:layout_right="100%"
app:layout_height="wrap_content"/>