1. 程式人生 > >Qt android 設定系統狀態列為全透明,半透明、全屏,設定狀態列顏色,修改程式圖示

Qt android 設定系統狀態列為全透明,半透明、全屏,設定狀態列顏色,修改程式圖示

實現Qt平臺下,安卓系統狀態列的相關設定(全透明,半透明、全屏,設定狀態列顏色,修改程式圖示,網上文章大多數提供多種方法,但是講述的雲裡霧裡,沒有說清楚,以下是本人自己整理,希望大家相互交流學習)
實驗環境:
Qt 5.12
程式語言:qml 和 c++
執行平臺:android

正如文章標題所述:在Qt平臺上執行安卓程式使得程式的轉態欄為透明(預設不設定的話是黑色,巨醜)。設定透明執行結果如下:
在這裡插入圖片描述
圖中紅色箭頭所指區域則是系統的轉態欄,這個是在我的電腦模擬器上執行的,實際執行是一樣的。

在開始講解實現的方法之前,你先要了解一下相關的術語,如圖:
在這裡插入圖片描述

具體的實現步驟如下:

一、Qt Android 版本之間的變革:
1.1、說道這裡,就必須得說一說Qt Android的版本問題了,很多人在做實際的操作的時候,沒有想自己的Qt版本,所以很多別人的方法自己不能成功也是理所應當的。
1.2、言歸正傳,如果我沒有記錯的話,Qt從5.8以後,就把Android平臺的開發併入到了linux、windows、mac的開發環境中,以前的時候還需要去下載一個單獨的 Qt for Android 的 Qt開發環境。所以,接下來我所使用的方法,低於5.9的Qt版本,對你們不會有作用的(應該)。
1.3、目前很多開發基本上都已經升級到了5.9,而我時刻保持著最新,目前使用的是Qt5.12的版本(截止本文程式碼編寫完時)。

二、廢話不多說,看看知識庫:

2.1、正如你在Qt中配置Android開發環境一樣,裡面需要用到的是Java JDK、Android SDK、NDK,還有一個Ant。這些東西總結一句話的概括就是把你的c++程式碼通過其中的元件編譯成為Android的產物,所以,接下來的操作我們就要想想辦法在這裡面去動動手腳,只是靠c++,可能是不得行的。

2.2、在你的Qt安裝目錄下,有很多的平臺的開發檔案,以及相關的工具,所以,你配置了Android環境自然而然也有相關的檔案。如下所示:
在這裡插入圖片描述

對於各個不一樣的平臺都有特定的連線工具以及相對應的檔案。
在這裡,需要注意的是,android_x86 和 android_armv7 的區別是:同樣執行安卓系統,只是對應裝置的架構不一樣,一個是x86,一個是arm,架構不一樣,對應的指令集也就不一樣。

2.3、Android軟體的開發中,會有一個配置檔案,叫做:AndroidManifest.xml,他的作用很多,後面用到了再說,請記住,這個檔案真的很重要,多看幾眼,免得你又不認識他了。

2.4、安卓系統的啟動,或者說安卓系統的入口檔案,入口函式是 **OnCreate()**方法,在後續的相關操作中,我們都將從中進行相關的修改。

2.5、問題來了,那麼Qt程式的入口就應該和這個**OnCreate()**方法有著千絲萬縷的關係了,那麼,在Qt的原始檔中,這個方法在哪裡呢?讓我來告訴你吧,在你安裝Qt目錄下的這個位置:
F:\SoftWareCatelogy\Qt\5.12.0\android_x86\src\android\java\src\org\qtproject\qt5\android\bindings

org\qtproject\qt5\android\bindings這個路徑在AndroidManifest.xml檔案中引用的格式為org.qtproject.qt5.android.bindings.XXXX

這個是我的Qt安卓路徑,請自行對照自己的安卓路徑。在這個資料夾內,有如下檔案:
在這裡插入圖片描述
備註:圖中紅色區域需要格外注意。

三、一頓操作猛如虎,原來不是二百五:

好了,說了這麼多,進入正題。

3.1AndroidManifest.xml檔案在哪裡?
這個檔案的作用不多說,預設的如果你自己不寫,那麼他會在你編譯為安卓程式的時候,自動的在你的生成目錄中,如下所示:
在這裡插入圖片描述

在你的工程目錄下新建一個名為AndroidSource的資料夾,並複製一份這個檔案到你的工程目錄下,在你的工程裡面(pro檔案內),新增如下程式碼:ANDROID_PACKAGE_SOURCE_DIR = $$PWD/AndroidSource

如圖所示:
在這裡插入圖片描述

接下來就是在你的資原始檔中,把這個檔案新增進來,新增好後如下所示:
在這裡插入圖片描述

接下來,雙擊這個檔案,Qt就會以圖形化的方式載入這個xml檔案了,相關的描述已經寫好自己看,修改程式的圖示就在這裡就可以進行修改了,但是需要把圖片以資源的形式新增到專案中。內容如下:
在這裡插入圖片描述

3.2、修改程式為全屏模式,狀態列也相應的隱藏掉:
在3.1中,我們已經說了AndroidManifest.xml這個檔案,接下來,我們使用文字方式開啟這個檔案。
內容如下:
在這裡插入圖片描述
這個是我截圖一個大的,下面給出activity這個標籤的截圖,就是上圖的紅色框框內容;
在這裡插入圖片描述
在上面這個圖裡面,紅色劃線的地方實際上就是指明安卓的啟動入口檔案是那個。在第二節 2.5 的那個圖的檔案就是在這裡被引用的。
當然了,修改為全屏只需要在這裡新增這麼一句程式碼即可:
android:theme = "@android:style/Theme.NoTitleBar.Fullscreen"
如下所示:
在這裡插入圖片描述
然後儲存執行就可以實現全屏了。效果如下:
在這裡插入圖片描述
和本文的第一張圖片很明顯的可以看得出來,這裡沒有了系統狀態列了,程式設定成了全屏模式。

四、設定系統欄顯示且透明懸浮於我們的程式上面,也叫沉浸式風格
如果你僅僅滿足這一點需求,後面的內容你大可跳過,或者收藏一波,下次繼續看。
4.1、根據上面的思路,我們總結一下,我們的所有功能設定都是在這個AndroidManifest.xml檔案實現的,接下里,我們將進行一些高階的深入研究。

4.2、還記得3.2中有一個圖裡面我畫了橫向並且寫了一個重點的圖嗎?就知道你懶,我又給你貼上下來了。圖片如下。
在這裡插入圖片描述
在這個圖片裡面,實際上這句劃線的程式碼的意思就是說,啟動安卓的入口檔案在哪裡。把這句話翻譯一下,就應該是這樣的:
\org\qtproject\qt5\android\bindings\QtActivity這個實際上就是我在 2.5 中所提到的OnCreate()方法,你開啟 QtActivity.java這個檔案,就能找到這個方法,內容如下:
在這裡插入圖片描述
接下來,我們要做的就是,重寫這個入口函式,然後設定程式為全屏,並且狀態列懸浮在我們的程式上。

4.3重寫入口函式,設定相關資訊
2.5節的資料夾下,新增一個名為QtFullscreenActivity.java的檔案。如下:
在這裡插入圖片描述
然後開啟,並新增如下程式碼:

package an.qt.QtFullscreenActivityAPP;//指明檔案包名
import android.content.Context;
import android.content.Intent;
import android.app.PendingIntent;
import android.util.Log;
import android.os.Bundle;
import android.view.WindowManager;

//繼承 QtActivity 類
public class QtFullscreenActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
    private final static String TAG = "QtFullscreen";
    @Override
	// 重寫 onCreate 方法
    public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
		  // 設定全屏並且狀態列懸浮程式之上
          getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
          getWindow().getDecorView().setFitsSystemWindows(true);
    }
}

這個檔案寫好了,我們再開啟AndroidManifest.xml,修改入口類方法為我們自己重寫的方法QtFullscreenActivity,在這個檔案中新增如下程式碼:android:name="an.qt.QtFullscreenActivityAPP.QtFullscreenActivity"
在這裡插入圖片描述
紅色框框放大如下,需要刪除這句配置:android:theme = "@android:style/Theme.NoTitleBar.Fullscreen
在這裡插入圖片描述

然後儲存,執行結果如下,和本文的第一張圖雷同了。
在這裡插入圖片描述

4.4設定狀態列顏色
歷經千辛萬苦,終於實現了這個功能,但是你覺得這樣還是不好看,給人一種背部被遮擋了感覺,所以,你想實現一個這樣的效果,類似如下:
在這裡插入圖片描述
想要一個紅色的狀態列,這樣看起來更加協調一點,最起碼對於我這種強迫症的人來說,我是非得需要這裡有顏色,沒有顏色我就解除安裝軟體。
還好我實現了這個功能,不然這篇部落格你就沒得看了。騷操作如下:

以下部分是經過請假安卓開發人員才得以實現,掌握多門技術得多重要啊。

注意,以下的程式碼需要在安卓平臺5.0以上貌似才可以,如果不得行,請自行找方法,只能幫你到這裡了。

4.5設定狀態列為全透明
實現上訴的效果可以直接設定狀態列為透明,然後在qml程式裡面進行設定背景顏色,給人一種錯覺就是設定的背景顏色,但是,實際效果不是很好,因為跨平臺上,狀態列的高度不好把握。具體的步驟如下。
1)、在 QtFullscreenActivity.java 這個檔案中,修改程式碼如下:

package an.qt.QtFullscreenActivityAPP;//指明檔案包名
import android.content.Context;
import android.content.Intent;
import android.app.PendingIntent;
import android.util.Log;
import android.os.Bundle;
import android.os.Build;
import android.graphics.Color;
import android.view.WindowManager;
import android.view.View;

//繼承 QtActivity 類
public class QtFullscreenActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
    private final static String TAG = "QtFullscreen";
	private static Context context;
	
    @Override
	// 重寫 onCreate 方法
    public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
		  
		  // 獲取程式控制代碼
		  context = getApplicationContext();
		  // 設定狀態列全透明
		//  this.setStatusBarFullTransparent();
    }
	
	
    //全域性獲取Context
    public static Context getContext() {
        return context;
    } 
 
    //全透狀態列
    private void setStatusBarFullTransparent()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//透明狀態列
            // 狀態列字型設定為深色,SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 為SDK23增加
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
 
            // 部分機型的statusbar會有半透明的黑色背景
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().setStatusBarColor(Color.TRANSPARENT);// SDK21
        }
	}
}

2)、然後重新進行編譯,效果如下:
在這裡插入圖片描述
接下來就是在你的程式裡面,把程式向下移動,使得狀態列不被我們自己內容混淆。整麼修改,你就自己去試試好了,我不想試了。

4.6設定狀態列顏色
什麼?你覺得這樣還是沒有滿足你內心的慾望,還想繼續搞點花樣出來,ok,沒有問題的,看下面。
1)、老規矩,在 QtFullscreenActivity.java 這個檔案中,修改程式碼如下,這一部分的程式碼是在上面程式碼的基礎上進行增加的,內容如下:

package an.qt.QtFullscreenActivityAPP;//指明檔案包名
import android.content.Context;
import android.content.Intent;
import android.app.PendingIntent;
import android.util.Log;
import android.os.Bundle;
import android.os.Build;
import android.graphics.Color;
import android.view.WindowManager;
import android.view.View;

//繼承 QtActivity 類
public class QtFullscreenActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
    private final static String TAG = "QtFullscreen";
	private static Context context;
	
    @Override
	// 重寫 onCreate 方法
    public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
		  
		  // 獲取程式控制代碼
		  context = getApplicationContext();
		  
		  // 設定狀態列顏色,需要安卓版本大於5.0
		  this.setStatusBarColor("#FF4040");
		  
		  // 設定狀態列全透明
		  //	this.setStatusBarFullTransparent();
    }
	
	
    //全域性獲取Context
    public static Context getContext() {
        return context;
    } 
 
    //全透狀態列
    private void setStatusBarFullTransparent()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//透明狀態列
            // 狀態列字型設定為深色,SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 為SDK23增加
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
 
            // 部分機型的statusbar會有半透明的黑色背景
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().setStatusBarColor(Color.TRANSPARENT);// SDK21
        }
	}
	
	// 非全透,帶顏色的狀態列,需要指定顏色
	private void setStatusBarColor(String color){
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
			// 需要安卓版本大於5.0以上
			getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
			getWindow().setStatusBarColor(Color.parseColor(color));
        }
	}
	
}

2)、注意,需要安卓版本大於5.0,因為5.0以上的版本才有這個函式。執行結果如下:
在這裡插入圖片描述

哇塞,歷盡千辛萬苦,終於可以了,我想,沒有人比我寫的更加詳細了吧。

最後提示一下:如果你有多個安卓平臺,都需要將 QtFullscreenActivity.java 這個檔案放在你Qt預設的入口檔案進行一起編譯,參考2.5小節。

實際上,在安卓裡面還可以通過其他方式進行設定,只是相對於Qt Android來說,目前比較好用的方法就是這樣。裡面很多的機制實際上和安卓有區別的,但是又脫不開關係的。

小哥哥我第一次寫這麼長的文章,看到這裡,你不給我點個贊,你說你好意思不???

當然了,可惡的我又想到了一個問題,要是在程式裡面,不同的頁面需要設定不同的狀態列顏色的時候,整麼破???哇,自己給自己挖坑。等有時間再來填坑吧。

最後,你如果有更好的辦法或者已經實現了不同的頁面進行設定狀態列顏色,請留言告知。

我的QQ:543985125