Android EditText, soft keyboard show/hide event?
Solution 1
Hi I'd used following workaround:
As far as my content view is a subclass of LinearLayout (could be any other view or view group), I'd overridden onMeasure method lilke following:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int proposedheight = MeasureSpec.getSize(heightMeasureSpec);
final int actualHeight = getHeight();
if (actualHeight > proposedheight){
// Keyboard is shown
} else {
// Keyboard is hidden
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
This workaround helped me to hide some controls when keyboard is showing and bring back otherwise.
Hope this would be useful.
Solution 2
There actually isn't such an event to catch. The IME is simply showing and hiding its window; the feedback you get from this is the window manager causing your own window's content to resize if you have put it in resize mode.
Solution 3
I solved this issue by using onGlobalLayoutListener :
final View activityRootView = findViewById(R.id.top_root);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
if (heightDiff > 100) {
// keyboard is up
} else {
// keyboard is down
}
}
});
Here activityRootView is your Activity's root view.
Solution 4
In my case I wanted to hide a bottom bar when softkeyboard was shown. I considered best to just hide the bar when layout had less than a percent size of normal layout size. So I used this solution that works fine considering that soft keyboard usually takes 20% or more screen height. Just change the percent constant by any value you may think is ok. It needs attribute android:windowSoftInputMode="adjustResize" in manifest and layout must be the root to work.
Extend from any layout you may want instead of RelativeLayout.
public class SoftKeyboardLsnedRelativeLayout extends RelativeLayout {
private boolean isKeyboardShown = false;
private List<SoftKeyboardLsner> lsners=new ArrayList<SoftKeyboardLsner>();
private float layoutMaxH = 0f; // max measured height is considered layout normal size
private static final float DETECT_ON_SIZE_PERCENT = 0.8f;
public SoftKeyboardLsnedRelativeLayout(Context context) {
super(context);
}
public SoftKeyboardLsnedRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@SuppressLint("NewApi")
public SoftKeyboardLsnedRelativeLayout(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int newH = MeasureSpec.getSize(heightMeasureSpec);
if (newH > layoutMaxH) {
layoutMaxH = newH;
}
if (layoutMaxH != 0f) {
final float sizePercent = newH / layoutMaxH;
if (!isKeyboardShown && sizePercent <= DETECT_ON_SIZE_PERCENT) {
isKeyboardShown = true;
for (final SoftKeyboardLsner lsner : lsners) {
lsner.onSoftKeyboardShow();
}
} else if (isKeyboardShown && sizePercent > DETECT_ON_SIZE_PERCENT) {
isKeyboardShown = false;
for (final SoftKeyboardLsner lsner : lsners) {
lsner.onSoftKeyboardHide();
}
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void addSoftKeyboardLsner(SoftKeyboardLsner lsner) {
lsners.add(lsner);
}
public void removeSoftKeyboardLsner(SoftKeyboardLsner lsner) {
lsners.remove(lsner);
}
// Callback
public interface SoftKeyboardLsner {
public void onSoftKeyboardShow();
public void onSoftKeyboardHide();
}
}
Example:
layout/my_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<yourclasspackage.SoftKeyboardLsnedRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
</yourclasspackage.SoftKeyboardLsnedRelativeLayout>
MyActivity.java
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout);
SoftKeyboardLsnedRelativeLayout layout = (SoftKeyboardLsnedRelativeLayout) findViewById(R.id.myLayout);
layout.addSoftKeyboardLsner(new SoftKeyboardLsner() {
@Override
public void onSoftKeyboardShow() {
Log.d("SoftKeyboard", "Soft keyboard shown");
}
@Override
public void onSoftKeyboardHide() {
Log.d("SoftKeyboard", "Soft keyboard hidden");
}
});
}
}
Solution 5
try these methods: showSoftInput(View, int, ResultReceiver)
and hideSoftInputFromWindow(IBinder, int, ResultReceiver)
. You can override onReceiveResult(int resultCode, Bundle resultData)
method of ResultReceiver
class to handle show/hide event.
Related videos on Youtube
Comments
-
shkim over 3 years
Is it possible to catch the event that Soft Keyboard was shown or hidden for EditText?
-
Pedro Loureiro over 12 yearsAlthough this is an old post, this answer in a similar context is more appropriate: stackoverflow.com/questions/4312319/…
-
Zain Ali over 11 yearsThis is a better solution stackoverflow.com/questions/2150078/…
-
-
DiveInto about 13 yearshow to get the window content resize event?
-
David Homes over 11 yearswhere does one add this override? I've a SherlockActivty inflated from a LinearLayout but keep getting that the method is not defined for the class
-
Dmitry Zaytsev over 11 years@dhomes it's not method of
Activity
. It's method ofView
. Create your customView
and override this method. -
verybadalloc almost 11 yearsThis works for the Hard keyboard, while the OP specifically asked for the softKeyboard events.
-
adamdport over 9 yearsOn some devices (eg. Samsung), the predictive text feature causes issues with this solution. I worked around this by setting the inputType on my edittexts to "textVisiblePassword" to disable it.
-
TWiStErRob about 9 yearsThis way you'll only receive a callback when your requested action has been done. But not when any future events happen. It would be nice if we receive the user's hide events (e.g. back button) when handed a
ResultReceiver
toshowSoftInput
, but that's not the case.