День добрый камрады!
Подскажите, хочу скрыть ActionBar в android.
// java code
if(getSupportActionBar().isShowing()) {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
getSupportActionBar().hide();
} else {
getSupportActionBar().show();
}
Чтобы протестировать этот код, создал пустой "Blanck Activity" в Android Studio. Кинул на кнопку, все работает.
Теперь в Qt.
// main.cpp
QAndroidJniObject::callStaticMethod<void>("AndroidBar", "hideNavigationBar");
// AndroidBar.java
import android.view.View;
import android.util.Log;
public class AndroidBar extends org.qtproject.qt5.android.bindings.QtActivity
{
private static final String TAG = AndroidBar.class.getSimpleName();
public static void hideNavigationBar() {
Log.d(TAG, "Hide navigation bar");
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
Но выдает ошибку:
non-static method getWindow() cannot be referenced from a static context
Ок, тогда так:
// AndroidBar.java
import android.util.Log;
public class AndroidBar extends org.qtproject.qt5.android.bindings.QtActivity
{
private static final String TAG = AndroidBar.class.getSimpleName();
public static void hideNavigationBar() {
Log.d(TAG, "Hide navigation bar");
MyTest test = new MyTest();
test.hideBar();
test = null;
}
}
// MyTest.java
import android.view.View;
import android.util.Log;
public class MyTest extends org.qtproject.qt5.android.bindings.QtActivity
{
private String TAG = AndroidBar.class.getSimpleName();
public void hideBar() {
Log.d(TAG, "Hide bar");
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
Ошибок нет, но метод не вызывается. Походу не видит класс MyTest.
// .pro
android {
QT += androidextras
ANDROID_PACKAGE_SOURCE_DIR = $PWD/android
OTHER_FILES += android/AndroidManifest.xml \
android/src/AndroidBar.java \
android/src/MyTest.java
}
// AndroidManifest.xml
<application android:icon="@drawable/icon" android:label="@string/app_name" android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
android:label="@string/app_name"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:screenOrientation="landscape">
Как добавить второй класс в проект? Или может есть другие решения?
На днях вернулся к этой проблеме. Решение есть и это дичь.
Первый вариант - костыль.
В файле .../Qt/5.6/android_armv7/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java добавить код:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (hasFocus) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);}
}
в один из методов:
public void onCreate(Bundle savedInstanceState)
или
public void onWindowFocusChanged(boolean hasFocus)
.
Как оказалось, проверка версии (KITKAT) делается не зря. Я пробовал на версии андроида 4.2, бар скрывается, но после нажатия по экрану возвращается. Поэтому работает только на версиях моложе. На 4.4 пробовал, точно работает.
Но этот вариант будет влиять на все проекты.
Второй вариант - правильный во всех смыслах. Необходимо создать свой activity в каталоге andrdoid/src от QtActivity.
Обязательные статьи к прочтению https://www.kdab.com/qt-android-episode-7/.
Подробно разбирается общение между потоками андроида и Qt'а. И здесь же решается проблема с вызовом не статичного метода.
В конце статьи 7-го эпизода есть исходники. Скрыть бар опробовал в этом примере. Для этого в
public class MyActivity extends QtActivity
добавил следующий код:
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
Log.d("BLABLA", "Window focus changed");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (hasFocus) {
Log.d("SCREEN","IMMERSIVE MODE ACTIVE");
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}
if (!QtApplication.invokeDelegate(hasFocus).invoked)
super.onWindowFocusChanged(hasFocus);
}
Не забываем про это:
import android.os.Build;
import android.view.View;
import android.util.Log;
Бар успешно скрывается и больше не беспокоит. Но это хорошо например для игр. Как вынести данный функционал в отдельный метод еще не разобрался, но это уже после.
Надеюсь пригодится.