Qt Android 實現全屏

90后大叔666發表於2024-07-28

本文內容參考自:https://blog.csdn.net/jun4331247/article/details/80739662

1.新建JFullScreen.java,新增以下程式碼,放置在QT安裝目錄\android_armv7\src\android\java\src\org\qtproject\qt5\android\bindings

package org.qtproject.junj;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.View;

public class JFullScreen {
    static final private String TAG = "JFullScreen";
    static private JFullScreen mInstance = new JFullScreen();
    private Context mContext = null;

    private JFullScreen() { }

    static public JFullScreen instance() { return mInstance; }

    public void setContext(Context context) {
        Log.d(TAG, "context: " + context.toString());
        mContext = context;
    }


    public void fullScreenLeanBack() {
        Log.d(TAG, "fullScreenLeanBack");
        Activity activity = (Activity) mContext;
        View decorView = activity.getWindow().getDecorView();
        decorView.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);
    }

    public void fullScreenImmersive() {
        Log.d(TAG, "fullScreenImmersive");
        Activity activity = (Activity) mContext;
        View decorView = activity.getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_IMMERSIVE
                        | 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);
    }

    public void fullScreenStickyImmersive() {
        Log.d(TAG, "fullScreenStickyImmersive");
        Activity activity = (Activity) mContext;
        View decorView = activity.getWindow().getDecorView();
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                        | 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);
    }

    public int addTest(int value0, int value1) {
        Log.d(TAG, "I'm a test.");
        return value0 + value1;
    }
}

2. .pro檔案新增:+= androidextras

3.使用JNI寫呼叫Java程式碼的C++類

  這裡主要使用QAndroidJniObject類來實現呼叫Java程式碼,並使用QtAndroid::runOnAndroidThread讓程式碼執行在UI執行緒。

jfullscreen.h

#ifndef JFULLSCREEN_H
#define JFULLSCREEN_H

#include <QAndroidJniObject>

class JFullScreen
{
public:
    JFullScreen();
    void fullScreenLeanBack();
    void fullScreenImmersive();
    void fullScreenStickyImmersive();
    int addTest(int value0, int value1);

private:
    QAndroidJniObject _javaClass;
};

#endif // JFULLSCREEN_H

jfullscreen.cpp

#include "jfullscreen.h"

#include <functional>
#include <QtAndroid>

// JFS: JFullScreen
#define JFS_CLASSNAME "org/qtproject/junj/JFullScreen"
#define JFS_SIGNTURE_INSTANCE "()Lorg/qtproject/junj/JFullScreen;"

void realFullScreenLeanBackMethod() {
    QAndroidJniObject javaCustomFunction = QAndroidJniObject::callStaticObjectMethod(JFS_CLASSNAME, "instance", JFS_SIGNTURE_INSTANCE);
    javaCustomFunction.callMethod<void>("fullScreenLeanBack", "()V");
}
void realFullScreenImmersiveMethod() {
    QAndroidJniObject javaCustomFunction = QAndroidJniObject::callStaticObjectMethod(JFS_CLASSNAME, "instance", JFS_SIGNTURE_INSTANCE);
    javaCustomFunction.callMethod<void>("fullScreenImmersive", "()V");
}
void realFullScreenStickyImmersiveMethod() {
    QAndroidJniObject javaCustomFunction = QAndroidJniObject::callStaticObjectMethod(JFS_CLASSNAME, "instance", JFS_SIGNTURE_INSTANCE);
    javaCustomFunction.callMethod<void>("fullScreenStickyImmersive", "()V");
}

JFullScreen::JFullScreen()
{
    if(!QAndroidJniObject::isClassAvailable(JFS_CLASSNAME)) {
        qDebug("JFullScreen is unavailable.");
        return;
    }

    _javaClass = QAndroidJniObject::callStaticObjectMethod(JFS_CLASSNAME, "instance", JFS_SIGNTURE_INSTANCE);

    if(!_javaClass.isValid()) {
        qDebug(" JFullScreen instance is invalid.");
    }

    _javaClass.callMethod<void>("setContext", "(Landroid/content/Context;)V", QtAndroid::androidActivity().object<jobject>());
}

//use runOnAndroidThread() in order to run on android ui thread
void JFullScreen::fullScreenLeanBack()
{
    QtAndroid::Runnable runnable = realFullScreenLeanBackMethod;
    QtAndroid::runOnAndroidThread(runnable);
}

void JFullScreen::fullScreenImmersive()
{
    QtAndroid::Runnable runnable = realFullScreenImmersiveMethod;
    QtAndroid::runOnAndroidThread(runnable);
}

void JFullScreen::fullScreenStickyImmersive()
{
    QtAndroid::Runnable runnable = realFullScreenStickyImmersiveMethod;
    QtAndroid::runOnAndroidThread(runnable);
}

int JFullScreen::addTest(int value0, int value1)
{
    jint sum = _javaClass.callMethod<jint>("addTest", "(II)I", value0, value1);
    return sum;
}

4.新增jfullscreen.cpp、jfullscreen.h到工程

5.測試

建立一個JFullScreen進行測試。

    JFullScreen *pManager = new JFullScreen;
    int sum = pManager->addTest(1, 2);
    Q_ASSERT(sum == 3);
//    pManager->fullScreenLeanBack();
//    pManager->fullScreenImmersive();
    pManager->fullScreenStickyImmersive();

後記,三種全屏模式

1. Lean Back
Lean Back模式應用在不需要使用者頻繁的點選螢幕的情形下,比如影片播放APP。該模式下,使用者只需要單擊螢幕,System bar將會自動顯示處理,無需做更多的操作。

2.Immersive
Immersive模式應用在使用者需要頻繁與螢幕互動的情形下,比如遊戲,圖片瀏覽,閱讀等等。該模式下,使用者需要在螢幕邊緣向內滑動才能撥出system bar。

3. Sticky immersive
Sticky immersive模式與Immersive模式的區別是:System bar 撥出時,System bar是半透明顯示的, 同時System bar會自動隱藏。這種模式的好處是如果使用者誤操作導致system bar顯示出來後,無需做什麼其它操作,system bar會自動隱藏,在有些引用場景下,這是一個比較好的使用者體驗。

相關文章