Help us understand the problem. What is going on with this article?

【Android】WebViewのinputなどからのキーボードの表示/非表示のイベントを取得する

More than 3 years have passed since last update.

AndroidJavaでキーボードの表示/非表示を取得する

取得するAPIは用意されてないので自前で実装せざるを得ないが、そんな面倒でもない。

もくじ

  1. LinearLayoutを拡張させてキーボードのListenerを実装する
  2. キーボードの表示/非表示判定について
  3. 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);`でセットしておく。
   */

}

こんな感じ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away