Процентная ширина в RelativeLayout
Я работаю над макетом формы для входа Activity
в своем приложении для Android. Ниже показано, как я хочу выглядеть так:
Мне удалось достичь этого макета со следующим XML. Проблема в том, что она немного хакерская. Мне пришлось жестко закодировать ширину для хоста EditText. В частности, мне пришлось указать:
android:layout_width="172dp"
Мне бы очень хотелось дать процентную ширину хосту и порту EditText. (Что-то вроде 80% для хоста, 20% для порта.) Возможно ли это? Следующий XML работает на моем Droid, но, похоже, он не работает для всех экранов. Мне бы очень хотелось получить более надежное решение.
<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>
Ответы
Ответ 1
Вы ищете атрибут 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>
Он работает так же, как и любой вид View, вы можете заменить кнопки с помощью EditText в соответствии с вашими потребностями.
Обязательно установите layout_width
на 0dp
, или ваши представления могут не масштабироваться должным образом.
Обратите внимание, что весовая сумма не должна равняться 1, мне просто легче читать это. Вы можете установить первый вес на 7, а второй - на 3, и он даст тот же результат.
Ответ 2
Это не совсем ответит на исходный вопрос, который был для разделения 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 Android...
Ответ 3
Обновление 1
Как указано @EmJiHash PercentRelativeLayout устарел в уровне API 26.0.0
Ниже цитируется комментарий google:
Этот класс устарел на уровне API 26.0.0. вместо этого вместо этого используйте ConstraintLayout и связанные макеты. Ниже показано, как копировать функциональность процентных макетов с помощью параметра ConstraintLayout
Google представил новый API под названием android.support.percent
Затем вы можете просто указать процент, который нужно просмотреть по просмотру
Добавьте скомпилированную зависимость, например
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>
Ответ 4
Вы не можете использовать проценты для определения размеров View внутри RelativeLayout. Лучшие способы сделать это - использовать LinearLayout и весы или настраиваемый макет.
Ответ 5
Вы можете посмотреть новую библиотеку поддержки процентов.
compile 'com.android.support:percent:22.2.0'
docs
sample
Ответ 6
Вы можете использовать PercentRelativeLayout. Это недавнее недокументированное дополнение к Библиотеке поддержки дизайна. возможность указывать не только элементы по отношению друг к другу, но и общий процент доступного пространства.
Подкласс RelativeLayout, поддерживающий размеры, основанные на процентах и поля. Вы можете указать размер или размер дочернего элемента, используя атрибуты с суффиксом "Процент".
<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>
Пакет Percent предоставляет API для поддержки добавления и управления размерами в вашем приложении.
Для использования вам нужно добавить эту библиотеку в список Gradle зависимости:
dependencies {
compile 'com.android.support:percent:22.2.0'//23.1.1
}
Ответ 7
Я решил создать пользовательский вид:
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);
}
}
Это невидимая стойка, которую я могу использовать для выравнивания других представлений в RelativeLayout.
Ответ 8
Обновление
Как указано @EmJiHash PercentRelativeLayout и PercentFrameLayout устарел на уровне API 26.0.0
Рассмотрим использование ConstraintLayout
Google представил новый API под названием android.support.percent
1) PercentRelativeLayout
2) PercentFrameLayout
Добавьте скомпилированную зависимость, например
compile 'com.android.support:percent:23.1.1'
Вы можете указать размер в процентах, чтобы получить как преимущество RelativeLayout
, так и процент
<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/>
Ответ 9
PercentRelativeLayout устарел из Редакции 26.0.0 библиотеки поддержки.
Google представил новый макет под названием ConstraintLayout.
Добавьте библиотеку в качестве зависимости в файле build.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>
Ограничения
Ограничения помогают поддерживать соответствие виджетов. Для определения правил выравнивания между различными виджетами вы можете использовать якоря, такие как приведенные ниже инструкции ограничения.
-
Wrap Content
: представление расширяется по мере необходимости, чтобы соответствовать его содержимому.
-
Match Constraints
: представление расширяется по мере необходимости, чтобы соответствовать определению его ограничений после учета полей. Однако, если заданное измерение имеет только одно ограничение, то представление расширяется, чтобы соответствовать его содержимому. Используя этот режим на высоте или ширине, вы также можете установить соотношение размеров.
-
Fixed
: вы указываете конкретное измерение в текстовом поле ниже или изменяете размер представления в редакторе.
-
Spread
: Представления распределены равномерно (после учета полей). Это значение по умолчанию.
-
Spread inside
: первое и последнее представление прикреплены к ограничениям на каждом конце цепи, а остальные равномерно распределены.
-
Weighted
: Когда цепочка настроена на распространение или распространение внутри, вы можете заполнить оставшееся пространство, установив одно или несколько видов на "соответствия ограничениям" (0dp). По умолчанию пространство равномерно распределяется между каждым представлением, установленным на "ограничения соответствия", но вы можете назначить вес важности для каждого представления, используя атрибуты layout_constraintHorizontal_weight и layout_constraintVertical_weight. Если вы знакомы с layout_weight в линейном макете, это работает одинаково. Таким образом, представление с наивысшим значением веса получает наибольшее количество пространства; представления, имеющие одинаковый вес, получают одинаковое пространство.
-
Packed
: представления упакованы вместе (после учета полей). Затем вы можете отрегулировать смещение всей цепи (влево/вправо или вверх/вниз), изменив смещение вида цепи.
-
Center Horizontally or Center Vertically
. Чтобы быстро создать цепочку просмотров, выберите их все, щелкните правой кнопкой мыши одно из видов, а затем выберите "Центр по горизонтали" или "Вертикально по центру", чтобы создать горизонтальную или вертикальную цепочку.
-
Baseline alignment
: Выровняйте базовую линию текста в виде исходного текста в другом представлении.
-
Constrain to a guideline
: вы можете добавить вертикальную или горизонтальную директиву, с которой вы можете ограничить просмотры, а руководство будет невидимым для пользователей приложений. Вы можете позиционировать директиву в макете, основываясь либо на единицах измерения, либо на процентах относительно края макета.
-
Adjust the constraint bias
: когда вы добавляете ограничение на обе стороны представления (и размер представления для одного и того же измерения является либо "фиксированным", либо "завершающим контентом" ), представление становится центрированным между двумя ограничениями с уклоном по умолчанию 50%. Вы можете настроить смещение, перетащив ползунок смещения в окне "Свойства"
-
Set size as a ratio
: вы можете установить размер представления в таком соотношении, как 16: 9, если хотя бы одно из размеров представления установлено на "соответствия ограничениям" (0dp).
Вы можете узнать больше из официального doc.
Ответ 10
Вы можете выполнить это с помощью макетов компоновки. Вес определяет, как невостребованные части экрана разделяются. Дайте каждому EditText значение layout_width из 0 и некоторый пропорциональный вес. Ie, дайте один вес 2, а другой вес 1, если вы хотите, чтобы первое заняло в два раза больше места.
Ответ 11
Интересно, что, основываясь на ответе от @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>
Ответ 12
Просто поставьте два хоста и порт в текстовом режиме в независимую горизонтальную горизонтальную линию и используйте android: layout_weight, чтобы сделать процент
Ответ 13
Так как PercentRelativeLayout устарел в 26.0.0, а вложенные макеты, такие как LinearLayout внутри RelativeLayout, оказывают негативное влияние на производительность (Понимание преимуществ производительности ConstraintLayout) наилучшим вариантом для достижения процентной ширины является замена RelativeLayout на 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>
В обоих случаях вы получаете что-то вроде этого
Ответ 14
Отметьте 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"/>
Ответ 15
Использовать новую библиотеку поддержки процентов.
compile 'com.android.support:percent:24.0.0'
Пример:
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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"
app:layout_widthPercent="45%"
android:layout_height="wrap_content"
android:layout_below="@id/host_label"
app:layout_marginLeftPercent="4%"
app:layout_marginTopPercent="2.7%"
app:layout_marginRightPercent="4%"
android:background="@android:drawable/editbox_background"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/port_input"
android:layout_width="100dp"
app:layout_widthPercent="26.1%"
app:layout_marginTopPercent="2.7%"
android:layout_height="wrap_content"
android:layout_below="@id/host_label"
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"
app:layout_marginLeftPercent="4%"
app:layout_marginTopPercent="2.7%"
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"
app:layout_marginLeftPercent="4%"
app:layout_marginTopPercent="2.7%"
app:layout_marginRightPercent="4%"
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"
app:layout_marginLeftPercent="4%"
app:layout_marginTopPercent="2.7%"
app:layout_marginRightPercent="4%"
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"
app:layout_marginLeftPercent="4%"
app:layout_marginTopPercent="2.7%"
app:layout_marginRightPercent="4%"
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"
app:layout_marginLeftPercent="4%"
app:layout_marginTopPercent="2.7%"
app:layout_marginRightPercent="4%"
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"
app:layout_marginLeftPercent="4%"
app:layout_marginTopPercent="2.7%"
android:text=" login "
android:textSize="18sp" >
</Button>
</android.support.percent.PercentRelativeLayout>
* Для примера и учебника * Tutorial1 Tutorial2 Tutorial3