Android 개발 중 소프트 키보드 의 디 스 플레이 와 숨 기기

이 내용 은 소프트 키 보드 를 조작 하 는 함 수 를 통 해 소프트 키 보드 를 숨 기거 나 표시 하 는 실현 방법 을 상세 하 게 분석 하고 그 중에서 중요 한 코드 에 대해 상세 하 게 분석 했다.
첫머리
입력 이 필요 한 곳 이 있 으 면 자동 으로 꺼 내 거나 소프트 키 보드 를 꺼 야 하 는 수요 가 있다.처음에 명 의 를 밝 히 면 본 고 는 소프트 키보드 의 일부 세부 사항 을 팝 업 하고 접 으 며 최종 적 으로 소스 코드 에서 분석 할 것 이다.
소프트 키 보드 를 조작 하려 면 InputMethodManager 를 사용 해 야 합 니 다.시스템 서비스 입 니 다.Context.getSystemService()를 사용 하여 얻 을 수 있 습 니 다.그리고 많은 관건 적 인 논리 코드 는 모두 InputMethodManager Service 에서 이 루어 진 것 이다.
특히 본 논문 의 모든 분석의 소스 코드 는 안 드 로 이 드 26 의 소스 코드 를 바탕 으로 한다.
2.소프트 키보드 조작
2.1 InputMethodManager
앞에서 언급 한 바 와 같이 소프트 키 보드 를 조작 하려 면 InputMethodManager 를 사용 해 야 합 니 다.시스템 서비스 입 니 다.이 키 보드 를 얻 으 려 면getSystemService()를 사용 하여 얻 을 수 있 습 니 다.

시스템 서비스 이기 때문에 사용 할 때 안전 을 위해 서 는 빈 지침 을 피해 야 합 니 다.
2.2 소프트 키보드 표시
InputMethodManager 에는 두 가지 방법showSoftInput()showSoftInputFromInputMethod()이 있 는데 실제로showSoftInput()만 유효 하 다.
그것 은 두 개의 과부하 방법 이 있 는데,일반적으로 우 리 는 그것 의 두 개의 매개 변 수 를 사용 하 는 방법 을 사용한다.

여기 서 우 리 는 단지 두 개의 매개 변 수 를 전달 해 야 한다.먼저 View 가 필요 합 니 다.소프트 키 보드 를 사용 하 는 것 은 입력 을 위해 서 입 니 다.입력 내용 을 받 는 View 가 필요 합 니 다.여기 서 입력 한 View 를 받 으 려 면 EditText(그러나 이것 은 필요 한 것 이 아 닙 니 다)가 좋 습 니 다.
두 번 째 매개 변수 flags 는 표지 위치 입 니 다.위 에서 캡 처 하 는 방법 으로 서명 한 문서 에서 볼 수 있 습 니 다.0 또는 SHOW 를 받 습 니 다.INPYT_IMPLICIT 두 개의 매개 변수 가 있 지만 실제로 세 번 째 매개 변수 가 있 고 다른 하 나 는 SHOW 입 니 다.FORCED。

1,2 는 모두 특별한 의 미 를 가 진 것 을 볼 수 있 습 니 다.실제로 그들 은 표시 에 영향 을 주지 않 습 니 다.다만 숨 길 때 제한 이 있 습 니 다.이런 것들 은 뒤에서 소스 코드 를 볼 때 다시 이야기 합 니 다.보통 특별히 필요 하지 않 으 면 0 을 직접 전달 하면 됩 니 다.
이제 호출showSoftInput()이 효력 을 발생 하 는 관건 을 간단하게 정리 합 니 다.
1.첫 번 째 매개 변 수 는 EditText 또는 하위 클래스 가 좋 습 니 다.
소프트 키 보드 는 입력 을 위 한 것 임 을 감안 하면 EditText 는 입력 을 받 는 컨트롤 입 니 다.이것 은 절대적 인 것 이 아니 라 하나의 EditText 가 아니라면 이 View 에 두 가지 속성 이 있어 야 합 니 다.각각android:focusable="true"android:focusableInTouchMode="true"입 니 다.
2.첫 번 째 매개 변 수 는 초점 을 얻 을 수 있 고 현재 초점 을 얻 었 습 니 다.
EditText 는 기본적으로 초점 을 가 져 올 수 있 습 니 다.그러나 레이아웃 에 초점 을 가 져 올 수 있 는 여러 개의 컨트롤 이 존재 한다 면 우리 가 전달 할 View 에 초점 을 맞 춰 야 합 니 다.초점 획득 하기requestFocus()방법 을 사용 할 수 있 습 니 다.
3.레이아웃 을 불 러 와 야 합 니 다.onCreate()에서 즉시 호출showSoftInput()하면 효력 이 발생 하지 않 는 다.페이지 가 시작 되 자마자 키 보드 를 꺼 내 려 면 Activity 에android:windowSoftInputMode속성 을 설정 하여 완성 하거나 로드 지연View.postDelayed()을 하 는 것 도 해결 방안 이다.
그래서 결국 소프트 키 보드 를 완전히 표시 하 는 코드 는 다음 과 같다.

2.3 소프트 키보드 숨 기기showSoftInput()방법 은 효과 적 이지 만 소프트 키 보드 를 숨 기 려 면 해당 하 는hideSoftInput()방법 을 제공 하지 않 았 지만 소프트 키 보드 를 숨 길 수 있 는hideSoftInputFromWindow()방법 이 있 었 다.
먼저 이 방법의 서명 을 살 펴 보 자.그것 역시 두 가지 방법 으로 호출 할 수 있다.

두 개의 인 자 를 받 습 니 다.첫 번 째 인 자 는 IBinder 입 니 다.하나의View.getWindowToken()windowToken 대상 을 직접 전달 하면 됩 니 다.두 번 째 매개 변 수 는 소프트 키보드 의 표지 위 치 를 숨 기 는 것 입 니 다.특별한 요구 가 없 으 면 0 을 직접 전달 하면 됩 니 다.
이 곳 은 원칙적으로 이전에 키보드 가 전 달 될 때 전 달 된 View 의 windowToken 을 전달 해 야 하지만 실제 상황 은 현재 레이아웃 ViewTree 에 존재 하 는 View 의 windowToken 을 전달 하면 됩 니 다.
결국 숨겨 진 소프트웨어 의 코드 는 이렇다.

2.4 키보드 의 팝 업 과 숨 기기 전환
InputMethodManager 에 서 는 이름 처럼 소프트 키 보드 를 표시 와 숨 김 사이 에서 전환 시 킬 수 있 는toggleSoftInput()방법 도 제공 합 니 다.

이 방법 은 두 개의 flags 를 수신 하 는데 각각 show 와 hide 를 제어 할 때의 표지 이다.그들의 의 미 는 앞에서 소개 한showSoftInput()hideSoftInputFromWindow()가 일치 하기 때문에 특별한 요구 없 이 0 을 직접 전달 하면 된다.toggleSoftInput()방법 은 View 나 windowToken 을 전달 하 라 고 요구 하지 않 기 때문에showSoftInput()중의 일부 제한 이 없 지만 레이아웃 이 완 료 된 후에 호출 해 야 효과 가 있 습 니 다.

비록 이 방법 은 제한 이 매우 적 지만,우 리 는 기본적으로 그것 을 사용 하지 않 을 것 이다.주요 원인 은 스위치 를 끄 는 방법 으로 현재 상태 에 따라 상 반 된 조작 을 하기 때문이다.이 로 인해 우 리 는 코드 에서 InputMethodManager 가 제공 하 는 방법 에 따라 현재 소프트 키보드 의 디 스 플레이 상 태 를 직접 판단 할 수 없 을 때 가 많 습 니 다.그러면 호출 시의 효 과 를 확정 할 수 없습니다.
3.소스 코드 분석
3.1 flag 의 디 테 일
앞의 몇 가지 방법 은 모두 flag 값 을 전달 해 야 합 니 다.문서 에서 설명 한 것 이 상세 하지 않 습 니 다.우 리 는 소스 코드 의 측면 에서 이러한 flag 의 의 미 를 분석 해 보 겠 습 니 다.
먼저 방법 을 살 펴 보 자.

최종 적 으로showSoftInput()방법 을 호출 합 니 다.최종 소스 코드 는 InputMethodManager Service 의 코드 를 확인 해 야 합 니 다.그리고mService.showSoftInput()방법 은 최종 적 으로 호출 된다showSoftInput().
flag 는 두 필드 에 영향 을 미 칠 수 있 습 니 다.mShowExplicitly Required 와 mShowForced,그리고 SHOWFORCED 가 더 강해 질 거 예요.showCurrentInputLocked()방법 은 최종 적 으로 InputMethodManager Service 중의hideSoftInputFromWindow()방법 도 호출 된다.
hideCurrentInputLocked()출력 되 는 로그 에서 의 미 를 볼 수 있 습 니 다.이 곳 은 전 달 된 두 개의 flag 를 표시 하고 숨 기 는 것 에 따라 비교 합 니 다.즉,flag 의 사용 이 정확 하지 않 으 면 여기 서 false 로 바로 돌아 가 소프트 키 보드 를 숨 길 수 없습니다.이런 디 테 일 한 대조 코드 는 뚜렷 하고 글 에서 이런 디 테 일 을 자주 하지 않 습 니 다.
그래서 앞에서 언급 한 것 처럼 특별한 요구 가 없 으 면 0 을 직접 전달 하면 되 고 이 제한 을 피 할 수 있 는 이유 다.
3.2 소프트 키보드 의 팝 업 여 부 를 어떻게 판단 합 니까?DEBUG == true현재 소프트 키보드 의 상태 에 따라 서로 다른 조작 을 할 수 있 는 이상 현재 소프트 키보드 의 상 태 를 확정 하 는 방법 이 있 을 것 이다.
그럼 계속 추적 하 겠 습 니 다.
이 방법 은 최종 적 으로 InputMethodServicetoggleSoftInput()방법 으로 호출 된다.

이 방법 에 서 는toggleSoftInput()방법 에 따라 현재 소프트 키보드 가 팝 업 상태 에 있 는 지 여 부 를 판단 합 니 다.그러나 우 리 는 InputMethodService 와 직접 상호작용 을 할 방법 이 없고 현재 키보드 가 표시 되 는 지 여 부 를 직접 얻 을 수 없습니다.
키보드 의 팝 업 과 접 기 를 감청 하려 면 ViewTreeObserver.OnGlobalLayoutListener 라 는 감청 을 사용 하여 레이아웃 조정 을 감청 하여 키보드 의 팝 업 과 숨 김 을 판단 할 수 있 습 니 다.이 세부 사항 들 은 시간 이 있 으 면 다시 이야기 하 자.
4.KeyboardUtils
소프트 키보드 의 걷 기와 팝 업 방법 에 대한 세부 사항 을 알 았 으 니 도움 류 를 써 서 이 문 제 를 해결 합 시다.받 으 라 고 하면 돼.
자바 버 전과 Kotlin 버 전 을 제공 합 니 다.
4.1 Java 버 전

public class KeyboardUtils {

 public static void showKeyboard(View view) {
  InputMethodManager imm = (InputMethodManager) view.getContext()
    .getSystemService(Context.INPUT_METHOD_SERVICE);
  if (imm != null) {
   view.requestFocus();
   imm.showSoftInput(view, 0);
  }
 }

 public static void hideKeyboard(View view){
  InputMethodManager imm = (InputMethodManager) view.getContext()
    .getSystemService(Context.INPUT_METHOD_SERVICE);
  if (imm != null) {
   imm.hideSoftInputFromWindow(view.getWindowToken(),0);
  }
 }
 public static void toggleSoftInput(View view){
  InputMethodManager imm = (InputMethodManager) view.getContext()
    .getSystemService(Context.INPUT_METHOD_SERVICE);
  if (imm != null) {
   imm.toggleSoftInput(0,0);
  }
 }
}
 
4.2 Kotlin 버 전

object KeyboardktUtils{
 fun showKeyboard(view: View) {
  val imm = view.context
    .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  if (imm != null) {
   view.requestFocus()
   imm.showSoftInput(view, 0)
  }
 }

 fun hideKeyboard(view: View) {
  val imm = view.context
    .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  imm?.hideSoftInputFromWindow(view.windowToken, 0)
 }

 fun toggleSoftInput(view: View) {
  val imm = view.context
    .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  imm?.toggleSoftInput(0, 0)
 }
}
이상 이 바로 본 고의 전체 내용 입 니 다.만약 에 여러분 이 공부 한 후에 모 르 는 부분 이 있 으 면 아래 의 댓 글 구역 에서 토론 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기