Android: как я могу узнать, показывает ли программная клавиатура или нет?
Вот дилемма: я показываю экран с 3 полями ввода и 2 кнопками внутри вкладки (всего 3 вкладки, и они находятся в нижней части экрана). 2 кнопки расположены слева внизу и справа от экрана, прямо над вкладками. когда я нажимаю на поле ввода, все вкладки и кнопки нажимаются вверх на верхней части клавиатуры.
Я хочу только нажимать кнопки вверх и оставлять вкладки там, где они изначально находятся, внизу. я думаю о настройке видимости вкладок в состояние УДАЛЕНО, как только я определю, что экранная клавиатура отображается, и видимости ВИДИМОГО, когда экранная клавиатура исчезла.
есть ли какой-нибудь слушатель для софт-клавиатуры или, может быть, поле ввода? может быть, какое-то хитрое использование OnFocusChangeListener
для редактирования текста? Как я могу определить, видна ли клавиатура или нет?
6 ответов
Определить, показывает ли клавиатура, по-видимому, невозможно.
Вы можете отключить все вместе с windowSoftInputMode
тег xml в манифесте: http://developer.android.com/reference/android/R.attr.html. Или вы можете посмотреть, как снять фокусировку, чтобы скрыть клавиатуру: скрыть программную клавиатуру во время работы без каких-либо операций с клавиатурой.
Ни один из них точно не решит вашу проблему. Я помню, как читал пост в блоге, настоятельно советуя не использовать вкладки внизу, а не вверху экрана, для ясности пользовательского интерфейса. Я рекомендую вам следить за этим.
Насколько я знаю, ты не можешь.
Тем не менее, вы можете отслеживать изменения размера макета, и поскольку появление клавиатуры является основной причиной изменения размеров, вы можете предположить, что клавиатура отображается или нет.
Вот пример кода для мониторинга изменения размера макета. Просто используйте этот макет в качестве родителя вашего оригинального макета и используйте его слушателя. Если высота уменьшилась, вы можете предположить, что клавиатура отображается, а если она была увеличена, вы можете предположить, что она закрыта.
public class LayoutSizeChangedSensorFrameLayout extends FrameLayout {
public enum SizeChange {
HEIGHT_INCREASED, HEIGHT_DECREASED, WIDTH_INCREASED, WIDTH_DECREASED
}
public interface OnLayoutSizeChangedListener {
void onSizeChanged(EnumSet<SizeChange> direction);
}
private OnLayoutSizeChangedListener mLayoutSizeChangeListener;
public LayoutSizeChangedSensorFrameLayout(final Context context) {
super(context);
}
public LayoutSizeChangedSensorFrameLayout(final Context context, final AttributeSet attributeSet) {
super(context, attributeSet);
}
public LayoutSizeChangedSensorFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mLayoutSizeChangeListener != null) {
final EnumSet<SizeChange> result = EnumSet.noneOf(SizeChange.class);
if (oldh > h)
result.add(SizeChange.HEIGHT_DECREASED);
else if (oldh < h)
result.add(SizeChange.HEIGHT_INCREASED);
if (oldw > w)
result.add(SizeChange.WIDTH_DECREASED);
else if (oldw < w)
result.add(SizeChange.WIDTH_INCREASED);
if (!result.isEmpty())
mLayoutSizeChangeListener.onSizeChanged(result);
}
}
public void setOnLayoutSizeChangedListener(final OnLayoutSizeChangedListener layoutSizeChangeListener) {
this.mLayoutSizeChangeListener = layoutSizeChangeListener;
}
public OnLayoutSizeChangedListener getOnLayoutSizeChangeListener() {
return mLayoutSizeChangeListener;
}
}
Наконец-то я нашел решение после поиска нескольких классов. Я решил использовать WindowsInset, потому что он не вызывается каждую секунду, как использование глобального макета. Есть видео, рассказывающее о том, как использовать windowsInset. Связь
Это может помочь http://developer.android.com/reference/android/inputmethodservice/InputMethodService.html
Код клавиатуры здесь, я немного обошел его, но сдался, я не вижу отправляемых трансляций, которые были бы полезны, по крайней мере, здесь. Может быть, вы можете найти код более низкого уровня в репозитории и найти полезную отправку намерений. Первый линк может сказать вам, когда он станет видимым, но я не уверен, как сказать, когда он станет невидимым.
Рабочее решение для меня -
ViewTreeObserver treeObserver = getViewTreeObserver();
if (treeObserver != null)
treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int pHeight = getResources().getDisplayMetrics().heightPixels;
Rect visRect = new Rect();
viewGroup.getWindowVisibleDisplayFrame(visRect);
boolean keyboardVisible;
int keyboardHeight= pHeight-currentHeight;
if (keyboardHeight > (MIN_KEYBOARD_HEIGHT*pHeight))
{
TGVLog.d(debugTag, "keyboardVisible-- "+true);
keyboardVisible = true;
}
else
{
TGVLog.d(debugTag, "keyboardVisible-- "+false);
keyboardVisible = false;
}
}
});
В моем последнем приложении у меня были некоторые проблемы с отображением программной клавиатуры, затем я использовал следующий код в моем файле манифеста:
<activity android:screenOrientation="portrait" android:configChanges="keyboardHidden|orientation" android:name=".rate.Calculator"/>