EditText에 실시간으로 입력된 값에따라 특정 이벤트를 발생시키거나 뷰를 보이게해야 할 때가 있다. 그런경우 TextWatcher라는 Interface를 사용하여 EditText에 실시간으로 입력된 값을 받아 올 수 있다.

 

editText.addTextChangedListener(object : TextWatcher {
            override fun **afterTextChanged**(s: Editable?) {
                // text가 변경된 후 호출
                // s에는 변경 후의 문자열이 담겨 있다.
            }

            override fun **beforeTextChanged**(s: CharSequence?, start: Int, count: Int, after: Int) {
                // text가 변경되기 전 호출
                // s에는 변경 전 문자열이 담겨 있다.
            }

            override fun **onTextChanged**(s: CharSequence?, start: Int, before: Int, count: Int) {
                // text가 바뀔 때마다 호출된다. 
                checkEmail()
            }
        })

 

afterTextChanged(s : Editable?) {}

  • Text가 변경된 후 호출, s→ 변경후의 문자열

beforeTextChanged(s : CharSequence?, start: Int, count: Int, after: Int )

  • Text변경 전 호출 s → 변경전의 문자열
  • start : s에 저장된 문자열에서 새로 추가될 문자열의 시작 위치값(인덱스)
  • count : s에 새로운 문자열이 추가된 후 문자열의 길이
  • after: 새로 추가될 문자열의 길이

onTextChanged(s : CharSequence?, start: Int, before: Int, count: Int)

  • Text실시간 호출 s → 실시간으로 변경되는 문자열
  • start : 새로 추가된 문자열의 시작 위치 값
  • befoer : 삭제된 기존 문자열의 개수
  • count : 새로 추가된 문자열의 개수

안드로이드의 xml에서는 ConstraintLayout이랑 RecyclerView, LinearLayout만 잘 다룰줄 알면 간단한 뷰는 거의다 구현 할 수 있다.

 

ConstraintLayout은 뷰들간의 제약을 걸어 체인 형태로 묶어주어 간단하게 뷰의 위치를 제어할 수 있는 장점을 갖고있다.

오늘은 그 중에서 ChainStyle에 대해 학습해 보도록 하자.

 

자식 뷰들의 체인스타일을 수직으로 할지 수평으로 할지 먼저 정한다.

layout_constraintHorizontal_chainStyle	//체인 스타일을 수평으로 설정
layout_constraintVertical_chainStyle	//체인 스타일을 수직으로 설정

 

수직으로할지 수평으로 할지 정했으면 ChainStyle을 설정해주면 되는데 

ChainStyle에는 3가지가 있다.

1. packed (가운데로 합쳐짐)

2. spread (균등하게 배분)

3. spread_inside (양 끝 고정 후 남은 공간에 대해 균등하게 배분)

 

우선 imageView3개를 박스 형태로 뷰들간에 연결을 해주고 chainStyle을 적용하지 않은 상태에서 보자.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/box1"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="@color/black"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/box2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

        <ImageView
            android:id="@+id/box2"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:background="#894753"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/box3"
            app:layout_constraintStart_toEndOf="@+id/box1"
            app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/box3"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="#385203"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/box2"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

ChainStyle이 적용 되지 않은 상태

chainStyle을 적용하지 않고 뷰들간에 동일한 체인을 걸어 화면의 정중앙에 동일한 간격을 갖고 배치된것을 볼 수 있다.


ChainStyle을 적용한 상태

왼쪽 순서대로 packed, spread, spread_inside로 설정을 했는데 chainStyle은 가장 왼쪽 뷰(Horizontal_chainStyle일 때) 또는 위쪽뷰(Vertical_chainStyle일 때)에 설정해주어야 지정된다.

 

packed (가운데로 합쳐짐)

체인이 연결된 가장 바깥쪽 끝 뷰를 기준으로 가운데로 뭉친 다음 뷰들 간의 간격을 지정해주는 방식이다. 

 

spread (균등하게 배분)

가장 바깥쪽 뷰를 기준으로 정렬한 후 뷰들 간의 사이가 동일하게 간격을 나누는 방식이다. 

 

spread_inside (양 끝 고정 후 남은 공간에 대해 균등하게 배분)

가장 바깥쪽 뷰를 부모뷰에 고정 시킨 다음 나머지 공간에 대해서 여백을 동일하게 나누는 방식이다.

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/box1"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="@color/black"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/box2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/box2"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="#894753"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/box3"
        app:layout_constraintStart_toEndOf="@+id/box1"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/box3"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="#385203"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/box2"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

EditText가 포함된 Activity에 진입 시 키보드가 자동으로 올라오는 문제가 발생하고 있다면 다음 속성값을 추가해주면 된다.

EditText에 focust가 있어서 키보드가 올라오기 때문에 포커스를 제거하던가 아래 속성값을 넣어주면 된다.

 

방법1

부모 뷰에 포커스를 주는 방식으로 xml에서 부모뷰에 다음 속성값을 추가한다.

android:focusable="true"
android:focusableInTouchMode="true"

 

방법2

manifest의 해당 activity에 windowSoftInputMode="stateAlwaysHidden"값을 추가한다

<activity
    android:name=".SampleActivity"
    android:exported="false"
    android:windowSoftInputMode="stateAlwaysHidden"
    android:screenOrientation="nosensor">
</activity>

stateAlwaysHidden -> 액티비티가 시작될 때 항상 키보드를 숨기게 하는 속성

EditText를 입력하고 키보드창을 닫은 후 다시 editText를 클릭하게 되면 커서가 맨 앞으로 이동하는 경우가 생기는데 

그런 경우에 사용자가 잘못 입력해서 텍스트를 지우려고 하면 커서를 움직여야 하는 불편함이 따른다.

이 때 EditText를 눌렀을 때 커서를 맨 끝으로 이동하려면 setSelection을 사용하면 된다. 

 

binding.editText.setSelection(binding.editText.text.length)

+ Recent posts