Как "подтолкнуть" экран, когда отображается софтборд
У меня в приложении LibGDX для Android есть таблица, расположенная ниже некоторых текстовых полей (одна строка) и кнопка ниже (Отправить). У меня вопрос, как "сдвинуть" вверх таблицу, текстовые поля и кнопку, когда текстовое поле фокусируется (щелкните по нему) и появляется программная клавиатура? Другими словами, как заставить программную клавиатуру не покрывать другие мои объекты. Это решение может быть связано с этим вопросом: Как найти высоту программной клавиатуры в приложении LibGDX
Большое спасибо.
3 ответа
Я нашел обходной путь для своей проблемы, он работает, но я не думаю, что он слишком чистый. Итак, мой сценарий был:
- таблица контейнеров, содержащая ScrollPane (другую таблицу), под этой таблицей прокрутки два TextFields и под ними кнопка Submit
- таблица контейнеров для заполнения родительского элемента (полный экран)
- текстовые поля и кнопка выровнены по нижней части таблицы контейнера
Проблема была в том, что когда OnscreenKeybord был виден, он покрывал нижние объекты (текстовые поля и кнопки) и часть таблицы прокрутки.
Мое решение / обходной путь:
keyboard = new OnscreenKeyboard() {
@Override
public void show(boolean visible) {
Gdx.input.setOnscreenKeyboardVisible(visible);
// Hmmmm...
container.invalidate();
if (visible) {
// TODO get OsK height somehow!!!
container.padBottom(310);
} else {
container.padBottom(0);
}
}
};
textFld1.setOnscreenKeyboard(keyboard);
textFld2.setOnscreenKeyboard(keyboard);
и на InputListener кнопки Submit (на touchDown) у меня есть функция очистки, как:
textFld1.setText("");
textFld2.setText("");
stage.unfocus(textFld1);
stage.unfocus(textFld2);
keyboard.show(false);
Таким образом, таблица контейнеров будет заполнена при отображении программной клавиатуры и будет восстановлена после нажатия кнопки отправки; также мягкая клавиатура скрыта.
Теперь есть две проблемы с этим обходным путем:
Я не нашел способ получить высоту мягкой клавиатуры; как вы можете видеть в примере кода, я выбрал произвольное значение для отступа вверх, поэтому на моем эмуляторе все будет хорошо выглядеть
если нажата хард-кнопка Back или ESC в эмуляторе, софт-клавиатура будет скрыта, но добавление таблицы будет по-прежнему; Я не нашел, как определить, видна ли программная клавиатура или нет
Если кто-то найдет другое решение для моей проблемы, пожалуйста, опубликуйте его.
Благодарю.
Я тоже полностью боролся с этой проблемой, но я думаю, что нашел действительно хорошее решение.
Решение в теории:
когда клавиатура выскакивает, экран изменяет размеры, вызывая обратный вызов libgdx resize.
Преимущества:
- нет необходимости иметь логику, связанную с обнаружением видимости клавиатуры
- нет необходимости получать высоту клавиатуры
- обрабатывать все в обратном вызове resize класса экрана libgdx
- прост в реализации (я думаю)
Недостатки
- приложение больше не может быть полноэкранным; строка состояния показывает и прочее
Как это сделать:
Создать
main_layout.xml
файл, (....YourLibGdxThing\android\res\layout\main_layout.xml
) такой, что имеет следующий XML:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/main_frame_layout" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout>
изменить ваш класс запуска Android (
....YourLibGdxThing\android\src\your\name\space\android\AndroidLauncher.java
) такой, что onCreate выглядит так:public class AndroidLauncher extends AndroidApplication { @Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); FrameLayout frameLayout = (FrameLayout) findViewById(R.id.main_frame_layout); frameLayout.addView(initializeForView(new YourGame(),config)); } }
менять
android:windowFullScreen
атрибут вstyle.xml
(....YourLibGdxThing\android\res\values\styles.xml
) ложно; XML должен выглядеть так вstyle.xml
:<resources> <style name="GdxTheme" parent="android:Theme"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowAnimationStyle">@android:style/Animation</item> <item name="android:windowNoTitle">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowFullscreen">false</item> <!-- IMPORTANT --> </style> </resources>
добавить атрибут
android:windowSoftInputMode="adjustResize"
в манифест андроид, в тег активности... мой AndroidManifest (....YourLibGdxThing\android\AndroidManifest.xml
) выглядит так:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.project.reverse.domain.thing" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="22" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/GdxTheme" > <activity android:name="my.project.reverse.domain.thing.AndroidLauncher" android:label="@string/app_name" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize" <!-- IMPORTANT --> android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Спасибо! Я надеюсь, что это помогает!!!!!!!!!!
Задавать android:windowSoftInputMode
в adjustPan
в вашем <activity>
блок, чтобы получить желаемый результат. См. Документы: https://developer.android.com/guide/topics/manifest/activity-element.html