Есть ли способ в android получить высоту виртуальной клавиатуры устройства

есть ли какой-либо способ в android получить высоту виртуальной клавиатуры Android-устройства во время выполнения. На самом деле я хочу показать текстовое поле над клавиатурой.

Ответ 1

Да, вы можете с помощью Viewtree Observer и глобального прослушивателя макетов просто попробовать следующие шаги

  • Получить корневой вид вашего макета
  • получить наблюдателя Viewtree для этого корня и добавить к нему глобальный приемник макетов.

теперь, когда отображается мягкая клавиатура, андроид будет изменять размер экрана, и вы получите звонок на слушателя. Это единственное, что вам теперь нужно сделать, это рассчитать разницу между высотой, которую ваш корневой вид имеет после изменения размера и исходного размера. Если разница больше 150, рассмотрите это как раздутую клавиатуру.

Ниже приведен пример кода

root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
     public void onGlobalLayout(){
           int heightDiff = root.getRootView().getHeight()- root.getHeight();
           // IF height diff is more then 150, consider keyboard as visible.  
        }
  });

С уважением, Techfist

Ответ 2

Чтобы решить эту проблему, я написал keyboardHeightProvider, который может вычислять высоту плавающей мягкой клавиатуры. Упражнение может быть настроено на настройкуNone или adjustPan в AndroidManifest.xml.

https://github.com/siebeprojects/samples-keyboardheight

Siebe

Ответ 3

Я попробовал много предложенных методов для этого, но ни один из них не работал для Android SDL. Я думаю, что это происходит потому, что дисплей SDL "полный экран" или что он находится в "AbsoluteLayout", и поэтому высота "View" никогда не меняется. Этот метод работал у меня:

Получение размеров мягкой клавиатуры

mRootWindow = getWindow();
mRootView = mRootWindow.getDecorView().findViewById(android.R.id.content);
mRootView.getViewTreeObserver().addOnGlobalLayoutListener(
    new ViewTreeObserver.OnGlobalLayoutListener() {
    public void onGlobalLayout(){
        Rect r = new Rect();
        View view = mRootWindow.getDecorView();
        view.getWindowVisibleDisplayFrame(r);
        // r.left, r.top, r.right, r.bottom
    }
    });

Ответ 4

поместите текстовое поле как родительское дно.

android:layout_alignParentBottom="true"

а в файле манифеста введите мягкий ввод adjustresize

android:windowSoftInputMode="adjustResize"

тогда текстовое поле будет двигаться вверх, когда появится клавиатура.

Ответ 5

Вы не можете сказать. Нет, на самом деле: вы просто не можете сказать.

Клавиатуре не обязательно должна быть какая-то особая форма. Его не нужно размещать в нижней части экрана (много наиболее популярные варианты не), он не должен сохранять свой текущий размер при изменении текстовых полей (почти ни один из них не зависит от флагов). Это даже не должно быть прямоугольник. Он также может просто взять на себя весь экран.

(копия моего ответа по аналогичному вопросу Получение размеров мягкой клавиатуры)

Ответ 6

Я создал проект библиотеки для получения высоты клавиатуры Android, даже когда действия не используют adjustResize ввода adjustResize.

https://github.com/Crysis21/KeyboardHeightProvider

Ответ 7

Мое решение - это комбинация всех вышеперечисленных решений. Это решение также является взломанным, но решает проблему (по крайней мере для меня).

  • У меня есть временное представление с прозрачным фоном в нижней части экрана.
  • Я добавил флаг android:windowSoftInputMode="adjustResize" в тег активности в манифесте, как показано на рисунке @bill.
  • Теперь основная история находится в onGlobalLayout(). Там я вычисляю разницу между осью y temp view и высотой корневого представления

    final View view = findViewById(R.id.base);
    
    view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    
        @Override
        public void onGlobalLayout() {
    
            int rootViewHeight = view.getRootView().getHeight();
            View tv = findViewById(R.id.temp_view);
            int location[] = new int[2];
            tv.getLocationOnScreen(location);
            int height = (int) (location[1] + tv.getMeasuredHeight());
            deff = rootViewHeight - height;
            // deff is the height of soft keyboard
    
        }
    });
    

Но в любом случае для решения проблемы @zeeshan0026 достаточно всего одного флага в манифесте android:windowSoftInputMode="adjustResize".

Ответ 8

Не смотрите больше! Я искал решение для этого в течение длительного времени. После нескольких дней попыток всех трюков, предложенных в SOF, я нашел идеальное решение, которое действительно работает.

Этот проект GitHub демонстрирует его наилучшим образом: https://github.com/siebeprojects/samples-keyboardheight

Удачи!

Ответ 9

Я использовал это для того, чтобы программно увеличить высоту клавиатуры в Android и протестировать ее, попробуйте один раз:

myLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

                @Override
                public void onGlobalLayout() {
                    // TODO Auto-generated method stub
                    Rect r = new Rect();
                    parent.getWindowVisibleDisplayFrame(r);

                    int screenHeight = parent.getRootView().getHeight();
                    int heightDifference = screenHeight - (r.bottom - r.top);
                    Log.d("Keyboard Size", "Size: " + heightDifference);

                    //boolean visible = heightDiff > screenHeight / 3;
                }
            });

Спасибо.

Ответ 10

Предположим, что rootView вашего макета - это RelativeLayout. Что вы можете сделать, создайте класс CustomRelativeLayout который расширяет RelativeLayout и Overrides onSizeChanged метод Overrides onSizeChanged внутри него. Поэтому, когда программная клавиатура откроется, высота RelativeLayout изменится, и об этом будет сообщено в методе onSizeChanged.

public class CustomRelativeLayout extends RelativeLayout {

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    int softKeyboardHeight = oldh - h; // Assuming softKeyboard Opened up

    if(softKeyboardHeight > oldh * 0.15) {
        Log.i("Here", Integer.toString(softKeyboardHeight));
        // Keyboard has popped up

    } else {
        // Not the keyboard
    }
}

В файле манифеста внесите эти изменения, чтобы действие открывалось в режиме изменения размера, а не в режиме панорамирования и сканирования. В режиме изменения размера макет сможет изменить размер при открытии клавиатуры. Чтобы узнать больше о пан-сканировании и изменении размера посетите https://developer.android.com/training/keyboard-input/visibility

<activity
        android:name=".MainActivity"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

Ответ 11

Эта работа для меня:

// get height statusbar
int heightStatusbar= 0;
int resourceId = getResources().getIdentifier("status_bar_height","dimen","android");
    if (resourceId > 0) {
        heightStatusbar= getResources().getDimensionPixelSize(resourceId);
    }

// get height Screen
Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int heightScreeen = size.y;

float heightKeyBoard = (heightScreeen - heightStatusbar) / 2.1168385

Ответ 12

Этот метод работает с adjustNothing или любым windowSoftInputMode в вашей деятельности.

<activity android:name=".MainActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:theme="@style/AppTheme"
        android:windowSoftInputMode="stateHidden|adjustNothing"/>

Используя PopupWindow, у вас может быть отдельное "поведение клавиатуры", и оно будет уведомлять вас о размере клавиатуры. PopupWindow имеет высоту экрана, но ширину 0px, поэтому вы не увидите его, это не повлияет на вашу активность, но предоставит вам необходимую информацию.

Создайте класс с именем KeyboardHeightProvider и добавьте следующий код:

public class KeyboardHeightProvider extends PopupWindow {
    public KeyboardHeightProvider(Context context, WindowManager windowManager, View parentView, KeyboardHeightListener listener) {
        super(context);

        LinearLayout popupView = new LinearLayout(context);
        popupView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        popupView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            DisplayMetrics metrics = new DisplayMetrics();
            windowManager.getDefaultDisplay().getMetrics(metrics);

            Rect rect = new Rect();
            popupView.getWindowVisibleDisplayFrame(rect);

            int keyboardHeight = metrics.heightPixels - (rect.bottom - rect.top);
            int resourceID = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceID > 0) {
                keyboardHeight -= context.getResources().getDimensionPixelSize(resourceID);
            }
            if (keyboardHeight < 100) {
                keyboardHeight = 0;
            }
            boolean isLandscape = metrics.widthPixels > metrics.heightPixels;
            boolean keyboardOpen = keyboardHeight > 0;
            if (listener != null) {
                listener.onKeyboardHeightChanged(keyboardHeight, keyboardOpen, isLandscape);
            }
        });

        setContentView(popupView);

        setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
        setWidth(0);
        setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
        setBackgroundDrawable(new ColorDrawable(0));

        parentView.post(() -> showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0));
    }

    public interface KeyboardHeightListener {
        void onKeyboardHeightChanged(int keyboardHeight, boolean keyboardOpen, boolean isLandscape);
    }
}

Обратите внимание на то, что у PopupWindow есть свой собственный setSoftInputMode(...), поэтому не имеет значения, на что вы устанавливаете свою активность, PopupWindow все равно будет зависеть от открытия или закрытия клавиатуры и будет обеспечивать родительскую активность высоты. Если высота >= 100, вы можете предположить, что клавиатура открыта.

Чтобы использовать его, просто создайте его экземпляр в методе Activity onCreate(...) после setContentView(...):

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    LinearLayout llRoot = findViewById(R.id.llRoot); //The root layout (Linear, Relative, Contraint, etc...)

    new KeyboardHeightProvider(this, getWindowManager(), llRoot, new KeyboardHeightProvider.KeyboardHeightListener() {
        @Override
        public void onKeyboardHeightChanged(int keyboardHeight, boolean keyboardOpen, boolean isLandscape) {
            Log.i("keyboard listener", "keyboardHeight: " + keyboardHeight + " keyboardOpen: " + keyboardOpen + " isLandscape: " + isLandscape);

            //Do what you want or have to with the parameters..
        }
    });

    //...
}