본문 바로가기
깡샘 코틀린

13-3 액티비티 제어

by 농농씨 2023. 7. 1.

소프트 키보드 제어하기

시스템에서 제공하는 키보드(소프트 키보드)는 액티비티 화면에서 사용자가 글을 입력할 수 있는 뷰가 포커스를 가지는 순간 자동으로 올라온다. 그리고 사용자가 뒤로가기 버튼을 누르면 뷰가 자동으로 사라진다.

 

입력 매니저

그런데 때로는 코드에서 특정한 순간에 키보드를 올리거나 내려야 할 수도 있다. 이를 InputMethodManager 클래스가 지원한다.

  • public boolean hideSoftInputFromWindow(IBinder windowToken, int flags)
  • public boolean showSoftInput(View view, int flags)
  • public void toggleSoftInput(int showFlags, int hideFlags)

InputMethodManager의 showSoftInput() 함수를 이용하면 소프트 키보드를 화면에 나타나게 할 수 있으며, hideSoftInputFromWindow() 함수를 이용하면 사라지게 할 수 있다.

그리고 toggleSoftInput() 함수를 이용하면 키보드를 토글 방식(한가지 기능 on/off만 있는거)으로 제어한다. 즉, 소프트 키보드가 안 보이면 나타나고 보이면 사라진다.

// 키보드 올리고 내리기
val manager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
binding.showInputButton.setOnClickListener {
	binding.editView.requestFocus() // 뷰에 포커스 강제
    manager.shoSoftInput(binding.editView, InputmethodManager.SHOW_IMPLICIT)
}
binding.hideInputButton.setOnclickListener {
	manager.hideSofrInputFromWindow(currentFocus?.windowToken,
    	InputMethodManager.HIDE_NOT_ALWAYS)
}

showSoftInput() 함수 이용할 때 주의할 점. 첫번째 매개변수는 글이 입력될 뷰. 이 뷰가 포커스를 가지지 않은 상태라면 키보드가 나타나지 않음. 그래서 에디트 텍스트 같은 뷰에 포커스가 없는 상태에서 키보드가 나타나게 하려면 포커스를 강제로 지정한 다음 showsoftInput() 함수를 호출해야 한다. 이때 뷰에 포커스를 (강제로) 지정하려면 requestFocus() 함수를 이용한다.

 

다음은 toggleSoftInput() 함수를 이용하는 코드이다.

// 키보드 반대로 제어
manager.toggleSoftInput(InputmethodManager.SHOW_FORCED, 0)

 

입력 모드 설정

액티비티 화면에 소프트 키보드가 올라오면 키보드가 세로로 일정한 크기를 확보한다. 이렇게 키보드가 올라올 때 액티비티가 함께 올라오게 할 수도 있고 액티비티의 크기를 조정하게 하는 등 설정할 수 있다.

이런 설정은 필수는 아니며 일반적으로 시스템에서 알아서 액티비티의 상태를 보고 조정해준다. 개발자가 직접 조정하고 싶으면 매니페스트 파일에서 <activity> 태그의 windowSoftInputMode 속성을 이용하면 된다.

// 키보드 올라올 때 설정
<activity android:name="""."SettingActivity" android:windowSoftInputMode="adjustpan">

windowSoftInputMode 속성에는 다음과 같은 값을 설정할 수 있다.

  • adjustPan: 키보드가 올라올 때 입력 에디트 텍스트에 맞춰 화면을 위로 올린다.
  • adjustResize: 키보드가 올라올 대 액티비티의 크기를 조정한다.
  • adjustUnspecified: 상황에 맞는 옵션을 시스템이 알아서 설정한다. ← 기본값
  • stateHidden: 액티비티 실행 시 키보드가 자동으로 올라오는 것을 방지한다.
  • stateVisible: 액티비티 실행 시 키보드가 자동으로 올라온다.
  • stateUnspecified: 시스템이 적절한 키보드 상태를 설정하거나 테마에 따른다. ← 기본값

 

만약 한 액티비티에 색깔다른 뷰 세개 있고 에디트 텍스트가 화면에 있다고 하자.

여기서 에디트 텍스트 터치하면 윈도우 영역 전체가 올라간다.

그런데 만약 사용자가 에디트 텍스트 입력하면서 액티비티의 맨 위의 뷰를 참조해야 한다면? windowSoftInputMode 속성으로 입력 모드를 설정해 주면 된다.

입력 모드를 adjustResize로 설정하면 키보드가 올라올 때 액티비티의 세로 크기를 알맞게 다시 조정한다.

그리고 입력 모드를 stateVisible이나 stateHidden으로 설정하면 액티비티가 실행될 때 키보드가 자동으로 올라오거나 올라오지 않게 설정할 수 있다. 물론 이때에는 화면에 에디트 텍스트가 있고 액티비티가 실행되면서 에디트 텍스트가 포커스를 가진 상태여야 한다. 앞에서 살펴본 것처럼 뷰에 포커스를 (강제로) 지정하려면 requestFocus() 함수를 이용한다. 

 

 

방향과 전체 화면 설정하기

액티비티의 방향을 고정하고 싶다면 매니페스트 파일의 <activity> 태그의 screenOrientation 속성을 이용한다. 값은 landscape는 가로로 지정하고 portrait는 세로로 고정한다.

// 화면 방향 고정하기
<activity android:name=".SettingActivity" android:screenOrientation="landscape">

액티비티를 전체 화면으로 표시한다는 것은 액티비티의 콘텐츠 영역을 화면 전체에 나오게 한다는 의미이다. (상단의 상태바와 하단의 내비게이션 바도 안나오게)

액티비티를 전체 화면으로 출력하고 싶으면 우선 액티비티 창의 액션바가 출력되지 않게 설정해야 한다. 액티비티에 적용되는 테마를 NoActionBar 테마 등으로 지정하여 액션바가 나오지 않게 하면 된다.

// 액션바 출력하지 않기
<style name="Theme.AndroidLab" parent="ThemeMaterialComponents.DayNight.NoActionBar">

그다음 액티비티 코드에서 전체 화면으로 출력되게 설정한다. 그런데 이 부분은 API 레벨 30에서 변경되었다. 즉, API 레벨 29까지는 window.setFlags() 함수를 이용해 전체 화면을 지정했는데 이때 값으로 이용되는 FLAG_FULLSCREEN 등의 상수가 모두 deprecated 되었다.

// 전체 화면 출력 코드(API 레벨 30 이후)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // SDK 최소 버전 선언
    window.setDecorFitsSystemWindows(false)
    val controller = window.insetsController
    if (ocntroller != null) {
    	controller.hide(WindowInsets.Type.statusBars() or
        WindowInsets.Type.navigationBars())
        controller.systemBarsBehavior =
        	WindowInsetsController.BEHAVIOR_SHOW_TRANSIENS_BARS_BY_SWIPE
    }
} else {
    window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN)
}

API 레벨 30부터는. WindowInsetsController라는 클래스의 함수를 이용해 액티비티 창을 설정한다. 물론 WindowInsetsController를 사용할 때는 위 코드처럼 호환성을 고려해서 작성해야 한다. 

'깡샘 코틀린' 카테고리의 다른 글

13-5 액티비티 ANR 문제와 코루틴  (0) 2023.07.01
13-4 태스크 관리  (0) 2023.07.01
13-2 액티비티 생명주기  (0) 2023.07.01
13-1 인텐트 이해하기  (0) 2023.06.30
12-4 확장된 플로팅 액션 버튼  (0) 2023.06.30