Есть ли в Android способ определить, видна ли программная («мягкая») клавиатура на экране?
Есть ли в Android способ определить, видна ли программная («мягкая») клавиатура на экране?
Ответы:
Там нет прямого пути - см http://groups.google.com/group/android-platform/browse_thread/thread/1728f26f2334c060/5e4910f0d9eb898a где Дайан Hackborn из команды Android ответил. Однако вы можете обнаружить это косвенно, проверив, изменился ли размер окна в #onMeasure. См. Как проверить видимость программной клавиатуры в Android? ,
Это работает для меня. Может быть, это всегда лучший способ для всех версий .
Было бы эффективно создать свойство видимости клавиатуры и наблюдать, как эти изменения задерживаются, поскольку метод onGlobalLayout вызывается много раз. Также хорошо проверить вращение устройства и windowSoftInputMode
нет adjustNothing
.
boolean isKeyboardShowing = false;
void onKeyboardVisibilityChanged(boolean opened) {
print("keyboard " + opened);
}
// ContentView is the root view of the layout of this activity/fragment
contentView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
contentView.getWindowVisibleDisplayFrame(r);
int screenHeight = contentView.getRootView().getHeight();
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
int keypadHeight = screenHeight - r.bottom;
Log.d(TAG, "keypadHeight = " + keypadHeight);
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
onKeyboardVisibilityChanged(true)
}
}
else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
onKeyboardVisibilityChanged(false)
}
}
}
});
contentView
заявлено?
попробуй это:
InputMethodManager imm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isAcceptingText()) {
writeToLog("Software Keyboard was shown");
} else {
writeToLog("Software Keyboard was not shown");
}
Я создал простой класс, который можно использовать для этого: https://github.com/ravindu1024/android-keyboardlistener . Просто скопируйте его в свой проект и используйте следующим образом:
KeyboardUtils.addKeyboardToggleListener(this, new KeyboardUtils.SoftKeyboardToggleListener()
{
@Override
public void onToggleSoftKeyboard(boolean isVisible)
{
Log.d("keyboard", "keyboard visible: "+isVisible);
}
});
rootView
это просто представление, указывающее на мой корневой вид в этом случае relative layout
:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/addresses_confirm_root_view"
android:background="@color/WHITE_CLR">
RelativeLayout rootView = (RelativeLayout) findViewById(R.id.addresses_confirm_root_view);
getViewTreeObserver()
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
if (heightDiff > 100) {
Log.e("MyActivity", "keyboard opened");
} else {
Log.e("MyActivity", "keyboard closed");
}
}
});
1
. Не важно. Только это должно быть меньше реальной длины клавиатуры
Я использовал это в качестве основы: http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android
/**
* To capture the result of IMM hide/show soft keyboard
*/
public class IMMResult extends ResultReceiver {
public int result = -1;
public IMMResult() {
super(null);
}
@Override
public void onReceiveResult(int r, Bundle data) {
result = r;
}
// poll result value for up to 500 milliseconds
public int getResult() {
try {
int sleep = 0;
while (result == -1 && sleep < 500) {
Thread.sleep(100);
sleep += 100;
}
} catch (InterruptedException e) {
Log.e("IMMResult", e.getMessage());
}
return result;
}
}
Затем написал этот метод:
public boolean isSoftKeyboardShown(InputMethodManager imm, View v) {
IMMResult result = new IMMResult();
int res;
imm.showSoftInput(v, 0, result);
// if keyboard doesn't change, handle the keypress
res = result.getResult();
if (res == InputMethodManager.RESULT_UNCHANGED_SHOWN ||
res == InputMethodManager.RESULT_UNCHANGED_HIDDEN) {
return true;
}
else
return false;
}
Затем вы можете использовать это для проверки всех полей (EditText, AutoCompleteTextView и т. Д.), Которые могли открыть программную клавиатуру:
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
if(isSoftKeyboardShown(imm, editText1) | isSoftKeyboardShown(imm, autocompletetextview1))
//close the softkeyboard
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
К сожалению, это не идеальное решение, но оно выполняет свою работу.
Вы можете использовать результат обратного вызова showSoftInput () и hideSoftInput (), чтобы проверить состояние клавиатуры. Полная информация и пример кода на
http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android
Вы можете обратиться к этому ответу - https://stackoverflow.com/a/24105062/3629912
Это работало на меня каждый раз.
adb shell dumpsys window InputMethod | grep "mHasSurface"
Он вернет true, если видна программная клавиатура.
Так что после долгого времени игры с AccessibilityServices, оконными вставками, определением высоты экрана и т. Д., Я думаю, я нашел способ сделать это.
Отказ от ответственности: он использует скрытый метод в Android, что означает, что он может быть непоследовательным. Тем не менее, в моем тестировании, похоже, работает.
Метод является InputMethodManager # getInputMethodWindowVisibleHeight () и существует с Lollipop (5.0).
Вызов, который возвращает высоту в пикселях текущей клавиатуры. Теоретически клавиатура не должна быть 0 пикселей в высоту, поэтому я сделал простую проверку высоты (в Kotlin):
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
if (imm.inputMethodWindowVisibleHeight > 0) {
//keyboard is shown
else {
//keyboard is hidden
}
Я использую Android Hidden API, чтобы избежать рефлексии, когда я вызываю скрытые методы (я делаю это много для приложений, которые я разрабатываю, в основном это хакерские / настраивающие приложения), но это должно быть возможно и с помощью рефлексии:
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
val windowHeightMethod = InputMethodManager::class.java.getMethod("getInputMethodWindowVisibleHeight")
val height = windowHeightMethod.invoke(imm) as Int
//use the height val in your logic
Это было намного менее сложным для требований, в которых я нуждался. Надеюсь, что это может помочь:
На основной деятельности:
public void dismissKeyboard(){
InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearchBox.getWindowToken(), 0);
mKeyboardStatus = false;
}
public void showKeyboard(){
InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
mKeyboardStatus = true;
}
private boolean isKeyboardActive(){
return mKeyboardStatus;
}
Основное логическое значение по умолчанию для mKeyboardStatus будет инициализировано как false .
Затем проверьте значение следующим образом и при необходимости выполните действие:
mSearchBox.requestFocus();
if(!isKeyboardActive()){
showKeyboard();
}else{
dismissKeyboard();
}
Это должно работать, если вам нужно проверить состояние клавиатуры:
fun Activity.isKeyboardOpened(): Boolean {
val r = Rect()
val activityRoot = getActivityRoot()
val visibleThreshold = dip(UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP)
activityRoot.getWindowVisibleDisplayFrame(r)
val heightDiff = activityRoot.rootView.height - r.height()
return heightDiff > visibleThreshold;
}
fun Activity.getActivityRoot(): View {
return (findViewById<ViewGroup>(android.R.id.content)).getChildAt(0);
}
Где UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP
= 100, а dip () - это функция anko, которая преобразует dpToPx:
fun dip(value: Int): Int {
return (value * Resources.getSystem().displayMetrics.density).toInt()
}
Я сделал это, установив GlobalLayoutListener, следующим образом:
final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightView = activityRootView.getHeight();
int widthView = activityRootView.getWidth();
if (1.0 * widthView / heightView > 3) {
//Make changes for Keyboard not visible
} else {
//Make changes for keyboard visible
}
}
});
Попробуйте этот код, он действительно работает, если KeyboardShown показан, то эта функция возвращает истинное значение ....
private final String TAG = "TextEditor";
private TextView mTextEditor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
mTextEditor = (TextView) findViewById(R.id.text_editor);
mTextEditor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
isKeyboardShown(mTextEditor.getRootView());
}
});
}
private boolean isKeyboardShown(View rootView) {
/* 128dp = 32dp * 4, minimum button height 32dp and generic 4 rows soft keyboard */
final int SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD = 128;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
/* heightDiff = rootView height - status bar height (r.top) - visible frame height (r.bottom - r.top) */
int heightDiff = rootView.getBottom() - r.bottom;
/* Threshold size: dp to pixels, multiply with display density */
boolean isKeyboardShown = heightDiff > SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD * dm.density;
Log.d(TAG, "isKeyboardShown ? " + isKeyboardShown + ", heightDiff:" + heightDiff + ", density:" + dm.density
+ "root view height:" + rootView.getHeight() + ", rect:" + r);
return isKeyboardShown;
}
В моем случае у меня был только один EditText
способ управления макетом, поэтому я нашел это решение. Это работает хорошо, в основном это обычай, EditText
который слушает фокус и отправляет локальную трансляцию, если фокус меняется или если нажата кнопка назад / сделано. Чтобы работать, вам нужно поместить манекен View
в макет с помощью android:focusable="true"
и android:focusableInTouchMode="true"
потому, что при вызове clearFocus()
фокус будет переназначен на первый фокусируемый вид. Пример фиктивного представления:
<View
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true"
android:focusableInTouchMode="true"/>
Дополнительная информация
Решение, которое обнаруживает разницу в изменениях компоновки, работает не очень хорошо, потому что оно сильно зависит от плотности экрана, поскольку 100 пикселей может быть много на одном устройстве, а на некоторых других вы не получите ложных срабатываний. Также разные производители имеют разные клавиатуры.
В Android вы можете обнаружить через оболочку ADB. Я написал и использую этот метод:
{
JSch jsch = new JSch();
try {
Session session = jsch.getSession("<userName>", "<IP>", 22);
session.setPassword("<Password>");
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
ChannelExec channel = (ChannelExec)session.openChannel("exec");
BufferedReader in = new BufferedReader(new
InputStreamReader(channel.getInputStream()));
channel.setCommand("C:/Android/android-sdk/platform-tools/adb shell dumpsys window
InputMethod | findstr \"mHasSurface\"");
channel.connect();
String msg = null;
String msg2 = " mHasSurface=true";
while ((msg = in.readLine()) != null) {
Boolean isContain = msg.contains(msg2);
log.info(isContain);
if (isContain){
log.info("Hiding keyboard...");
driver.hideKeyboard();
}
else {
log.info("No need to hide keyboard.");
}
}
channel.disconnect();
session.disconnect();
} catch (JSchException | IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
final View activityRootView = findViewById(R.id.rootlayout);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
activityRootView.getWindowVisibleDisplayFrame(r);
int screenHeight = activityRootView.getRootView().getHeight();
Log.e("screenHeight", String.valueOf(screenHeight));
int heightDiff = screenHeight - (r.bottom - r.top);
Log.e("heightDiff", String.valueOf(heightDiff));
boolean visible = heightDiff > screenHeight / 3;
Log.e("visible", String.valueOf(visible));
if (visible) {
Toast.makeText(LabRegister.this, "I am here 1", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(LabRegister.this, "I am here 2", Toast.LENGTH_SHORT).show();
}
}
});
Ответ @iWantScala отличный, но не работает для меня
rootView.getRootView().getHeight()
всегда имеет одинаковое значение
Одним из способов является определение двух переменных
private int maxRootViewHeight = 0;
private int currentRootViewHeight = 0;
добавить глобального слушателя
rootView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
currentRootViewHeight = rootView.getHeight();
if (currentRootViewHeight > maxRootViewHeight) {
maxRootViewHeight = currentRootViewHeight;
}
}
});
затем проверьте
if (currentRootViewHeight >= maxRootViewHeight) {
// Keyboard is hidden
} else {
// Keyboard is shown
}
работает отлично
Наконец-то появился прямой путь от Android R на базе Kotlin.
val imeInsets = view.rootWindowInsets.getInsets(Type.ime())
if (imeInsets.isVisible) {
//Ime is visible
//Lets move our view by the height of the IME
view.translationX = imeInsets.bottom }
У меня была похожая проблема. Мне нужно было отреагировать на кнопку Enter на экране (которая спрятала клавиатуру). В этом случае вы можете подписаться на OnEditorAction текстового представления, с которым была открыта клавиатура - если у вас есть несколько редактируемых блоков, то подпишитесь на все из них.
В своей деятельности вы полностью контролируете клавиатуру, поэтому ни при каких условиях вы не столкнетесь с проблемой, открыта ли клавиатура или нет, если вы слушаете все события открытия и закрытия.
Существует прямой способ выяснить это. И это не требует изменения макета.
Так что он работает и в полноэкранном режиме с погружением.
Но, к сожалению, это работает не на всех устройствах. Таким образом, вы должны проверить это с вашим устройством (ами).
Хитрость в том, что вы пытаетесь скрыть или показать программную клавиатуру и зафиксировать результат этой попытки.
Если все работает правильно, клавиатура не отображается и не скрывается. Мы просто просим о состоянии.
Чтобы оставаться в курсе, вы просто повторяете эту операцию, например, каждые 200 миллисекунд, используя обработчик.
Реализация ниже делает только одну проверку.
Если вы делаете несколько проверок, вам следует включить все (_keyboardVisible) тесты.
public interface OnKeyboardShowHide
{
void onShowKeyboard( Object param );
void onHideKeyboard( Object param );
}
private static Handler _keyboardHandler = new Handler();
private boolean _keyboardVisible = false;
private OnKeyboardShowHide _keyboardCallback;
private Object _keyboardCallbackParam;
public void start( OnKeyboardShowHide callback, Object callbackParam )
{
_keyboardCallback = callback;
_keyboardCallbackParam = callbackParam;
//
View view = getCurrentFocus();
if (view != null)
{
InputMethodManager imm = (InputMethodManager) getSystemService( Activity.INPUT_METHOD_SERVICE );
imm.hideSoftInputFromWindow( view.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY, _keyboardResultReceiver );
imm.showSoftInput( view, InputMethodManager.SHOW_IMPLICIT, _keyboardResultReceiver );
}
else // if (_keyboardVisible)
{
_keyboardVisible = false;
_keyboardCallback.onHideKeyboard( _keyboardCallbackParam );
}
}
private ResultReceiver _keyboardResultReceiver = new ResultReceiver( _keyboardHandler )
{
@Override
protected void onReceiveResult( int resultCode, Bundle resultData )
{
switch (resultCode)
{
case InputMethodManager.RESULT_SHOWN :
case InputMethodManager.RESULT_UNCHANGED_SHOWN :
// if (!_keyboardVisible)
{
_keyboardVisible = true;
_keyboardCallback.onShowKeyboard( _keyboardCallbackParam );
}
break;
case InputMethodManager.RESULT_HIDDEN :
case InputMethodManager.RESULT_UNCHANGED_HIDDEN :
// if (_keyboardVisible)
{
_keyboardVisible = false;
_keyboardCallback.onHideKeyboard( _keyboardCallbackParam );
}
break;
}
}
};
Вот обходной путь, чтобы узнать, видна ли программная клавиша.
У некоторых популярных клавиатур есть определенные ключевые слова в их classNames:
Из ActivityManager.RunningServiceInfo проверьте наличие вышеуказанных шаблонов в ClassNames. Кроме того, ActivityManager.RunningServiceInfo's clientPackage = android указывает, что клавиатура привязана к системе.
Вышеупомянутая информация может быть объединена для строгого способа выяснить, видна ли программная клавиатура.
Как вы, наверное, знаете, Клавиатура Android Software будет видна только при возможном событии набора текста. Другими словами, клавиатура становится видимой только тогда, когда EditText сфокусирован. это означает, что вы можете узнать, видна клавиатура или нет, с помощью OnFocusChangeListener .
//Declare this Globally
public boolean isKeyBoardVisible = false;
//In OnCreate *[For Activity]*, OnCreateView *[For Fragment]*
text_send.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
isKeyBoardVisible = true;
else
isKeyBoardVisible = false;
}
});
Теперь вы можете использовать переменную isKeyBoardVisible в любом месте класса, чтобы узнать, открыта ли клавиатура или нет. Это хорошо сработало для меня.
Примечание. Этот процесс не работает, когда клавиатура открывается программно с помощью InputMethodManager, потому что это не вызывает OnFocusChangeListener.
Я преобразовал ответ в kotlin, надеюсь, это поможет пользователям kotlin.
private fun checkKeyboardVisibility() {
var isKeyboardShowing = false
binding.coordinator.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
binding.coordinator.getWindowVisibleDisplayFrame(r)
val screenHeight = binding.coordinator.rootView.height
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
val keypadHeight = screenHeight - r.bottom
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
}
} else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
}
}
}
}
Он работает с настройкой AdjustNothing, и используются события жизненного цикла. Также с Kotlin:
/**
* This class uses a PopupWindow to calculate the window height when the floating keyboard is opened and closed
*
* @param activity The parent activity
* The root activity that uses this KeyboardManager
*/
class KeyboardManager(private val activity: AppCompatActivity) : PopupWindow(activity), LifecycleObserver {
private var observerList = mutableListOf<((keyboardTop: Int) -> Unit)>()
/** The last value of keyboardTop */
private var keyboardTop: Int = 0
/** The view that is used to calculate the keyboard top */
private val popupView: View?
/** The parent view */
private var parentView: View
var isKeyboardShown = false
private set
/**
* Create transparent view which will be stretched over to the full screen
*/
private fun createFullScreenView(): View {
val view = LinearLayout(activity)
view.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT)
view.background = ColorDrawable(Color.TRANSPARENT)
return view
}
init {
this.popupView = createFullScreenView()
contentView = popupView
softInputMode = LayoutParams.SOFT_INPUT_ADJUST_RESIZE or LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
inputMethodMode = INPUT_METHOD_NEEDED
parentView = activity.findViewById(android.R.id.content)
width = 0
height = LayoutParams.MATCH_PARENT
popupView.viewTreeObserver.addOnGlobalLayoutListener {
val rect = Rect()
popupView.getWindowVisibleDisplayFrame(rect)
val keyboardTop = rect.bottom
if (this.keyboardTop != keyboardTop) {
isKeyboardShown = keyboardTop < this.keyboardTop
this.keyboardTop = keyboardTop
observerList.forEach { it(keyboardTop) }
}
}
activity.lifecycle.addObserver(this)
}
/**
* This must be called after the onResume of the Activity or inside view.post { } .
* PopupWindows are not allowed to be registered before the onResume has finished
* of the Activity
*/
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun start() {
parentView.post {
if (!isShowing && parentView.windowToken != null) {
setBackgroundDrawable(ColorDrawable(0))
showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0)
}
}
}
/**
* This manager will not be used anymore
*/
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun close() {
activity.lifecycle.removeObserver(this)
observerList.clear()
dismiss()
}
/**
* Set the keyboard top observer. The observer will be notified when the keyboard top has changed.
* For example when the keyboard is opened or closed
*
* @param observer The observer to be added to this provider
*/
fun registerKeyboardTopObserver(observer: (keyboardTop: Int) -> Unit) {
observerList.add(observer)
}
}
Полезный способ держать вид всегда над клавиатурой
fun KeyboardManager.updateBottomMarginIfKeyboardShown(
view: View,
activity: AppCompatActivity,
// marginBottom of view when keyboard is hide
marginBottomHideKeyboard: Int,
// marginBottom of view when keybouard is shown
marginBottomShowKeyboard: Int
) {
registerKeyboardTopObserver { bottomKeyboard ->
val bottomView = ViewUtils.getFullViewBounds(view).bottom
val maxHeight = ScreenUtils.getFullScreenSize(activity.windowManager).y
// Check that view is within the window size
if (bottomView < maxHeight) {
if (bottomKeyboard < bottomView) {
ViewUtils.updateMargin(view, bottomMargin = bottomView - bottomKeyboard +
view.marginBottom + marginBottomShowKeyboard)
} else ViewUtils.updateMargin(view, bottomMargin = marginBottomHideKeyboard)
}
}
}
Где getFullViewBounds
fun getLocationOnScreen(view: View): Point {
val location = IntArray(2)
view.getLocationOnScreen(location)
return Point(location[0], location[1])
}
fun getFullViewBounds(view: View): Rect {
val location = getLocationOnScreen(view)
return Rect(location.x, location.y, location.x + view.width,
location.y + view.height)
}
Где getFullScreenSize
fun getFullScreenSize(wm: WindowManager? = null) =
getScreenSize(wm) { getRealSize(it) }
private fun getScreenSize(wm: WindowManager? = null, block: Display.(Point) -> Unit): Point {
val windowManager = wm ?: App.INSTANCE.getSystemService(Context.WINDOW_SERVICE)
as WindowManager
val point = Point()
windowManager.defaultDisplay.block(point)
return point
}
Где updateMargin
fun updateMargin(
view: View,
leftMargin: Int? = null,
topMargin: Int? = null,
rightMargin: Int? = null,
bottomMargin: Int? = null
) {
val layoutParams = view.layoutParams as ViewGroup.MarginLayoutParams
if (leftMargin != null) layoutParams.leftMargin = leftMargin
if (topMargin != null) layoutParams.topMargin = topMargin
if (rightMargin != null) layoutParams.rightMargin = rightMargin
if (bottomMargin != null) layoutParams.bottomMargin = bottomMargin
view.layoutParams = layoutParams
}
Я сделал это следующим образом, но это можно сделать только в том случае, если ваша цель - закрыть / открыть клавиатуру.
пример закрытия: (проверка, закрыта ли клавиатура, если нет - закрытие)
imm.showSoftInput(etSearch, InputMethodManager.HIDE_IMPLICIT_ONLY, new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode != InputMethodManager.RESULT_UNCHANGED_HIDDEN)
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
});
может использовать:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(
getClass().getSimpleName(),
String.format("conf: %s", newConfig));
if (newConfig.hardKeyboardHidden != hardKeyboardHidden) {
onHardwareKeyboardChange(newConfig.hardKeyboardHidden);
hardKeyboardHidden = newConfig.hardKeyboardHidden;
}
if (newConfig.keyboardHidden != keyboardHidden) {
onKeyboardChange(newConfig.keyboardHidden);
keyboardHidden = newConfig.hardKeyboardHidden;
}
}
public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
public static final int KEYBOARDHIDDEN_NO = 1;
public static final int KEYBOARDHIDDEN_YES = 2;
public static final int KEYBOARDHIDDEN_SOFT = 3;
//todo
private void onKeyboardChange(int keyboardHidden) {
}
//todo
private void onHardwareKeyboardChange(int hardKeyboardHidden) {
}
Я написал образец .
Этот репозиторий может помочь определить состояние клавиатуры, не предполагая, что «клавиатура должна быть больше, чем X часть экрана»
Если вы поддерживаете apis для AndroidR в своем приложении, вы можете использовать метод ниже.
In kotlin :
var imeInsets = view.rootWindowInsets.getInsets(Type.ime())
if (imeInsets.isVisible) {
view.translationX = imeInsets.bottom
}
Примечание: это доступно только для AndroidR, и ниже версия Android должна следовать некоторым другим ответам, или я обновлю это для этого.