TextInputLayout: как дать отступ или отступ для подсказки?
Я должен использовать TextInputLayout
библиотеки поддержки дизайна в моем проекте. Я хочу дать пространство между hint
а также EditText
в TextInputLayout
, Я устанавливаю поля и отступы в TextInputLayout
и даже внутри EditText
но оба не работают. Так как решить эту проблему. Здесь я прилагаю снимок экрана и мое кодирование.
==============================Style=================================
<style name="TextHint" parent="Base.TextAppearance.AppCompat">
<item name="android:textSize">18sp</item>
<item name="android:textColor">@color/green</item>
</style>
=============================XML===================================
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
app:hintTextAppearance="@style/TextHint"
android:layout_marginTop="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/edttxtEmailAddress"
android:singleLine="true"
android:hint="@string/enter_valid_email"
android:paddingLeft="20dp"
android:textSize="20sp"
android:background="@drawable/rounded_common"/>
</android.support.design.widget.TextInputLayout>
22 ответа
Решение, предложенное ganesh2shiv, работает по большей части, хотя я обнаружил, что оно также децентрирует текст подсказки, отображаемый внутри EditText, когда он не сфокусирован.
Лучший трюк - установить желаемое paddingTop
к EditText, но также вставьте дополнительный отступ в фоновом режиме EditText. Довольно разумный способ сделать это, чтобы обернуть ваш оригинальный фон в <layer-list>
и установить <item android:top="...">
атрибут, чтобы соответствовать paddingTop
вашего EditText.
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/floating_hint_margin"
android:background="@drawable/bg_edit_text" />
</android.support.design.widget.TextInputLayout>
И bg_edit_text.xml
файл для рисования:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="@dimen/floating_hint_margin">
<your original background; can be <bitmap> or <shape> or whatever./>
</item>
</layer-list>
Я сам искал решение этого вопроса в последние пару дней. После того, как я несколько часов рвал на себе волосы, я наконец нашел простой обходной путь. Что я заметил, так это то, что если у вас установлен пользовательский фон в EditText, то атрибут android: paddingTop simple не работает, чтобы изменить интервал между текстами подсказок и редактировать текст (я действительно не знаю, почему). Поэтому, если вы установили пользовательский фон для вашего EditText, вы можете использовать атрибут android: translationY в EditText.
Итак, вот ваше решение:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="10dp"
app:hintTextAppearance="@style/TextHint">
<EditText
android:id="@+id/edttxtEmailAddress"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/rounded_common"
android:hint="@string/enter_valid_email"
android:paddingLeft="20dp"
android:translationY="10dp"
android:singleLine="true"
android:textSize="20sp" />
</android.support.design.widget.TextInputLayout>
Надеюсь, поможет.:)
Обновление: мои искренние извинения за позднее обновление. Я был очень занят в последнее время. Если вы еще не поняли, позвольте мне сказать вам, что этот ответ прямо уродлив и неправильн. Оглядываясь назад, я думаю, что, вероятно, был пьян, когда писал это. Как уже упоминалось другими, это может обрезать нижнюю область фона editText, но есть и уродливое решение для этой проблемы - вы можете установить высоту (родительского) textInputLayout заметно больше (насколько большой? Вы должны найти ее пробным путем и ошибка, чёрт!) чем (дочерний) editText. Я надеюсь, вы все понимаете, что это было бы сумасшествием, поэтому, пожалуйста, не делайте этого. Проверьте ответ, написанный @Radu Topor, это, безусловно, лучшее и чистое решение этого вопроса. Благодарю.
Я попробовал изменения заполнения, но это не работает хорошо.
Простой обходной путь - изменить высоту TIL:
android:layout_height="wrap_content"
(например)
android:layout_height="50dp"
это может не дать тот же результат на всех размерах экрана.
И добавить
android:gravity="bottom"
нажать свой текст вниз.
Ответ @RaduTopor хорош, но я думаю, что нам также нужно добавить android:bottom, иначе он также децентрирует текст подсказки, отображаемый внутри EditText, когда он не сфокусирован.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="@dimen/floating_hint_margin" android:bottom="@dimen/floating_hint_margin">
<your original background; can be <bitmap> or <shape> or whatever./>
</item>
</layer-list>
До (ответ RaduTopor):
После:
После многих попыток я нашел еще одно решение (версия материала 1.2.1):
это образец макета:
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textInputLayout"
style="@style/CustomTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/textInputEditText"
style="@style/CustomTextInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint" />
</com.google.android.material.textfield.TextInputLayout>
это образец стилей:
<style name="CustomTextInputLayout">
<item name="boxCollapsedPaddingTop">-16dp</item>
<item name="android:paddingTop">16dp</item>
<item name="boxBackgroundColor">@color/backgroundColorWhite</item>
<item name="android:textColorHint">...</item>
<item name="android:textAppearance">...</item>
<item name="hintTextAppearance">...</item>
<item name="hintTextColor">...</item>
<item name="boxStrokeColor">...</item>
</style>
<style name="CustomTextInputEditText">
<item name="android:textAppearance">...</item>
<item name="android:paddingTop">@dimen/margin_12</item>
<item name="android:paddingBottom">@dimen/margin_12</item>
<item name="android:paddingStart">0dp</item>
<item name="android:paddingEnd">0dp</item>
</style>
эти 2 строки устанавливают вертикальное смещение для просмотра заголовка / подсказки в развернутом состоянии над свернутым состоянием:
<item name="boxCollapsedPaddingTop">-16dp</item>
<item name="android:paddingTop">16dp</item>
эти 2 строки - для поля между текстом и подчеркиванием:
<item name="android:paddingTop">@dimen/margin_12</item>
<item name="android:paddingBottom">@dimen/margin_12</item>
эта строка - для устранения ошибки тонирования фона:
<item name="boxBackgroundColor">@color/backgroundColorWhite</item>
эти 2 строки - для удаления стандартных горизонтальных отступов
<item name="android:paddingStart">0dp</item>
<item name="android:paddingEnd">0dp</item>
Я создал специальный класс с целью добавления пустого представления над EditText, таким образом добавив отступ к подсказке. Вы можете использовать его как простой TextInputLayout.
public class PaddingTextInputLayout extends TextInputLayout {
public View paddingView;
public PaddingTextInputLayout(Context context) {
super(context);
}
public PaddingTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PaddingTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
super.addView(child, index, params);
refreshPaddingView();
}
public void addPaddingView(){
paddingView = new View(getContext());
int height = (int) getContext().getResources()
.getDimension(R.dimen.edittext_text_input_layout_padding);
ViewGroup.LayoutParams paddingParams = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height);
super.addView(paddingView, 0, paddingParams);
}
public void refreshPaddingView(){
if (paddingView != null) {
removeView(paddingView);
paddingView = null;
}
addPaddingView();
}
}
Эта реализация очень проста и глупа, вы можете ее значительно улучшить.
Чтобы отключить эффект сокращения нижней строки, я использовал поля, translationY и clipChildren="false"
<android.support.design.widget.TextInputLayout
android:id="@+id/textinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:clipChildren="false">
<android.support.design.widget.TextInputEditText
android:id="@+id/et_profile_contact_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="3dp"
android:background="@drawable/image_back"
android:hint="Contact name"
android:padding="5dp"
android:translationY="3dp" />
</android.support.design.widget.TextInputLayout>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="10dp"
android:bottom="5dp">
<shape>
<!-- Background Color -->
<solid android:color="#f1f1f1"/>
<!-- Round Corners -->
<corners android:radius="5dp"/>
</shape>
</item>
</layer-list>
<style name="text_input_edit_text_without_border_style">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">55dp</item>
<item name="android:paddingTop">10dp</item>
<item name="android:paddingBottom">5dp</item>
<item name="android:gravity">left|center_vertical</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:maxLines">1</item>
<item name="android:singleLine">true</item>
<item name="android:imeOptions">actionNext</item>
<item name="android:textSize">@dimen/text_size_large</item>
<item name="android:background">@drawable/bg_without_border_with_padding_top</item>
</style>
<style name="text_input_layout_style">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginBottom">@dimen/margin_medium</item>
</style>
Это то, что я сделал в своем проекте, чтобы получить достаточно места между edittext и hint
<android.support.design.widget.TextInputLayout
android:id="@+id/til_full_name"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"
android:layout_marginTop="30dp"
android:gravity="bottom"
android:textColorHint="#fff"
app:layout_constraintTop_toBottomOf="@+id/welcome_til_email">
<android.support.v7.widget.AppCompatEditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#9a050505"
android:hint="You email"
android:inputType="textCapWords"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="#fff"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.design.widget.TextInputLayout>
Если вы хотите установитьandroid:hint
дополнение до 0 в фокусе, добавитьapp:boxCollapsedPaddingTop="0dp"
на вашTextInputLayout
.
Спасибо @Erkan заapp:boxCollapsedPaddingTop
(если установлено вTextInputLayout
).
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
android:background="@drawable/rounded_corners"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp"
app:boxCollapsedPaddingTop="8dp">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="0dp"
android:paddingVertical="8dp"
android:hint="Hint" />
</com.google.android.material.textfield.TextInputLayout>
Но если вы установитеbackground
вTextInputEditText
, больше ничего не требуется. Это даже хорошо работает для состояния ошибки.
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rounded_corners"
android:hint="Hint" />
</com.google.android.material.textfield.TextInputLayout>
Просто добавьте в свой EditText пользовательский фон
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<padding
android:top="4dp"/> // your padding value
</shape>
</item>
// customize your background items if you need
</layer-list>
<android.support.design.widget.TextInputLayout
...>
<android.support.design.widget.TextInputEditText
...
android:background="@style/your_custom_background"/>
затем примените его к вашему EditText и увеличьте высоту вашего EditText со значением отступа, если вы используете фиксированную высоту
Попробуйте использовать paddingStart вместо заполнения влево или вправо. Это сработало для меня.
android:paddingStart="8dp"
Просто используйте padding-bottom
<com.google.android.material.textfield.TextInputLayout
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
>
<com.google.android.material.textfield.TextInputEditText
....
android:paddingBottom="@dimen/dp_25"
...
/>
</com.google.android.material.textfield.TextInputLayout>
Это поздний ответ, но надеюсь, что это поможет, и я думаю, что это немного лучшее решение. Вместо того, чтобы дать фон вашей editText
Дайте этот фон вашему TextInputLayout
, И установить edittext
макет прозрачный.
<android.support.design.widget.TextInputLayout
android:id="@+id/tinput_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="05dp"
android:background="@drawable/send_email_screen_element_bg"
android:padding="05dp"
android:theme="@style/grey_control_style">
<android.support.v7.widget.AppCompatEditText
android:id="@+id/edt_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:ems="10"
android:hint="@string/phone_hint_str"
android:inputType="text"
android:paddingStart="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:singleLine="true"
android:textColor="@color/black"
android:textSize="14sp" />
</android.support.design.widget.TextInputLayout>
Рабочее решение:
Вы должны указать нестандартную высоту для TextInputEditText и сделать собственный рисунок, после чего вы получите свое решение, НАДЕЮСЬ, ОНО БУДЕТ РАБОТАЕТ 100%
1-й шаг:
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilStart"
android:layout_width="match_parent"
android:textColorHint="@color/darkgreen"
android:layout_marginTop="@dimen/_20sdp"
android:layout_height="wrap_content"
app:errorEnabled="true"
android:layout_below="@+id/labelDescription">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/tietStart"
android:layout_width="match_parent"
android:layout_height="@dimen/_30sdp"
android:hint="@string/start_offset"
android:fontFamily="@font/gilroysemibold"
android:background="@drawable/customedittext"
android:text="@string/zero"
android:gravity="bottom"
android:paddingLeft="@dimen/_10sdp"
android:textColor="@color/darkgreen"
android:inputType="number"
android:typeface="monospace"
android:digits="0123456789."
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
2-й шаг:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="@dimen/_10sdp">
<shape >
<solid android:color="@color/activitycolor"/>
<corners android:radius="@dimen/_10sdp"/>
</shape>
</item>
</layer-list>
макет xml
<com.google.android.material.textfield.TextInputLayout
style="@style/TextInputLayout"
android:layout_marginTop="10dp"
android:gravity="center"
android:theme="@style/TextInputLayoutHint">
<androidx.appcompat.widget.AppCompatEditText
style="@style/TextInputEditText"
android:hint="Email ID"
android:inputType="textEmailAddress"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
styles.xml
<style name="TextInputLayout">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginStart">15dp</item>
<item name="android:layout_marginLeft">15dp</item>
<item name="android:layout_marginTop">10dp</item>
<item name="android:layout_marginEnd">15dp</item>
<item name="android:layout_marginRight">15dp</item>
</style>
<style name="TextInputLayoutHint" parent="">
<item name="android:textColorHint">@color/colorHintNormal</item>
<item name="colorControlActivated">@color/colorOrange</item>
<item name="android:textSize">11dp</item>
</style>
<style name="TextInputEditText" parent="">
<item name="android:translationY">10dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">@null</item>
<item name="android:paddingBottom">15dp</item>
<item name="android:textColor">@color/colorBlack</item>
<item name="android:textColorHint">@color/colorHintActive</item>
<item name="android:textSize">13sp</item>
</style>
Вы можете попробовать это решение и редактировать TextStyle только в стиле TextInputLayout. Например:
<com.google.android.material.textfield.TextInputLayout
...
android:layout_width="@dimen/element_width"
android:layout_height="@dimen/element_height"
...
style="@style/EditTextField.Container"
...
android:hint="@string/you_hint_resource">
<com.google.android.material.textfield.TextInputEditText
...
android:layout_width="match_parent"
android:layout_height="wrap_content"
... />
</com.google.android.material.textfield.TextInputLayout>
В разделе вашего стиля
<style name="EditTextField"/>
<style name="EditTextField.Container" parent="Widget.MaterialComponents.TextInputLayout.FilledBox.Dense">
<item name="android:textColorHint">@color/edit_text_hint_color</item>
<item name="hintTextColor">@color/edit_text_hint_color</item>
<item name="hintTextAppearance">@style/PasswordInput.HintTextAppearance</item>
<item name="materialThemeOverlay">@style/PasswordInput.MaterialThemeOverlayStyle</item>
</style>
<style name="EditTextField.HintTextAppearance">
<item name="android:paddingBottom">20dp</item>
<item name="android:paddingTop">10dp</item>
<item name="android:textSize">12sp</item>
</style>
<style name="EditTextField.MaterialThemeOverlayStyle">
<item name="editTextStyle">@style/EditTextStyle</item>
</style>
<style name="EditTextStyle" parent="@style/Widget.MaterialComponents.TextInputEditText.FilledBox.Dense">
<item name="android:background">@drawable/edittext_body_container</item>
<item name="android:paddingBottom">@dimen/input_text_bottom_padding</item>
<item name="android:paddingStart">@dimen/input_text_padding_start</item>
<item name="android:paddingTop">@dimen/input_text_top_padding</item>
<item name="android:textCursorDrawable">@drawable/cursor_white_drawable</item>
<item name="android:textSize">16sp</item>
<item name="lineHeight">20sp</item>
</style>
Вы можете использовать
startIconDrawable
к
TextInputLayout
и убедитесь, что вы установили какой-то фиктивный прозрачный значок (ширина значка будет начальным значением заполнения). так что вы получите заполнение с самого начала. Примечание: это взлом, а не прямое решение
Если требуется добавить пробел между курсором и подсказкой, вы можете попробовать
editTextComment.setHint(" "+getString(R.string.add_a_comment));
Я думаю, вы должны рассмотреть это:
Библиотека дизайна использует интересный подход к настройке EditText
: это не меняет это напрямую. Вместо этого TextInputLayout
используется, чтобы обернуть EditText
и предоставить улучшения.
Первый, отображающий плавающую метку, когда пользователь вводит что-то в поле, выполняется автоматически. TextInputLayout
находит EditText
среди своих детей и присоединяется как TextWatcher
Таким образом, он может определить, когда поле было изменено, и анимирует движение подсказки от его обычного места в EditText
в плавающей позиции над ним.
Второе улучшение, отображающее сообщение об ошибке, требует небольшого изменения кода. Вместо установки ошибки на EditText, ошибка должна быть установлена на TextInputLayout
, Это потому, что не существует автоматического способа TextInputLayout
получать уведомление, когда ошибка установлена на EditText
, Вот как может выглядеть макет:
<android.support.design.widget.TextInputLayout
android:id="@+id/username_text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/username_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/username_hint"/>
</android.support.design.widget.TextInputLayout>
Обратите внимание, что оба EditText
а также TextInputLayout
нужны идентификаторы макета. Во фрагменте нам нужно настроить TextInputLayout
чтобы включить отображение ошибок:
TextInputLayout usernameTextInputLayout = (TextInputLayout) view.findViewById(R.id.username_text_input_layout);
usernameTextInputLayout.setErrorEnabled(true);
...
usernameTextInputLayout.setError(R.string.username_required);
Я думаю, проще, чем вы думаете, работать с размерами исправлений, если вам не нужно использовать wrap_content
по какой-то причине, в противном случае принятый подход работает должным образом.
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="bottom">
<EditText
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="10dp"/>
</com.google.android.material.textfield.TextInputLayout>
Следуя этому примеру, у вас есть пространство 20dp для размещения метки подсказки, как вы хотите, играя с layout_marginTop
свойство.