AndroidJavaでキーボードの表示/非表示を取得する
取得するAPIは用意されてないので自前で実装せざるを得ないが、そんな面倒でもない。
もくじ
- LinearLayoutを拡張させてキーボードのListenerを実装する
- キーボードの表示/非表示判定について
- Activityで通知を受け取る
※適度に省略する。
LinearLayoutを拡張させてキーボードのListenerを実装する
LinearLayoutWithSoftwareKayboardListener
クラスとしたがここはテキトーに。
LinearLayoutWithSoftwareKeyboardListener.java
/**
* ここらへんの pckage とか import とかはテキトーに。
*/
public class LinearLayoutWithSoftwareKayboardListener extends LinearLayout
{
// Context 持ちのコンストラクタしか書かないがここはテキトーに
public LinearLayoutWithSoftwareKayboardListener(Context context)
{
super(context);
}
public interface SoftwareKeyboardListener
{
/**
* キーボードが表示されたときに呼ばれる。
* @param height キーボードの高さ[px]
*/
public void onShow(int height);
/**
* キーボードが表示になったときに呼ばれる。
*/
public void onHide();
}
private SoftwareKeyboardListener _listener;
private boolean _preStatus = false;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (this._listener == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
Activity activity = (Activity)this.getContext();
Rect rect = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
/**
* rectのメンバはそれぞれ次を表す。
* - rect.top ステータスバーの高さ[px]
* - rect.bottom 画面の高さから、ステータスバーとキーボード分を引いた残り[px]
*/
int keyboardHeight = MeasureSpec.getSize(heightMeasureSpec) - (rect.top + rect.bottom);
// 若干の誤差があるっぽい。この時点で`keyboardHeight > 10`であればキーボード表示と見なす。
if (keyboardHeight > 10 && !this._preStatus)
this._listener.onShow(keyboardHeight);
else if (keyboardHeight <= 10 && this._preStatus)
this._listener.onHide();
this.preStatus = (keyboardHeight > 10);
}
}
キーボードの表示/非表示判定について
コメントでだいたい説明したので、ざっくり。
画面サイズの縦幅と実際にコンテンツが描画されている縦幅とを比較して判定している。
画面縦幅 - (スタータスバー縦幅 + 描画縦幅) = 「何か」が表示されている縦幅
となり、これが10[px]
より大きければその「何か」はキーボードだという判定である。
さらに、手前の状態(_preStatus
)を持っておき、表示状態→表示状態、非表示状態→非表示状態をはじくようにしている。
Activityで通知を受け取る
キーボードのイベントを受け取りたいアクティビティで
FooActivity.java
public class FooActivity {
// :
/* private */ LinearLayoutWithSoftwareKeyboardListener. SoftwareKeyboardListener _listener = new LinearLayoutWithSoftwareKeyboardListener. SoftwareKeyboardListener()
{
@Override
public void onShow(int height)
{
/**
* キーボードが表示されたらここが実行される。
* `height`はキーボードの高さ[px]
*/
}
@Override
public voif onHide()
{
/**
* キーボードが非表示になったらここが実行される。
*/
}
};
// :
/**
* 普段LinearLayoutを使うところをLinearLayoutWithSoftwareKeyboardListenerを使って、
* `layout.setListener(this._listener);`でセットしておく。
*/
}
こんな感じ。