日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android 配置aspect_Android APP全面屏适配技术要点

發(fā)布時間:2025/4/16 Android 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 配置aspect_Android APP全面屏适配技术要点 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

全面屏的概念

為什么先要解釋一下全面屏,因為這個詞在現(xiàn)在來講就是一個偽命題。全面屏字面意思就是手機的正面全部都是屏幕,100%的屏占比。但是現(xiàn)在推出所謂“全面屏”手機的廠商沒有一個能達到全面的。

那么下面來說一下Android開發(fā)領域?qū)θ嫫恋睦斫夂投x吧。

一般手機的屏幕縱橫比為16:9,如1080x1920、1440x2560等,其比值為1.77,在全面屏手機出現(xiàn)之前,Android中默認的最大屏幕縱橫比(maximum aspect ratio)為1.86,即能夠兼容16:9的屏幕。

一些手機廠商為了追求更大的屏幕空間以及更極致的用戶體驗,于是提高了屏幕縱橫比,17:9、19:10、18:9、18.5:9的手機開始進入市場,這些手機的屏幕縱橫比大大超過了1.86,這些手機被稱為全面屏手機。

為何需要適配

我們將targetSdkVersion的值改為小于等于23,運行程序,我們會發(fā)現(xiàn)屏幕底部出現(xiàn)一個黑條。

image

如何適配

targetSdkVersion<=23,更大的屏幕縱橫比

在Galaxy S8發(fā)布之后,Android官方提供了適配方案,即提高App所支持的最大屏幕縱橫比,實現(xiàn)很簡單,在AndroidManifest.xml中可做如下配置:

android:value="ratio_float"/>

其中ratio_float為浮點數(shù),官方建議為2.1或更大,因為18.5:9=2.055555555……,如果日后出現(xiàn)縱橫比更大的手機,此值將會更大。

android:value="2.1" />

max_aspect值也可以在Java代碼中動態(tài)地設置,通過下面的方法即可實現(xiàn):

public void setMaxAspect() {

ApplicationInfo applicationInfo = null;

try {

applicationInfo = getPackageManager().getApplicationInfo(getPackageName(),

PackageManager.GET_META_DATA);

} catch (PackageManager.NameNotFoundException e) {

e.printStackTrace();

}

if(applicationInfo == null){

throw new IllegalArgumentException(" get application info = null ");

}

applicationInfo.metaData.putString("android.max_aspect", "2.1");

}

如果targetSdkVersion的值的值大于23,那么應該不用設置max_aspect即可。

查看適配之后的截圖:

image

圖片資源適配

我們看一下啟動頁,在16:9屏幕中適配的圖片,到了18:9的屏幕中就會被拉伸了。

16:9屏幕中顯示

18:9屏幕中顯示

image

image

解決這個問題無非就是兩種方法,換圖片或者是換布局

換圖片

不能依賴單一廠商的解決方案,只能從Android系統(tǒng)屬性出發(fā)。考慮到目前大部分全面屏手機只是在高度上拉長,且大多為6.0英寸左右,像素密度對比xxhdpi并沒有多大區(qū)別,那我們可以在項目中增加一組資源drawable-xxhdpi-2160x1080 、drawable-long 這樣解決圖片的拉伸問題,當然這樣的方法肯定是不太好的,會增加app的容量。這里就不演示了。

優(yōu)化布局

當然最好的方法還是用相對布局采用XML的方式,或者.9圖的解決方案。

我總結的就是少量多切,盡量減少尺寸對布局的影響。比如這里,使用正方形的切圖,讓他居中顯示,無論屏幕縱橫比如何,都不會拉伸這個圖片,拉伸的只是背景而已。

image

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:scaleType="fitCenter"

android:src="@drawable/bz002"/>

適配前

適配后

image

image

全面屏高度問題適配

首先解釋一下window,decorview,rootview這幾個概念

image

Window官方文檔:Window

public abstract class Window. Abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background, title area, default key processing, etc.

The only existing implementation of this abstract class is android.view.PhoneWindow, which you should instantiate when needing a Window.

翻譯一下:每一個 Activity 都持有一個 Window 對象,但是 Window 是一個抽象類,這里 Android 為 Window 提供了唯一的實現(xiàn)類 PhoneWindow。也就是說 Activity 中的 window 實例就是一個 PhoneWindow 對象。

但是 PhoneWindow 終究是 Window,它并不具備多少 View 相關的能力。不過 PhoneWindow 中持有一個 Android 中非常重要的一個 View 對象 DecorView.

現(xiàn)在的關系就很明確了,每一個 Activity 持有一個 PhoneWindow 的對象,而一個 PhoneWindow 對象持有一個 DecorView 的實例,所以 Activity 中 View 相關的操作其實大都是通過 DecorView 來完成。

DecorView就可以理解為手機的內(nèi)屏,就是那塊玻璃,可以發(fā)光的屏幕。

這里通過代碼,打印出我們頁面中的高度的各項數(shù)據(jù)

int decorviewHeight = decorView.getHeight();

int screenHeight = FullScreenManager.getScreenHeight();

int nativeBarHeight = FullScreenManager.getNativeBarHeight();

int contentViewHeight = rootView.getHeight();

int navigationBarHeight1 = FullScreenManager.getNavigationBarHeight();

Log.d("shijiacheng","=======================================");

Log.d("shijiacheng","DecorView height: " + decorviewHeight + " px");

Log.d("shijiacheng","Screen height: " + screenHeight + " px");

Log.d("shijiacheng","NativeBar height: " + nativeBarHeight + " px");

Log.d("shijiacheng","ContentView height: " + contentViewHeight + " px");

Log.d("shijiacheng","NavigationBar height: " + navigationBarHeight + " px");

Log.d("shijiacheng","---------------------------------------");

獲取decorView的高度

final View decorView = getWindow().getDecorView();

int decorviewHeight = decorView.getHeight();

獲得屏幕高度

/**

* 獲得屏幕高度

* @return

*/

public static int getScreenHeight() {

Resources resource = AppContext.getInstance().getResources();

DisplayMetrics displayMetrics = resource.getDisplayMetrics();

return displayMetrics.heightPixels;

}

獲取狀態(tài)欄的高度

/**

* 獲取狀態(tài)欄的高度

*

* @return

*/

public static int getNativeBarHeight() {

Resources resource = AppContext.getInstance().getResources();

int result = 0;

int resourceId = resource.getIdentifier("status_bar_height",

"dimen", "android");

if (resourceId > 0) {

result = resource.getDimensionPixelSize(resourceId);

}

return result;

}

獲取contentView的高度

LinearLayout contentView = findViewById(R.id.root);

int contentViewHeight = contentView.getHeight();

獲取NavigationBar的高度

public static int getNavigationBarHeight() {

Resources resources = AppContext.getInstance().getResources();

int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");

int height = resources.getDimensionPixelSize(resourceId);

return height;

}

為了更加直觀的展示各個數(shù)據(jù),這里我們使用布局的方式將各個數(shù)據(jù)展示出來,布局代碼比較簡單,這里就不展示了。

image

先展示一下正常的屏幕高度的各項數(shù)據(jù)

10-08 09:52:03.636 23818-23818/? D/shijiacheng: =========================

10-08 09:52:03.637 23818-23818/? D/shijiacheng: DecorView height: 1280 px

10-08 09:52:03.637 23818-23818/? D/shijiacheng: Screen height: 1280 px

10-08 09:52:03.637 23818-23818/? D/shijiacheng: NativeBar height: 50 px

10-08 09:52:03.637 23818-23818/? D/shijiacheng: ContentView height: 1230 px

10-08 09:52:03.637 23818-23818/? D/shijiacheng: NavigationBar height: 96 px

10-08 09:52:03.637 23818-23818/? D/shijiacheng: -------------------------

image

DecorView = Screen height = NativeBar height + ContentView height

看一下小米mix全面屏的情況

2018-10-08 09:54:15.640 /? D/shijiacheng: =========================

2018-10-08 09:54:15.640 /? D/shijiacheng: DecorView height: 2160 px

2018-10-08 09:54:15.641 /? D/shijiacheng: RootView height: 2094 px

2018-10-08 09:54:15.641 /? D/shijiacheng: Screen height: 2030 px

2018-10-08 09:54:15.641 /? D/shijiacheng: NativeBar height: 66 px

2018-10-08 09:54:15.641 /? D/shijiacheng: ContentView height: 2094 px

2018-10-08 09:54:15.641 /? D/shijiacheng: NavigationBar height: 130 px

2018-10-08 09:54:15.641 /? D/shijiacheng: -------------------------

image

問題出現(xiàn)了,可以發(fā)現(xiàn)contentView的高度比screen屏幕的高度還要大,不禁要懷疑,我們的獲取屏幕高度的方法在全面屏下計算錯誤了。

問題1:獲取屏幕高度方法計算不準確

我們一直都是使用如下方法進行屏幕高度測量的:

public static int getScreenHeight() {

Resources resource = AppContext.getInstance().getResources();

DisplayMetrics displayMetrics = resource.getDisplayMetrics();

return displayMetrics.heightPixels;

}

但是這個方法卻是一個十分古老的方法,沒有與時俱進,雖然說在普通屏幕上這種方法沒有問題,但是在全面屏手機上來說,這種方法就不靈了。

下面我們就來研究一下獲取屏幕尺寸的方法的演進。

獲取屏幕寬高

獲取屏幕的寬高是我們開發(fā)中經(jīng)常遇到的問題,而且相信大家都已經(jīng)非常熟悉,最常用的為以下兩種:

public static int getScreenHeight1(Activity activity) {

return activity.getWindowManager().getDefaultDisplay().getHeight();

}

public static int getScreenHeight2(Activity activity) {

DisplayMetrics displayMetrics = new DisplayMetrics();

activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

return displayMetrics.heightPixels;

}

其實以上兩種方式是一樣的,只不過第二種是把信息封裝到 DesplayMetrics中,再從DesplayMetrics得到數(shù)據(jù)。

在 Android 3.2(Api 13) 之后又提供了如下的一個方法,將數(shù)據(jù)封裝到Point中,然后返回寬度高度信息。

@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)

public static int getScreenHeight3(Activity activity) {

Point point = new Point();

activity.getWindowManager().getDefaultDisplay().getSize(point);

return point.y;

}

在 Android 4.2(Api17) 之后提供了如下方法,與第三種類似也是將數(shù)據(jù)封裝到Point中,然后返回款高度信息。

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)

public static int getScreenHeight4(Activity activity) {

Point realSize = new Point();

activity.getWindowManager().getDefaultDisplay().getRealSize(realSize);

return realSize.y;

}

其實getRealSize這個方法在Android Api15的時候就已經(jīng)加入了,不過是被隱藏了,通過查閱源碼我們可以看到。

image

Android Api15 Display.java源碼中getRealSize()方法被標記為@hide

image

因此,我們可以重寫獲取高度的方法,適配所有機型,所有系統(tǒng)。

適配所有屏幕的獲取屏幕尺寸的方法

public static int[] getScreenSize(Context context) {

int[] size = new int[2];

WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

Display d = w.getDefaultDisplay();

DisplayMetrics metrics = new DisplayMetrics();

d.getMetrics(metrics);

// since SDK_INT = 1;

int widthPixels = metrics.widthPixels;

int heightPixels = metrics.heightPixels;

// includes window decorations (statusbar bar/menu bar)

if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)

try {

widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);

heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);

} catch (Exception ignored) {

}

// includes window decorations (statusbar bar/menu bar)

if (Build.VERSION.SDK_INT >= 17)

try {

Point realSize = new Point();

Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);

widthPixels = realSize.x;

heightPixels = realSize.y;

} catch (Exception ignored) {

}

size[0] = widthPixels;

size[1] = heightPixels;

return size;

}

使用新的獲取高度的方法,重新運行程序,運行結果已經(jīng)正常顯示了。

2018-10-08 13:19:32.389 /? D/shijiacheng: ==========================

2018-10-08 13:19:32.390 /? D/shijiacheng: DecorView height: 2160 px

2018-10-08 13:19:32.390 /? D/shijiacheng: Screen height: 2160 px

2018-10-08 13:19:32.390 /? D/shijiacheng: NativeBar height: 66 px

2018-10-08 13:19:32.390 /? D/shijiacheng: ContentView height: 2094 px

2018-10-08 13:19:32.390 /? D/shijiacheng: NavigationBar height: 130 px

2018-10-08 13:19:32.390 /? D/shijiacheng: --------------------------

image

問題2:小米mix切為經(jīng)典導航鍵模式下的計算問題

我們在MIUI設置中將全面屏導航樣式修改為“經(jīng)典導航鍵”樣式。

image

重新運行程序,運行結果如下:

image

可以發(fā)現(xiàn)又出問題了,DecorView = Screen height > NativeBar height + ContentView height

這里不難發(fā)現(xiàn),Screen height將底部虛擬導航欄的高度也算進里面了。

很多情況下,我們都用如下方法獲取導航欄的高度:

public static int getNavigationBarHeight() {

Resources resources = AppContext.getInstance().getResources();

int resourceId = resources.getIdentifier("navigation_bar_height",

"dimen", "android");

int height = resources.getDimensionPixelSize(resourceId);

return height;

}

這種方法得到的導航欄的高度數(shù)值是沒問題的,但是在全面屏的手機上,即使隱藏了導航欄,也是可以獲取到導航欄的高度的。通過上面的logcat日志可以看到,即使沒有導航欄,導航欄的高度的計算也是有值的。

適配小米mix虛擬導航欄

小米mix的機型中,我們可以“force_fsg_nav_bar”來判斷小米手機是否開啟了全面屏手勢。

public static int getHeightOfNavigationBar(Context context) {

//如果小米手機開啟了全面屏手勢隱藏了導航欄則返回 0

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {

if (Settings.Global.getInt(context.getContentResolver(),

"force_fsg_nav_bar", 0) != 0) {

return 0;

}

}

int realHeight = getScreenSize(context)[1];

Display d = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))

.getDefaultDisplay();

DisplayMetrics displayMetrics = new DisplayMetrics();

d.getMetrics(displayMetrics);

int displayHeight = displayMetrics.heightPixels;

return realHeight - displayHeight;

}

因此可以通過這個方法來判斷是否顯示了底部導航欄,并且可以計算導航欄的高度。

int navigationBarHeight = FullScreenManager.getHeightOfNavigationBar(MainActivity.this);

if (navigationBarHeight > 0){

container_navigationview.setVisibility(View.VISIBLE);

}else {

container_navigationview.setVisibility(View.GONE);

}

正常的顯示效果如下:

有虛擬導航欄

沒有虛擬導航欄

image

image

沒有虛擬導航欄Log

2018-10-08 13:19:32.389 /? D/shijiacheng: ==========================

2018-10-08 13:19:32.390 /? D/shijiacheng: DecorView height: 2160 px

2018-10-08 13:19:32.390 /? D/shijiacheng: Screen height: 2160 px

2018-10-08 13:19:32.390 /? D/shijiacheng: NativeBar height: 66 px

2018-10-08 13:19:32.390 /? D/shijiacheng: ContentView height: 2094 px

2018-10-08 13:19:32.390 /? D/shijiacheng: NavigationBar height: 0 px

2018-10-08 13:19:32.390 /? D/shijiacheng: --------------------------

有虛擬導航欄Log

2018-10-08 13:38:03.229 /? D/shijiacheng: ==========================

2018-10-08 13:38:03.230 /? D/shijiacheng: DecorView height: 2160 px

2018-10-08 13:38:03.230 /? D/shijiacheng: Screen height: 2160 px

2018-10-08 13:38:03.230 /? D/shijiacheng: NativeBar height: 66 px

2018-10-08 13:38:03.230 /? D/shijiacheng: ContentView height: 1964 px

2018-10-08 13:38:03.230 /? D/shijiacheng: NavigationBar height: 130 px

2018-10-08 13:38:03.230 /? D/shijiacheng: --------------------------

總結

以上是生活随笔為你收集整理的android 配置aspect_Android APP全面屏适配技术要点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 99久久久无码国产精品不卡 | 国产草草| 日韩欧美123 | 日韩少妇精品 | 日本中文不卡 | 黑人100部av解禁片 | 国产精品成人电影在线观看 | 中文字幕日韩精品亚洲一区小树林 | 亚洲欧美综合网 | 饥渴的少妇和男按摩师 | 手机av在线不卡 | 色一情一交一乱一区二区三区 | 一区二区三区四区在线视频 | 爱色成人网 | 香蕉久久综合 | 日本在线视频www | 欧美一级鲁丝片 | 69网站在线观看 | 日韩三级在线免费观看 | 国产日韩一区二区三区 | 又爽又黄又无遮挡 | 日本天堂在线视频 | 天天做天天爱天天做 | av在线播放免费 | 中文字幕乱码中文乱码b站 国产一区二区三区在线观看视频 | 亚洲va在线| 色天天av| 免费观看的av网站 | 欧美三日本三级少妇三99 | 最新av在线播放 | 亚洲精品视频久久久 | 台湾佬在线 | 国产三级91 | 大屁股白浆一区二区三区 | 国产精品视频99 | 日韩三级av在线 | 亚洲一级网站 | 99精品国产免费 | 亚洲性生活 | 69视频在线看 | 久久精品国产亚洲AV熟女 | 国产一区二区三区精品视频 | 日本高清视频www夜色资源 | 欧美日韩中文在线观看 | av无码久久久久久不卡网站 | 一区二区在线 | 性高潮视频在线观看 | 精品免费av | 国产成人综合亚洲 | 国产真实乱在线更新 | 欧美三级手机在线观看 | 艳母日本动漫在线观看 | 国产视频在线观看网站 | 日本免费网站在线观看 | 91精品国产麻豆国产自产在线 | 国产123在线 | 亚洲国产精品久久 | 国产xxxxxxxxx | 林天顾悦瑶笔趣阁 | 人人妻人人澡人人爽精品欧美一区 | 亚洲一区日韩精品 | ass极品水嫩小美女ass | 久久精品一区二区 | 天天插天天射天天干 | 99精品一级欧美片免费播放 | 91麻豆精品视频 | 欧美激情自拍偷拍 | 精品少妇一区二区三区在线观看 | 国产香蕉在线视频 | 女王脚交玉足榨精调教 | 成年网站在线播放 | 国产高清日韩 | 超碰免费在线观看 | 国产日本亚洲 | 好了av在线 | 国产精品视频一区二区三区 | 成人黄色视屏 | 日韩中文在线观看 | 91亚洲精品在线观看 | 成人在线观看你懂的 | 女厕厕露p撒尿八个少妇 | 亚洲精品美女视频 | 麻豆一区二区在线 | 日韩一区二区视频在线观看 | 伊人av综合 | 久久这里只有精品首页 | 男人av的天堂 | 黄色网页免费看 | avtt2015| 欧美在线视频免费 | 无码精品久久久久久久 | 牛牛澡牛牛爽一区二区 | 99久久婷婷| 亚洲伊人婷婷 | 国产浮力影院 | 作爱视频在线 | 久久视频免费看 | 久久综合中文 | 亚洲激情二区 |