Friday, September 16, 2011

Android soft (virtual) keyboard listener

If you use Evernote android app you might have noticed, that when, on a login screen, soft keyboard gets shown (to type password or username) the layout doesn't just scale, or scrolls. It changes (for example Evernotes logo is hidden).

Unfortunately, android api doesn't provide you with the specific tools to listen for a moment, when soft keyboard gets shown, or hidden. But there is a way (dirty hack) to assume that the keyboards state was changed.
We can guess it by listening measure changes in layout.
To do it, first, we need to make our layout to resize and scale instaed of scroll.  Add android:windowSoftInputMode="adjustResize" parameter to your activity in manifest.xml. This way, when soft keyboard is called, content will be resized instead of scrolled.

Next step is to actually listen for this resizing. And again, there is a catch. There is no such thing as OnMeasureChangedListener, so the only way is to extend the container layout and do it inside. As an example I extended LinearLayout, and this is what I've got:

public class MyLayout extends LinearLayout {

  public MyLayout(final Context context, final AttributeSet attrs) {
    super(context, attrs);
  }

  public MyLayout(Context context) {
    super(context);
  }

  private OnSoftKeyboardListener onSoftKeyboardListener;

  @Override
  protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    if (onSoftKeyboardListener != null) {
      final int newSpec = MeasureSpec.getSize(heightMeasureSpec);
      final int oldSpec = getMeasuredHeight();
      // If layout became smaller, that means something forced it to resize. Probably soft keyboard :)
      if (oldSpec > newSpec){
        onSoftKeyboardListener.onShown();
      } else {
        onSoftKeyboardListener.onHidden();
      }
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  }

  public final void setOnSoftKeyboardListener(final OnSoftKeyboardListener listener) {
    this.onSoftKeyboardListener = listener;
  }

  // Simplest possible listener :)
  public interface OnSoftKeyboardListener {
    public void onShown();
    public void onHidden();
  }
}


That's about it. Of course you need to use your layout (MyLayout) in your code/xml for it to work. And example from activity:


((MyLayout)findViewById(R.id.layout)).setOnSoftKeyboardListener(new OnSoftKeyboardListener() {
  @Override
  public void onShown() {
    // Do something here
  }
  @Override
  public void onHidden() {
    // Do something here
  }
});

P.S. It works pretty well as it is. But you should check it for different situations. For example screen rotations, or other possible changes in the layout, that might trigger resize of any sort.  

2 comments:

  1. But whenever i enter a key in the edittext the showkeyboard method again called.

    ReplyDelete
  2. How to Make a Sledgehammer - Titanium Art - iTanium-ART
    The apple watch titanium vs aluminum basic idea behind the Sledgehammer is titanium watch band simple. titanium hoop earrings You'll titanium knee replacement get the most out winnerwell titanium stove of your hardware, without needing a replacement!

    ReplyDelete