編輯:關於Android編程
使用 Qt 開發的 Android 應用,怎樣適應 Android 智能手機各種各樣的屏幕尺寸?
說到屏幕尺寸,從 2.8 吋到 8.9 吋的手機屏幕都有,這對程序猿們來講痛苦可不只一點。 Android 項目本身已經考慮了這個問題,資源文件,比如圖標,都有 ldpi / mdpi / hdpi / xhdpi 等等版本, Android 框架會根據屏幕大小自動選擇相應的圖標,這樣在不同尺寸的屏幕上,應用看起來就差不多了。
那 Qt 應用呢?其實不大用得上 Android 的這種機制(惟有 App Icon 可以搭便車),一切都得自己處理了。那怎麼處理呢?
首先要理解 DPI ,然後是字體大小。
DPI , dot per inch ,即每英寸包含的點數。還有一個概念是 PPI ,即每英寸包含的像素數。一般我們用 DPI 就夠了,對於專業人士處理超高 DPI 的場景,使用 PPI 可能更精確一些。在 Qt 中,只有 DPI ,所以我們單說它吧。
這個值越大,像素密度越大,小尺寸的屏幕就可以有大分辨率。比如有的 Android 手機, 3.7 吋屏幕就能提供 960x540 的分辨率,而有的手機, 5 吋屏幕卻提供 800x480 的分辨率。這兩種不同屏幕的尺寸和分辨率的手機,5 吋屏看起來會有顆粒感,而 3.7 吋看起來則非常細膩。這就是像素密度帶來的差別。
有的屏幕,橫向的 DPI 和縱向的 DPI 不一樣,即像素點不是正方形,這就更復雜了……
我們在寫應用時,理想的情況是:應當根據 DPI + 屏幕分辨率來設置界面元素的大小。
在 Qt 中, QScreen 類可以獲取到 DPI 相關的信息。
QScreen 的 physicalDotsPerInch / physicalDotsPerInchX / physicalDotsPerInchY 這一組屬性表示物理 DPI 。 logicalDotsPerInch / logicalDotsPerInchX / logicalDotsPerInchY 這一組屬性表示邏輯 DPI , Qt 使用它來計算字體大小,我們可以用它將字體的 pointSize 轉換為 pixelSize 。下面咱們就來說它。
logicalDotsPerInch 是一個 X 、 Y 的簡單平均值,多數情況下就夠用了,當然如果你有極致追求,請問道於 logicalDotsPerInchX 和 logicalDotsPerInchY 。
QFont 代表字體,字體的大小有兩種表示方式: pixelSize 和 pointSize 。即像素大小和點陣大小。如果你使用像素大小來表示字體,那字體將不受 DPI 的影響,在電腦上你可以調整顯示器的 DPI 來觀察界面的變化。但這不適用於移動場景中適配多樣化屏幕尺寸的要求。在針對 Android 設備開發時,我們應當使用字體的 pointSize ,這也是 Qt 應用的默認處理方式。
廢話了不是,默認就是 pointSize ,還啰嗦個甚!
非也非也!且往下看。
Qt 中有 QLabel / QPushButton / QListWidget / QTabelWidget 等等可以在 Android 設備上使用的控件,它們可以用來顯示文本。你找來一堆不同尺寸屏幕的手機,使用 QFont 的 setPointSize() 方法調整一下字體的點陣大小,權衡一下效果,就可以決定你的應用的字體尺寸如何設置了。
但還有非文本的場景,比如你是圖片按鈕,那怎麼辦呢?
我的答案是:根據字體的點陣大小計算出像素大小,然後拿這個來調整非文本控件的大小。這樣子界面上的文本元素和圖片等非文本元素才可以匹配起來。
從 pointSize 到 pixelSize 的計算公式: pixelSize = DPI * pointSize/72 。
看一個代碼片段:
int main(int argc, char **argv) { QApplication a(argc, argv); ... QScreen *screen = a.primaryScreen(); QFont f = a.font(); int pixelSize = (f.pointSize() * screen->logicalDotsPerInch()) / 72; /* f.setPointSize(25); a.setFont(f); int newPixelSize = (f.pointSize() * screen->logicalDotsPerInch()) / 72; */ ... }
上面的代碼還演示了從 pointSize 到 pixelSize 的換算,一旦你得到了合適的 pixelSize ,就可以以它為基礎來設置非文本界面元素的尺寸。
前面我們說最好結合分辨率和 DPI ,一起來調整界面元素。 DPI 的使用已經簡單介紹過了,剩分辨率了。
QScreen 類的 size 屬性可以返回屏幕的像素尺寸, availableSize 可以返回應用能夠使用的尺寸。兩者的區別是, availableSize 移除了窗口管理器占用的尺寸(在電腦上就是任務欄, Android 手機上是狀態欄之類的區域)。
下面是一個簡單的示例代碼:
#ifdef ANDROID QSize iconSize(32, 32); ... QScreen *screen = qApp->primaryScreen(); QFont f = qApp->font(); int pixelSize = (f.pointSize() * screen->logicalDotsPerInch()) / 72; QSize screenSize = screen->size(); if(screenSize.width() > 960 || screenSize.height() > 960) { iconSize *= ((qreal)pixelSize) / 20; } #endif
本系列的其它文章:
Fragment 是個什麼東西?可以把Fragment理解成Activity中的模塊,這個模塊有自己的布局,有自己的生命周期,單獨處理自己的輸入,在Activity運行的
cardView:添加依賴:在Studio搜索cardview即可 在V7包中或者直接在gradle中添加compile 'com.android.support
導航抽屜(navigationdrawer)是一個從屏幕左邊滑入的面板,用於顯示應用的主要導航項目。用戶可以通過在屏幕左邊緣滑入或者觸摸操作欄的應用圖標打開導航抽屜。導航
本章節所有內容皆為原創,如需轉載,請注明出處。http://blog.csdn.net/manoel/article/details/38471825Android是一個