본문 바로가기
공부기록/안드로이드

[안드로이드] 키보드 show&hide 이벤트 발생시키기

by 책읽는 개발자 ami 2021. 4. 12.
728x90
반응형

안드로이드 soft keyboard가 보이거나 숨겨졌을 때 이벤트를 발생시키고 싶을 경우

키보드 이벤트를 감지하면 되겠거니 싶었지만 아래 그림과 같이 키보드 아래 버튼이나 뒤로가기를 눌렀을 때 키보드 이벤트 발생 안 한다.

 

stackoverflow 에 나와 있는 그대로 사용했더니 해결!

stackoverflow.com/questions/4312319/how-to-capture-the-virtual-keyboard-show-hide-event-in-android

 

How to capture the "virtual keyboard show/hide" event in Android?

I would like to alter the layout based on whether the virtual keyboard is shown or not. I've searched the API and various blogs but can't seem to find anything useful. Is it possible? Thanks!

stackoverflow.com

OnKeyboardVisibilityListener 인터페이스와 구현부 그대로 가져다 썼습니다.

    public interface OnKeyboardVisibilityListener {
        void onVisibilityChanged(boolean visible);
    }

    private void setKeyboardVisibilityListener(final OnKeyboardVisibilityListener onKeyboardVisibilityListener) {
        final View parentView = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
        parentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            private boolean alreadyOpen;
            private final int defaultKeyboardHeightDP = 100;
            private final int EstimatedKeyboardDP = defaultKeyboardHeightDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);
            private final Rect rect = new Rect();

            @Override
            public void onGlobalLayout() {
                int estimatedKeyboardHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, parentView.getResources().getDisplayMetrics());

                parentView.getWindowVisibleDisplayFrame(rect);
                int heightDiff = parentView.getRootView().getHeight() - (rect.bottom - rect.top);

                boolean isShown = heightDiff >= estimatedKeyboardHeight;

                if (isShown == alreadyOpen) {
                    Log.i("Keyboard state", "Ignoring global layout change...");
                    return;
                }
                alreadyOpen = isShown;
                onKeyboardVisibilityListener.onVisibilityChanged(isShown);
            }
        });

100% 이해하진 못 했지만 대충 이해하고 썼다. 그냥 값을 다 찍어보고 아 그렇구나 정도로 이해한..

한 줄 씩 설명하자면 아래와 같다.

int estimatedKeyboardHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, parentView.getResources().getDisplayMetrics()); // 키보드 추정 높이값

private final Rect rect = new Rect();

parentView.getWindowVisibleDisplayFrame(rect); // rect에는 키보드를 제외한 화면의 크기 정보가 담긴다.

int heightDiff = parentView.getRootView().getHeight() - (rect.bottom - rect.top); // 키보드가 shown이면 heightDiff에는 (추정치보다 큰)키보드 높이가 저장되고, hidden일 경우엔 0에 가까운 값이 저장된다. (0보단 크고 estimatedKeyboardHeight보단 작은 값)

boolean isShown = heightDiff >= estimatedKeyboardHeight; // heightDiff가 키보드 추정치보다 크면 isShown = true가 저장된다. 

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        setKeyboardVisibilityListener(new OnKeyboardVisibilityListener() {
            @Override
            public void onVisibilityChanged(boolean visible) {
                if(visible){
                    //키보드 shown
                } else {
                    //키보드 hidden
                }
            }
        });
    }

위와 같이 keyboard 상태에 따라 원하는 코드를 작성할 수 있다.

728x90
반응형