본문 바로가기

IT/Android

[Android] Soft Key 기종의 소프트 키보드 관련 문제 해결 방법


현상

키보드값을 제대로 가져오지 못하여, 이모티콘 레이아웃이 화면은 덮는 현상이 벌어지거나, 너무 아래에 치우쳐져서 나오는 현상이 발생합니다.
최하단 이미지 첨부


원인

Android SDK 21 이후부터 Soft key를 사용하는 기종에서 화면을 가져올 때, 소프트키까지 포함한 화면을 가져오면서 화면의 높이까지 원하지 않는 크기로 가져오면 발생하게 되었습니다.


해결책

SDD 21 이후 버전에 대해서 windowManger를 통해서 DefaultDisplay르 가져오도록 요청하게 해야 합니다.

/**
 * SDK 21 이후 부터 소프트키 기종 화면 높이를 잘 못 가져오는 현상 있음
 */
if(Build.VERSION.SDK_INT >= 21) {
      Display display = getActivity().getWindowManager().getDefaultDisplay();
      Point size = new Point();
      display.getSize(size);
      screenHeight = size.y;
} else {
      screenHeight = paramParentLayout.getRootView().getHeight();
}


모듈 변경

SoftKeyboard의 크기를 알아내는 뷰를 새로 작성하여 사용함
View를 상속 받아 사용하며, View의 onSizeChanged 함수를 활용하여 뷰 변화를 통해 키보드의 높이를 알아낼 수 있다.
SoftKeyboardDectectorView.java

package com.wescan.alo.view;

/**
 * Created by hazuki21 on 16. 3. 10..
 */
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.View;

public class SoftKeyboardDectectorView extends View {

    private Context context;
    private boolean mShownKeyboard;
    private OnShownKeyboardListener mOnShownSoftKeyboard;
    private OnHiddenKeyboardListener onHiddenSoftKeyboard;
    private int diffHeight;

    public SoftKeyboardDectectorView(Context context) {
        this(context, null);
        this.context = context;
    }

    public SoftKeyboardDectectorView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SoftKeyboardDectectorView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        Activity activity = (Activity) context;
        Rect windowRect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(windowRect);
        Rect screenRect = new Rect();
        activity.getWindowManager().getDefaultDisplay().getRectSize(screenRect);
        diffHeight = screenRect.bottom - windowRect.bottom;

        Log.i("Main", "TestAPI diffHeight : " + diffHeight);
        if (diffHeight > 0 && !mShownKeyboard) { // 모든 키보드는 0px보다 크다고 가정
            mShownKeyboard = true;
            onShownSoftKeyboard();
        } else if (diffHeight <= 0 && mShownKeyboard) {
            mShownKeyboard = false;
            onHiddenSoftKeyboard();
        }
        super.onSizeChanged(w, h, oldw, oldh);
    }

    public boolean getKeyboardState() {
        return mShownKeyboard;
    }

    public int getKeyboardHeight() {
        return this.diffHeight;
    }

    public void onHiddenSoftKeyboard() {
        if (onHiddenSoftKeyboard != null)
            onHiddenSoftKeyboard.onHiddenSoftKeyboard();
    }

    public void onShownSoftKeyboard() {
        if (mOnShownSoftKeyboard != null)
            mOnShownSoftKeyboard.onShowSoftKeyboard();
    }

    public void setOnShownKeyboard(OnShownKeyboardListener listener) {
        mOnShownSoftKeyboard = listener;
    }

    public void setOnHiddenKeyboard(OnHiddenKeyboardListener listener) {
        onHiddenSoftKeyboard = listener;
    }

    public interface OnShownKeyboardListener {
        void onShowSoftKeyboard();
    }

    public interface OnHiddenKeyboardListener {
        void onHiddenSoftKeyboard();
    }
}


Activity의 onCreate 부분에서 사용하면 된다. 예시일 뿐이니 참고하여 사용해야 한다.

final SoftKeyboardDectectorView softKeyboardDecector = new SoftKeyboardDectectorView(this);
addContentView(softKeyboardDecector, new FrameLayout.LayoutParams(-1, -1));

softKeyboardDecector.setOnShownKeyboard(new OnShownKeyboardListener() {

    @Override
    public void onShowSoftKeyboard() {
        //키보드 등장할 때
    }
});

softKeyboardDecector.setOnHiddenKeyboard(new OnHiddenKeyboardListener() {

    @Override
    public void onHiddenSoftKeyboard() {
        // 키보드 사라질 때
    }
})