개발일지

Android in A..Z - TextInputLayout 본문

Android (안드로이드)

Android in A..Z - TextInputLayout

강태종 2021. 1. 20. 16:40

TextInputLayout

TextInputLayout은 EditText와 AutoCompleteTextView를 좀 더 유동적으로 반응하기 위해서 만든 레이아웃입니다. LinearLayout을 상속받았으며, TextInputLayout안에 TextInputEditText 또는 MaterialAutoCompleteTextView를 넣어서 사용합니다.

=> LinearLayout을 상속 받았지만 기본적으로 하나의 Child만 가질 수 있다.

JoinActivity

class JoinActivity : BaseActivity<ActivityJoinBinding>(R.layout.activity_join) {
    override fun init() {
        super.init()
        initIdTextInputLayout()
        initNameTextInputLayout()
        initPasswordTextInputLayout()
        initPasswordRepeatTextInputLayout()
        initOnJoinButton()
    }

    private fun initIdTextInputLayout() {
        with(binding.id) {
            editText?.addTextChangedListener {
                it?.let {
                    error = if(android.util.Patterns.EMAIL_ADDRESS.matcher(it).matches()) {
                        null
                    } else {
                        getString(R.string.write_your_email)
                    }
                }
            }
        }
    }

    private fun initNameTextInputLayout() {
        with(binding.name) {
            editText?.addTextChangedListener {
                it?.let {
                    error = if (Pattern.matches("[\\w]+", it)) {
                        null
                    } else {
                        getString(R.string.write_only_text)
                    }
                }
            }
        }
    }

    private fun initPasswordTextInputLayout() {
        with(binding.password) {
            editText?.addTextChangedListener {
                it?.let {
                    error = if(Pattern.matches("([\\w\\d]*[~!@#$%^&*()_+=:;,./<>?{}]+[\\w\\d]*)", it)) {
                        null
                    } else {
                        getString(R.string.include_one_or_more_special_characters)
                    }

                    if (binding.passwordRepeat.editText?.text?.trim()?.isNotEmpty() == true) {
                        binding.passwordRepeat.error = if (editText?.text?.toString() == binding.passwordRepeat.editText?.text?.toString()) {
                            null
                        } else {
                            getString(R.string.write_your_password)
                        }
                    }
                }
            }
        }
    }

    private fun initPasswordRepeatTextInputLayout() {
        with(binding.passwordRepeat) {
            editText?.addTextChangedListener {
                error = if (it?.toString() == binding.password.editText?.text?.toString()) {
                    null
                } else {
                    getString(R.string.write_your_password)
                }
            }
        }
    }

    private fun initOnJoinButton() {
        binding.setOnJoinButton {
            startActivity(Intent(this, MainActivity::class.java))
        }
    }
}
  • errorr : TextInputLayout에 Error효과를 준다. (counterMaxLength도 Error효과를 주지만 error은 null값이고 효과만 준다.)

XML

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="onJoinButton"
            type="android.view.View.OnClickListener" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/id"
            android:background="@color/white"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_margin="10dp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:hint="@string/id"
            app:endIconMode="clear_text"
            app:helperText="@string/write_your_email"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <com.google.android.material.textfield.TextInputEditText
                android:inputType="textEmailAddress"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/name"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_margin="10dp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:hint="@string/name"
            app:counterEnabled="true"
            app:counterMaxLength="10"
            app:endIconMode="clear_text"
            app:helperText="@string/write_only_text"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/id">

            <com.google.android.material.textfield.TextInputEditText
                android:inputType="textEmailAddress"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/password"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:hint="@string/password"
            app:helperText="@string/include_one_or_more_special_characters"
            app:endIconMode="password_toggle"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/name">

            <com.google.android.material.textfield.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textPassword" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/passwordRepeat"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:hint="@string/password_confirm"
            app:helperText="@string/write_your_password"
            app:endIconMode="password_toggle"
            app:layout_constraintTop_toBottomOf="@id/password"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

            <com.google.android.material.textfield.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textPassword" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.button.MaterialButton
            android:id="@+id/joinButton"
            android:text="@string/join"
            android:onClick="@{onJoinButton}"
            android:layout_margin="10dp"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            app:layout_constraintTop_toBottomOf="@id/passwordRepeat"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
  • hint : TextInputLayout에 추가하는게 권장사항이다. (EditText에 추가해도 정상적인 작동을 하지만 hint를 수정하는 작업을 수행하면 정상작동하지 않는다.
  • helperText : EditText아래에 설명하는 Text
  • counterMaxLength : 글자 입력수를 표시하는 기능 counterEnabled를 true로 설정해야한다.
  • endIconMode : 기본으로 제공하는 clear_text, password_toggle외에도 custom을 통해서 새로 만들 수 있다.
    • clear_text : 클릭시 Text 초기화
    • password_toggle : inputType이 password일 때만 정상작동 클릭시 password를 보이게 한다.

Standard vs Dense

Dense가 높이가 좀 더 낮다.

 

Standard vs ExposedDropdownMenu

Standard는 EditText이고, ExposedDropdownMenu는 Spinner와 비슷한 역할을 한다. Standrad는 TextInputEditText를 TextInputLayout에 넣고, ExposedDropdownMenu는 MaterialAutoCompleteTextView를 TextInputLayout에 넣어야한다.

=> ExposedDropdown을 사용할 때 MaterialAutoCompleteTextView의 android:editable="false"를 설정해야 수정을 막을 수 있다. (Android Developer에서 editable="false"를 적용하라 하지만 editable은 depedeprecated되어있다.)

 

OutlinedBox vs FilledBox

OutlinedBox는 Box에 hint가 표시되고 FilledBox는 박스안에 hint가 표시된다.

 

Kotlin

        val array = arrayOf("Apple", "Banana", "Watermelon")
        (binding.autoComplete.editText as? AutoCompleteTextView)?.apply {
            setAdapter(ArrayAdapter(this@MainActivity, android.R.layout.simple_spinner_dropdown_item, array))
        }

XML

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

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

        <TextView
            android:textSize="18sp"
            android:textStyle="bold"
            android:textColor="@color/black"
            android:layout_marginTop="20dp"
            android:layout_marginStart="10dp"
            android:text="Standard vs Dense"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.google.android.material.textfield.TextInputLayout
            android:hint="Standard"
            android:layout_margin="5dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.textfield.TextInputEditText
                android:inputType="text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:hint="Dense"
            android:layout_margin="5dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.textfield.TextInputEditText
                android:inputType="text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

        <TextView
            android:textSize="18sp"
            android:textStyle="bold"
            android:textColor="@color/black"
            android:layout_marginTop="20dp"
            android:layout_marginStart="10dp"
            android:text="Standard vs ExposedDropdown"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.google.android.material.textfield.TextInputLayout
            android:hint="Standard"
            android:layout_margin="5dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.textfield.TextInputEditText
                android:inputType="text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/autoComplete"
            android:hint="ExposedDropdownMenu"
            app:boxBackgroundColor="@color/white"
            android:layout_margin="5dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.textfield.MaterialAutoCompleteTextView
                android:editable="false"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

        <TextView
            android:textSize="18sp"
            android:textStyle="bold"
            android:textColor="@color/black"
            android:layout_marginTop="20dp"
            android:layout_marginStart="10dp"
            android:text="OutlinedBox vs FilledBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.google.android.material.textfield.TextInputLayout
            android:hint="OutlinedBox"
            android:layout_margin="5dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.textfield.TextInputEditText
                android:inputType="text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:hint="FilledBox"
            app:boxBackgroundColor="@color/white"
            android:layout_margin="5dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.textfield.TextInputEditText
                android:inputType="text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

        <TextView
            android:textSize="18sp"
            android:textStyle="bold"
            android:textColor="@color/black"
            android:layout_marginTop="20dp"
            android:layout_marginStart="10dp"
            android:text="Other"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.google.android.material.textfield.TextInputLayout
            app:helperTextEnabled="true"
            app:helperText="HelperText"
            app:placeholderText="PlaceHolder"
            app:prefixText="Prefix"
            app:suffixText="Suffix"

            android:hint="Other"
            android:layout_margin="5dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.textfield.TextInputEditText
                android:inputType="text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>
    </LinearLayout>
</layout>

Prefix, Suffix, Placeholder

  • Prefix : 접두사
  • Suffix : 접미사
  • Placeholder : 자리 표시자

XML

<com.google.android.material.textfield.TextInputLayout
            app:helperTextEnabled="true"
            app:helperText="HelperText"
            app:placeholderText="PlaceHolder"
            app:prefixText="Prefix"
            app:suffixText="Suffix"
            
            android:hint="Other"
            android:layout_margin="5dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <com.google.android.material.textfield.TextInputEditText
                android:inputType="text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.google.android.material.textfield.TextInputLayout>

Git (예제코드)

github.com/KangTaeJong98/Example/tree/main/Android/TextInputLayout

 

KangTaeJong98/Example

My Example Code. Contribute to KangTaeJong98/Example development by creating an account on GitHub.

github.com

 

'Android (안드로이드)' 카테고리의 다른 글

Android in A..Z - Location  (0) 2021.02.06
Android in A..Z - Fragment.setRetainInstance  (0) 2021.02.01
Android in A..Z - Glide  (0) 2020.11.07
Android in A..Z - Widget  (0) 2020.08.09
Android in A..Z - Handler  (0) 2020.07.28
Comments