日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导)

發(fā)布時(shí)間:2023/12/2 Android 67 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

來源:http://blog.csdn.net/zhaokaiqiang1992

更多:Android AutoLayout全新的適配方式, 堪稱適配終結(jié)者

?

Android的屏幕適配一直以來都在折磨著我們這些開發(fā)者,本篇文章以Google的官方文檔為基礎(chǔ),全面而深入的講解了Android屏幕適配的原因、重要概念、解決方案及最佳實(shí)踐,我相信如果你能認(rèn)真的學(xué)習(xí)本文,對于Android的屏幕適配,你將有所收獲!?

  • Android屏幕適配出現(xiàn)的原因
  • 重要概念
    • 屏幕尺寸
    • 屏幕分辨率
    • 屏幕像素密度
    • dpdipdpisppx
    • mdpihdpixdpixxdpi
  • 解決方案
    • 支持各種屏幕尺寸
      • 使用wrap_contentmatch_parentweight
      • 使用相對布局禁用絕對布局
      • 使用限定符
        • 使用尺寸限定符
        • 使用最小寬度限定符
        • 使用布局別名
        • 使用屏幕方向限定符
        • 使用自動(dòng)拉伸位圖
    • 支持各種屏幕密度
      • 使用非密度制約像素
      • 提供備用位圖
    • 實(shí)施自適應(yīng)用戶界面流程
      • 確定當(dāng)前布局
      • 根據(jù)當(dāng)前布局做出響應(yīng)
      • 重復(fù)使用其他活動(dòng)中的片段
      • 處理屏幕配置變化
    • 最佳實(shí)踐
      • 關(guān)于高清設(shè)計(jì)圖尺寸
      • ImageView的ScaleType屬性
      • 動(dòng)態(tài)設(shè)置
    • 更多參考資料

?

Android屏幕適配出現(xiàn)的原因

在我們學(xué)習(xí)如何進(jìn)行屏幕適配之前,我們需要先了解下為什么Android需要進(jìn)行屏幕適配。

由于Android系統(tǒng)的開放性,任何用戶、開發(fā)者、OEM廠商、運(yùn)營商都可以對Android進(jìn)行定制,修改成他們想要的樣子。

但是這種“碎片化”到底到達(dá)什么程度呢?

在2012年,OpenSignalMaps(以下簡稱OSM)發(fā)布了第一份Android碎片化報(bào)告,統(tǒng)計(jì)數(shù)據(jù)表明,

  • 2012年,支持Android的設(shè)備共有3997種。
  • 2013年,支持Android的設(shè)備共有11868種。
  • 2014年,支持Android的設(shè)備共有18796種。

下面這張圖片所顯示的內(nèi)容足以充分說明當(dāng)今Android系統(tǒng)碎片化問題的嚴(yán)重性,因?yàn)樵搱D片中的每一個(gè)矩形都代表著一種Android設(shè)備。

而隨著支持Android系統(tǒng)的設(shè)備(手機(jī)、平板、電視、手表)的增多,設(shè)備碎片化、品牌碎片化、系統(tǒng)碎片化、傳感器碎片化和屏幕碎片化的程度也在不斷地加深。而我們今天要探討的,則是對我們開發(fā)影響比較大的——屏幕的碎片化。

下面這張圖是Android屏幕尺寸的示意圖,在這張圖里面,藍(lán)色矩形的大小代表不同尺寸,顏色深淺則代表所占百分比的大小。

而與之相對應(yīng)的,則是下面這張圖。這張圖顯示了IOS設(shè)備所需要進(jìn)行適配的屏幕尺寸和占比。

當(dāng)然,這張圖片只是4,4s,5,5c,5s和平板的尺寸,現(xiàn)在還應(yīng)該加上新推出的iphone6和plus,但是和Android的屏幕碎片化程度相比而言,還是差的太遠(yuǎn)。

詳細(xì)的統(tǒng)計(jì)數(shù)據(jù)請到這里查看

現(xiàn)在你應(yīng)該很清楚為什么要對Android的屏幕進(jìn)行適配了吧?屏幕尺寸這么多,為了讓我們開發(fā)的程序能夠比較美觀的顯示在不同尺寸、分辨率、像素密度(這些概念我會在下面詳細(xì)講解)的設(shè)備上,那就要在開發(fā)的過程中進(jìn)行處理,至于如何去進(jìn)行處理,這就是我們今天的主題了。

但是在開始進(jìn)入主題之前,我們再來探討一件事情,那就是Android設(shè)備的屏幕尺寸,從幾寸的智能手機(jī),到10寸的平板電腦,再到幾十寸的數(shù)字電視,我們應(yīng)該適配哪些設(shè)備呢?

其實(shí)這個(gè)問題不應(yīng)該這么考慮,因?yàn)閷τ诰哂邢嗤袼孛芏鹊脑O(shè)備來說,像素越高,尺寸就越大,所以我們可以換個(gè)思路,將問題從單純的尺寸大小轉(zhuǎn)換到像素大小和像素密度的角度來。

下圖是2014年初,友盟統(tǒng)計(jì)的占比5%以上的6個(gè)主流分辨率,可以看出,占比最高的是480*800,320*480的設(shè)備竟然也占據(jù)了很大比例,但是和半年前的數(shù)據(jù)相比較,中低分辨率(320*480、480*800)的比例在減少,而中高分辨率的比例則在不斷地增加。雖然每個(gè)分辨率所占的比例在變化,但是總的趨勢沒變,還是這六種,只是分辨率在不斷地提高。

所以說,我們只要盡量適配這幾種分辨率,就可以在大部分的手機(jī)上正常運(yùn)行了。

當(dāng)然了,這只是手機(jī)的適配,對于平板設(shè)備(電視也可以看做是平板),我們還需要一些其他的處理。

好了,到目前為止,我們已經(jīng)弄清楚了Android開發(fā)為什么要進(jìn)行適配,以及我們應(yīng)該適配哪些對象,接下來,終于進(jìn)入我們的正題了!

首先,我們先要學(xué)習(xí)幾個(gè)重要的概念。

重要概念

什么是屏幕尺寸、屏幕分辨率、屏幕像素密度??
什么是dp、dip、dpi、sp、px?他們之間的關(guān)系是什么??
什么是mdpi、hdpi、xdpi、xxdpi?如何計(jì)算和區(qū)分?

在下面的內(nèi)容中我們將介紹這些概念。

屏幕尺寸

屏幕尺寸指屏幕的對角線的長度,單位是英寸,1英寸=2.54厘米

比如常見的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等

屏幕分辨率

屏幕分辨率是指在橫縱向上的像素點(diǎn)數(shù),單位是px,1px=1個(gè)像素點(diǎn)。一般以縱向像素*橫向像素,如1960*1080。

屏幕像素密度

屏幕像素密度是指每英寸上的像素點(diǎn)數(shù),單位是dpi,即“dot per inch”的縮寫。屏幕像素密度與屏幕尺寸和屏幕分辨率有關(guān),在單一變化條件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。

dp、dip、dpi、sp、px

px我們應(yīng)該是比較熟悉的,前面的分辨率就是用的像素為單位,大多數(shù)情況下,比如UI設(shè)計(jì)、Android原生API都會以px作為統(tǒng)一的計(jì)量單位,像是獲取屏幕寬高等。

dip和dp是一個(gè)意思,都是Density Independent Pixels的縮寫,即密度無關(guān)像素,上面我們說過,dpi是屏幕像素密度,假如一英寸里面有160個(gè)像素,這個(gè)屏幕的像素密度就是160dpi,那么在這種情況下,dp和px如何換算呢?在Android中,規(guī)定以160dpi為基準(zhǔn),1dip=1px,如果密度是320dpi,則1dip=2px,以此類推。

假如同樣都是畫一條320px的線,在480*800分辨率手機(jī)上顯示為2/3屏幕寬度,在320*480的手機(jī)上則占滿了全屏,如果使用dp為單位,在這兩種分辨率下,160dp都顯示為屏幕一半的長度。這也是為什么在Android開發(fā)中,寫布局的時(shí)候要盡量使用dp而不是px的原因。

而sp,即scale-independent pixels,與dp類似,但是可以根據(jù)文字大小首選項(xiàng)進(jìn)行放縮,是設(shè)置字體大小的御用單位。

mdpi、hdpi、xdpi、xxdpi

其實(shí)之前還有個(gè)ldpi,但是隨著移動(dòng)設(shè)備配置的不斷升級,這個(gè)像素密度的設(shè)備已經(jīng)很罕見了,所在現(xiàn)在適配時(shí)不需考慮。

mdpi、hdpi、xdpi、xxdpi用來修飾Android中的drawable文件夾及values文件夾,用來區(qū)分不同像素密度下的圖片和dimen值。

那么如何區(qū)分呢?Google官方指定按照下列標(biāo)準(zhǔn)進(jìn)行區(qū)分:

名稱像素密度范圍
mdpi120dpi~160dpi
hdpi160dpi~240dpi
xhdpi240dpi~320dpi
xxhdpi320dpi~480dpi
xxxhdpi480dpi~640dpi

在進(jìn)行開發(fā)的時(shí)候,我們需要把合適大小的圖片放在合適的文件夾里面。下面以圖標(biāo)設(shè)計(jì)為例進(jìn)行介紹。

在設(shè)計(jì)圖標(biāo)時(shí),對于五種主流的像素密度(MDPI、HDPI、XHDPI、XXHDPI 和 XXXHDPI)應(yīng)按照 2:3:4:6:8 的比例進(jìn)行縮放。例如,一個(gè)啟動(dòng)圖標(biāo)的尺寸為48x48 dp,這表示在 MDPI 的屏幕上其實(shí)際尺寸應(yīng)為 48x48 px,在 HDPI 的屏幕上其實(shí)際大小是 MDPI 的 1.5 倍 (72x72 px),在 XDPI 的屏幕上其實(shí)際大小是 MDPI 的 2 倍 (96x96 px),依此類推。

雖然 Android 也支持低像素密度 (LDPI) 的屏幕,但無需為此費(fèi)神,系統(tǒng)會自動(dòng)將 HDPI 尺寸的圖標(biāo)縮小到 1/2 進(jìn)行匹配。

下圖為圖標(biāo)的各個(gè)屏幕密度的對應(yīng)尺寸

屏幕密度圖標(biāo)尺寸
mdpi48x48px
hdpi72x72px
xhdpi96x96px
xxhdpi144x144px
xxxhdpi192x192px

解決方案

支持各種屏幕尺寸

使用wrap_content、match_parent、weight

要確保布局的靈活性并適應(yīng)各種尺寸的屏幕,應(yīng)使用 “wrap_content” 和 “match_parent” 控制某些視圖組件的寬度和高度。

使用 “wrap_content”,系統(tǒng)就會將視圖的寬度或高度設(shè)置成所需的最小尺寸以適應(yīng)視圖中的內(nèi)容,而 “match_parent”(在低于 API 級別 8 的級別中稱為 “fill_parent”)則會展開組件以匹配其父視圖的尺寸。

如果使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬編碼的尺寸,視圖就會相應(yīng)地僅使用自身所需的空間或展開以填滿可用空間。此方法可讓布局正確適應(yīng)各種屏幕尺寸和屏幕方向。

下面是一段示例代碼

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:id="@+id/linearLayout1" android:gravity="center" android:layout_height="50dp"> <ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/logo" android:paddingRight="30dp" android:layout_gravity="left" android:layout_weight="0" /> <View android:layout_height="wrap_content" android:id="@+id/view1" android:layout_width="wrap_content" android:layout_weight="1" /> <Button android:id="@+id/categorybutton" android:background="@drawable/button_bg" android:layout_height="match_parent" android:layout_weight="0" android:layout_width="120dp" style="@style/CategoryButtonStyle"/> </LinearLayout> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /> </LinearLayout>

?

?

下圖是在橫縱屏切換的時(shí)候的顯示效果,我們可以看到這樣可以很好的適配屏幕尺寸的變化。

weight是線性布局的一個(gè)獨(dú)特的屬性,我們可以使用這個(gè)屬性來按照比例對界面進(jìn)行分配,完成一些特殊的需求。

但是,我們對于這個(gè)屬性的計(jì)算應(yīng)該如何理解呢?

首先看下面的例子,我們在布局中這樣設(shè)置我們的界面

我們在布局里面設(shè)置為線性布局,橫向排列,然后放置兩個(gè)寬度為0dp的按鈕,分別設(shè)置weight為1和2,在效果圖中,我們可以看到兩個(gè)按鈕按照1:2的寬度比例正常排列了,這也是我們經(jīng)常使用到的場景,這是時(shí)候很好理解,Button1的寬度就是1/(1+2) = 1/3,Button2的寬度則是2/(1+2) = 2/3,我們可以很清楚的明白這種情景下的占比如何計(jì)算。

但是假如我們的寬度不是0dp(wrap_content和0dp的效果相同),則是match_parent呢?

下面是設(shè)置為match_parent的效果

我們可以看到,在這種情況下,占比和上面正好相反,這是怎么回事呢?說到這里,我們就不得不提一下weight的計(jì)算方法了。

android:layout_weight的真實(shí)含義是:如果View設(shè)置了該屬性并且有效,那么該 View的寬度等于原有寬度(android:layout_width)加上剩余空間的占比。

從這個(gè)角度我們來解釋一下上面的現(xiàn)象。在上面的代碼中,我們設(shè)置每個(gè)Button的寬度都是match_parent,假設(shè)屏幕寬度為L,那么每個(gè)Button的寬度也應(yīng)該都為L,剩余寬度就等于L-(L+L)= -L。

Button1的weight=1,剩余寬度占比為1/(1+2)= 1/3,所以最終寬度為L+1/3*(-L)=2/3L,Button2的計(jì)算類似,最終寬度為L+2/3(-L)=1/3L。

這是在水平方向上的,那么在垂直方向上也是這樣嗎?

下面是測試代碼和效果

如果是垂直方向,那么我們應(yīng)該改變的是layout_height的屬性,下面是0dp的顯示效果

下面是match_parent的顯示效果,結(jié)論和水平是完全一樣的

雖然說我們演示了match_parent的顯示效果,并說明了原因,但是在真正用的時(shí)候,我們都是設(shè)置某一個(gè)屬性為0dp,然后按照權(quán)重計(jì)算所占百分比。

使用相對布局,禁用絕對布局

在開發(fā)中,我們大部分時(shí)候使用的都是線性布局、相對布局和幀布局,絕對布局由于適配性極差,所以極少使用。

由于各種布局的特點(diǎn)不一樣,所以不能說哪個(gè)布局好用,到底應(yīng)該使用什么布局只能根據(jù)實(shí)際需求來確定。我們可以使用 LinearLayout 的嵌套實(shí)例并結(jié)合 “wrap_content” 和 “match_parent”,以便構(gòu)建相當(dāng)復(fù)雜的布局。不過,我們無法通過 LinearLayout 精確控制子視圖的特殊關(guān)系;系統(tǒng)會將 LinearLayout 中的視圖直接并排列出。

如果我們需要將子視圖排列出各種效果而不是一條直線,通常更合適的解決方法是使用 RelativeLayout,這樣就可以根據(jù)各組件之間的特殊關(guān)系指定布局了。例如,我們可以將某個(gè)子視圖對齊到屏幕左側(cè),同時(shí)將另一個(gè)視圖對齊到屏幕右側(cè)。

下面的代碼以官方Demo為例說明。

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/label" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Type here:"/> <EditText android:id="@+id/entry" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/label"/> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/entry" android:layout_alignParentRight="true" android:layout_marginLeft="10dp" android:text="OK" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/ok" android:layout_alignTop="@id/ok" android:text="Cancel" /> </RelativeLayout>

?

在上面的代碼中我們使用了相對布局,并且使用alignXXX等屬性指定了子控件的位置,下面是這種布局方式在應(yīng)對屏幕變化時(shí)的表現(xiàn)

在小尺寸屏幕的顯示

在平板的大尺寸上的顯示效果

雖然控件的大小由于屏幕尺寸的增加而發(fā)生了改變,但是我們可以看到,由于使用了相對布局,所以控件之前的位置關(guān)系并沒有發(fā)生什么變化,這說明我們的適配成功了。

使用限定符

使用尺寸限定符

上面所提到的靈活布局或者是相對布局,可以為我們帶來的優(yōu)勢就只有這么多了。雖然這些布局可以拉伸組件內(nèi)外的空間以適應(yīng)各種屏幕,但它們不一定能為每種屏幕都提供最佳的用戶體驗(yàn)。因此,我們的應(yīng)用不僅僅只實(shí)施靈活布局,還應(yīng)該應(yīng)針對各種屏幕配置提供一些備用布局。

如何做到這一點(diǎn)呢?我們可以通過使用配置限定符,在運(yùn)行時(shí)根據(jù)當(dāng)前的設(shè)備配置自動(dòng)選擇合適的資源了,例如根據(jù)各種屏幕尺寸選擇不同的布局。

很多應(yīng)用會在較大的屏幕上實(shí)施“雙面板”模式,即在一個(gè)面板上顯示項(xiàng)目列表,而在另一面板上顯示對應(yīng)內(nèi)容。平板電腦和電視的屏幕已經(jīng)大到可以同時(shí)容納這兩個(gè)面板了,但手機(jī)屏幕就需要分別顯示。因此,我們可以使用以下文件以便實(shí)施這些布局:

res/layout/main.xml,單面板(默認(rèn))布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /> </LinearLayout>

?

res/layout-large/main.xml,雙面板布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/> <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /> </LinearLayout>

?

請注意第二種布局名稱目錄中的 large 限定符。系統(tǒng)會在屬于較大屏幕(例如 7 英寸或更大的平板電腦)的設(shè)備上選擇此布局。系統(tǒng)會在較小的屏幕上選擇其他布局(無限定符)。

使用最小寬度限定符

在版本低于 3.2 的 Android 設(shè)備上,開發(fā)人員遇到的問題之一是“較大”屏幕的尺寸范圍,該問題會影響戴爾 Streak、早期的 Galaxy Tab 以及大部分 7 英寸平板電腦。即使這些設(shè)備的屏幕屬于“較大”的尺寸,但很多應(yīng)用可能會針對此類別中的各種設(shè)備(例如 5 英寸和 7 英寸的設(shè)備)顯示不同的布局。這就是 Android 3.2 版在引入其他限定符的同時(shí)引入“最小寬度”限定符的原因。

最小寬度限定符可讓您通過指定某個(gè)最小寬度(以 dp 為單位)來定位屏幕。例如,標(biāo)準(zhǔn) 7 英寸平板電腦的最小寬度為 600 dp,因此如果您要在此類屏幕上的用戶界面中使用雙面板(但在較小的屏幕上只顯示列表),您可以使用上文中所述的單面板和雙面板這兩種布局,但您應(yīng)使用 sw600dp 指明雙面板布局僅適用于最小寬度為 600 dp 的屏幕,而不是使用 large 尺寸限定符。

res/layout/main.xml,單面板(默認(rèn))布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /> </LinearLayout>

?

?

res/layout-sw600dp/main.xml,雙面板布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/> <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /> </LinearLayout>

?

?

也就是說,對于最小寬度大于等于 600 dp 的設(shè)備,系統(tǒng)會選擇 layout-sw600dp/main.xml(雙面板)布局,否則系統(tǒng)就會選擇 layout/main.xml(單面板)布局。

但 Android 版本低于 3.2 的設(shè)備不支持此技術(shù),原因是這些設(shè)備無法將 sw600dp 識別為尺寸限定符,因此我們?nèi)孕枋褂?large 限定符。這樣一來,就會有一個(gè)名稱為 res/layout-large/main.xml 的文件(與 res/layout-sw600dp/main.xml 一樣)。但是沒有太大關(guān)系,我們將馬上學(xué)習(xí)如何避免此類布局文件出現(xiàn)的重復(fù)。

使用布局別名

最小寬度限定符僅適用于 Android 3.2 及更高版本。因此,如果我們?nèi)孕枋褂门c較低版本兼容的概括尺寸范圍(小、正常、大和特大)。例如,如果要將用戶界面設(shè)計(jì)成在手機(jī)上顯示單面板,但在 7 英寸平板電腦、電視和其他較大的設(shè)備上顯示多面板,那么我們就需要提供以下文件:

  • res/layout/main.xml: 單面板布局
  • res/layout-large: 多面板布局
  • res/layout-sw600dp: 多面板布局

后兩個(gè)文件是相同的,因?yàn)槠渲幸粋€(gè)用于和 Android 3.2 設(shè)備匹配,而另一個(gè)則是為使用較低版本 Android 的平板電腦和電視準(zhǔn)備的。

要避免平板電腦和電視的文件出現(xiàn)重復(fù)(以及由此帶來的維護(hù)問題),您可以使用別名文件。例如,您可以定義以下布局:

  • res/layout/main.xml,單面板布局
  • res/layout/main_twopanes.xml,雙面板布局

然后添加這兩個(gè)文件:

res/values-large/layout.xml:

<resources><item name="main" type="layout">@layout/main_twopanes</item> </resources>

?

?

res/values-sw600dp/layout.xml:

<resources><item name="main" type="layout">@layout/main_twopanes</item> </resources>

?

后兩個(gè)文件的內(nèi)容相同,但它們并未實(shí)際定義布局。它們只是將 main 設(shè)置成了 main_twopanes 的別名。由于這些文件包含 large 和 sw600dp 選擇器,因此無論 Android 版本如何,系統(tǒng)都會將這些文件應(yīng)用到平板電腦和電視上(版本低于 3.2 的平板電腦和電視會匹配 large,版本高于 3.2 的平板電腦和電視則會匹配 sw600dp)。

使用屏幕方向限定符

某些布局會同時(shí)支持橫向模式和縱向模式,但我們可以通過調(diào)整優(yōu)化其中大部分布局的效果。在新聞閱讀器示例應(yīng)用中,每種屏幕尺寸和屏幕方向下的布局行為方式如下所示:

  • 小屏幕,縱向:單面板,帶徽標(biāo)
  • 小屏幕,橫向:單面板,帶徽標(biāo)
  • 7 英寸平板電腦,縱向:單面板,帶操作欄
  • 7 英寸平板電腦,橫向:雙面板,寬,帶操作欄
  • 10 英寸平板電腦,縱向:雙面板,窄,帶操作欄
  • 10 英寸平板電腦,橫向:雙面板,寬,帶操作欄
  • 電視,橫向:雙面板,寬,帶操作欄

因此,這些布局中的每一種都定義在了 res/layout/ 目錄下的某個(gè) XML 文件中。為了繼續(xù)將每個(gè)布局分配給各種屏幕配置,該應(yīng)用會使用布局別名將兩者相匹配:

res/layout/onepane.xml:(單面板)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /> </LinearLayout>

?

?

res/layout/onepane_with_bar.xml:(單面板帶操作欄)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:id="@+id/linearLayout1" android:gravity="center" android:layout_height="50dp"> <ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/logo" android:paddingRight="30dp" android:layout_gravity="left" android:layout_weight="0" /> <View android:layout_height="wrap_content" android:id="@+id/view1" android:layout_width="wrap_content" android:layout_weight="1" /> <Button android:id="@+id/categorybutton" android:background="@drawable/button_bg" android:layout_height="match_parent" android:layout_weight="0" android:layout_width="120dp" style="@style/CategoryButtonStyle"/> </LinearLayout> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" /> </LinearLayout>

?

?

res/layout/twopanes.xml:(雙面板,寬布局)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/> <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /> </LinearLayout>

?

?

res/layout/twopanes_narrow.xml:(雙面板,窄布局)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="200dp" android:layout_marginRight="10dp"/> <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /> </LinearLayout>

?

?

既然我們已定義了所有可能的布局,那就只需使用配置限定符將正確的布局映射到各種配置即可。

現(xiàn)在只需使用布局別名技術(shù)即可做到這一點(diǎn):

res/values/layouts.xml:

<resources><item name="main_layout" type="layout">@layout/onepane_with_bar</item> <bool name="has_two_panes">false</bool> </resources>

?

?

res/values-sw600dp-land/layouts.xml:

<resources><item name="main_layout" type="layout">@layout/twopanes</item> <bool name="has_two_panes">true</bool> </resources>

?

?

res/values-sw600dp-port/layouts.xml:

<resources><item name="main_layout" type="layout">@layout/onepane</item> <bool name="has_two_panes">false</bool> </resources>

?

?

res/values-large-land/layouts.xml:

<resources><item name="main_layout" type="layout">@layout/twopanes</item> <bool name="has_two_panes">true</bool> </resources>

?

?

res/values-large-port/layouts.xml:

<resources><item name="main_layout" type="layout">@layout/twopanes_narrow</item> <bool name="has_two_panes">true</bool> </resources>

?

?

使用自動(dòng)拉伸位圖

支持各種屏幕尺寸通常意味著您的圖片資源還必須能適應(yīng)各種尺寸。例如,無論要應(yīng)用到什么形狀的按鈕上,按鈕背景都必須能適應(yīng)。

如果在可以更改尺寸的組件上使用了簡單的圖片,您很快就會發(fā)現(xiàn)顯示效果多少有些不太理想,因?yàn)橄到y(tǒng)會在運(yùn)行時(shí)平均地拉伸或收縮您的圖片。解決方法為使用自動(dòng)拉伸位圖,這是一種格式特殊的 PNG 文件,其中會指明可以拉伸以及不可以拉伸的區(qū)域。

.9的制作,實(shí)際上就是在原圖片上添加1px的邊界,然后按照我們的需求,把對應(yīng)的位置設(shè)置成黑色線,系統(tǒng)就會根據(jù)我們的實(shí)際需求進(jìn)行拉伸。

下圖是對.9圖的四邊的含義的解釋,左上邊代表拉伸區(qū)域,右下邊代表padding box,就是間隔區(qū)域,在下面,我們給出一個(gè)例子,方便大家理解。

先看下面兩張圖,我們理解一下這四條線的含義。

上圖和下圖的區(qū)別,就在于右下邊的黑線不一樣,具體的效果的區(qū)別,看右邊的效果圖。上圖效果圖中深藍(lán)色的區(qū)域,代表內(nèi)容區(qū)域,我們可以看到是在正中央的,這是因?yàn)槲覀冊谟蚁逻叺氖莾蓚€(gè)點(diǎn),這兩個(gè)點(diǎn)距離上下左右四個(gè)方向的距離就是padding的距離,所以深藍(lán)色內(nèi)容區(qū)域在圖片正中央,我們再看下圖,由于右下邊的黑線是圖片長度,所以就沒有padding,從效果圖上的表現(xiàn)就是深藍(lán)色區(qū)域和圖片一樣大,因此,我們可以利用右下邊來控制內(nèi)容與背景圖邊緣的padding。

如果你還不明白,那么我們看下面的效果圖,我們分別以圖一和圖二作為背景圖,下面是效果圖。

我們可以看到,使用wrap_content屬性設(shè)置長寬,圖一比圖二的效果大一圈,這是為什么呢?還記得我上面說的padding嗎?

這就是padding的效果提現(xiàn),怎么證明呢?我們再看下面一張圖,給圖一添加padding=0,這樣背景圖設(shè)置的padding效果就沒了,是不是兩個(gè)一樣大了?

ok,我想你應(yīng)該明白右下邊的黑線的含義了,下面我們再看一下左上邊的效果。

下面我們只設(shè)置了左上邊線,效果圖如下

上面的線沒有包住圖標(biāo),下面的線正好包住了圖標(biāo),從右邊的效果圖應(yīng)該可以看出差別,黑線所在的區(qū)域就是拉伸區(qū)域,上圖黑線所在的全是純色,所以圖標(biāo)不變形,下面的拉伸區(qū)域包裹了圖標(biāo),所以在拉伸的時(shí)候就會對圖標(biāo)進(jìn)行拉伸,但是這樣就會導(dǎo)致圖標(biāo)變形。注意到下面紅線區(qū)域了嘛?這是系統(tǒng)提示我們的,因?yàn)檫@樣拉伸,不符合要求,所以會提示一下。

支持各種屏幕密度

使用非密度制約像素

由于各種屏幕的像素密度都有所不同,因此相同數(shù)量的像素在不同設(shè)備上的實(shí)際大小也有所差異,這樣使用像素定義布局尺寸就會產(chǎn)生問題。因此,請務(wù)必使用 dp 或 sp 單位指定尺寸。dp 是一種非密度制約像素,其尺寸與 160 dpi 像素的實(shí)際尺寸相同。sp 也是一種基本單位,但它可根據(jù)用戶的偏好文字大小進(jìn)行調(diào)整(即尺度獨(dú)立性像素),因此我們應(yīng)將該測量單位用于定義文字大小。

例如,請使用 dp(而非 px)指定兩個(gè)視圖間的間距:

<Button android:layout_width="wrap_content"android:layout_height="wrap_content" android:text="@string/clickme" android:layout_marginTop="20dp" />

?

?

請務(wù)必使用 sp 指定文字大小:

<TextView android:layout_width="match_parent"android:layout_height="wrap_content" android:textSize="20sp" />

?

除了介紹這些最基礎(chǔ)的知識之外,我們下面再來討論一下另外一個(gè)問題。

經(jīng)過上面的介紹,我們都清楚,為了能夠規(guī)避不同像素密度的陷阱,Google推薦使用dp來代替px作為控件長度的度量單位,但是我們來看下面的一個(gè)場景。

假如我們以Nexus5作為書寫代碼時(shí)查看效果的測試機(jī)型,Nexus5的總寬度為360dp,我們現(xiàn)在需要在水平方向上放置兩個(gè)按鈕,一個(gè)是150dp左對齊,另外一個(gè)是200dp右對齊,中間留有10dp間隔,那么在Nexus5上面的顯示效果就是下面這樣

但是如果在Nexus S或者是Nexus One運(yùn)行呢?下面是運(yùn)行結(jié)果

可以看到,兩個(gè)按鈕發(fā)生了重疊。

我們都已經(jīng)用了dp了,為什么會出現(xiàn)這種情況呢?

你聽我慢慢道來。

雖然說dp可以去除不同像素密度的問題,使得1dp在不同像素密度上面的顯示效果相同,但是還是由于Android屏幕設(shè)備的多樣性,如果使用dp來作為度量單位,并不是所有的屏幕的寬度都是相同的dp長度,比如說,Nexus S和Nexus One屬于hdpi,屏幕寬度是320dp,而Nexus 5屬于xxhdpi,屏幕寬度是360dp,Galaxy Nexus屬于xhdpi,屏幕寬度是384dp,Nexus 6 屬于xxxhdpi,屏幕寬度是410dp。所以說,光Google自己一家的產(chǎn)品就已經(jīng)有這么多的標(biāo)準(zhǔn),而且屏幕寬度和像素密度沒有任何關(guān)聯(lián)關(guān)系,即使我們使用dp,在320dp寬度的設(shè)備和410dp的設(shè)備上,還是會有90dp的差別。當(dāng)然,我們盡量使用match_parent和wrap_content,盡可能少的用dp來指定控件的具體長寬,再結(jié)合上權(quán)重,大部分的情況我們都是可以做到適配的。

但是除了這個(gè)方法,我們還有沒有其他的更徹底的解決方案呢?

我們換另外一個(gè)思路來思考這個(gè)問題。

下面的方案來自Android Day Day Up 一群的【blue-深圳】,謝謝他的分享精神

因?yàn)榉直媛什灰粯?#xff0c;所以不能用px;因?yàn)槠聊粚挾炔灰粯?#xff0c;所以要小心的用dp,那么我們可不可以用另外一種方法來統(tǒng)一單位,不管分辨率是多大,屏幕寬度用一個(gè)固定的值的單位來統(tǒng)計(jì)呢?

答案是:當(dāng)然可以。

我們假設(shè)手機(jī)屏幕的寬度都是320某單位,那么我們將一個(gè)屏幕寬度的總像素?cái)?shù)平均分成320份,每一份對應(yīng)具體的像素就可以了。

具體如何來實(shí)現(xiàn)呢?我們看下面的代碼

import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter;public class MakeXml { private final static String rootPath = "C:\\Users\\Administrator\\Desktop\\layoutroot\\values-{0}x{1}\\"; private final static float dw = 320f; private final static float dh = 480f; private final static String WTemplate = "<dimen name=\"x{0}\">{1}px</dimen>\n"; private final static String HTemplate = "<dimen name=\"y{0}\">{1}px</dimen>\n"; public static void main(String[] args) { makeString(320, 480); makeString(480,800); makeString(480, 854); makeString(540, 960); makeString(600, 1024); makeString(720, 1184); makeString(720, 1196); makeString(720, 1280); makeString(768, 1024); makeString(800, 1280); makeString(1080, 1812); makeString(1080, 1920); makeString(1440, 2560); } public static void makeString(int w, int h) { StringBuffer sb = new StringBuffer(); sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); sb.append("<resources>"); float cellw = w / dw; for (int i = 1; i < 320; i++) { sb.append(WTemplate.replace("{0}", i + "").replace("{1}", change(cellw * i) + "")); } sb.append(WTemplate.replace("{0}", "320").replace("{1}", w + "")); sb.append("</resources>"); StringBuffer sb2 = new StringBuffer(); sb2.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); sb2.append("<resources>"); float cellh = h / dh; for (int i = 1; i < 480; i++) { sb2.append(HTemplate.replace("{0}", i + "").replace("{1}", change(cellh * i) + "")); } sb2.append(HTemplate.replace("{0}", "480").replace("{1}", h + "")); sb2.append("</resources>"); String path = rootPath.replace("{0}", h + "").replace("{1}", w + ""); File rootFile = new File(path); if (!rootFile.exists()) { rootFile.mkdirs(); } File layxFile = new File(path + "lay_x.xml"); File layyFile = new File(path + "lay_y.xml"); try { PrintWriter pw = new PrintWriter(new FileOutputStream(layxFile)); pw.print(sb.toString()); pw.close(); pw = new PrintWriter(new FileOutputStream(layyFile)); pw.print(sb2.toString()); pw.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } } public static float change(float a) { int temp = (int) (a * 100); return temp / 100f; } }

?

?

代碼應(yīng)該很好懂,我們將一個(gè)屏幕寬度分為320份,高度480份,然后按照實(shí)際像素對每一個(gè)單位進(jìn)行復(fù)制,放在對應(yīng)values-widthxheight文件夾下面的lax.xml和lay.xml里面,這樣就可以統(tǒng)一所有你想要的分辨率的單位了,下面是生成的一個(gè)320*480分辨率的文件,因?yàn)閷捀叻指钪罂偡謹(jǐn)?shù)和像素?cái)?shù)相同,所以x1就是1px,以此類推

<?xml version="1.0" encoding="utf-8"?> <resources><dimen name="x1">1.0px</dimen> <dimen name="x2">2.0px</dimen> <dimen name="x3">3.0px</dimen> <dimen name="x4">4.0px</dimen> <dimen name="x5">5.0px</dimen> <dimen name="x6">6.0px</dimen> <dimen name="x7">7.0px</dimen> <dimen name="x8">8.0px</dimen> <dimen name="x9">9.0px</dimen> <dimen name="x10">10.0px</dimen> ...省略好多行 <dimen name="x300">300.0px</dimen> <dimen name="x301">301.0px</dimen> <dimen name="x302">302.0px</dimen> <dimen name="x303">303.0px</dimen> <dimen name="x304">304.0px</dimen> <dimen name="x305">305.0px</dimen> <dimen name="x306">306.0px</dimen> <dimen name="x307">307.0px</dimen> <dimen name="x308">308.0px</dimen> <dimen name="x309">309.0px</dimen> <dimen name="x310">310.0px</dimen> <dimen name="x311">311.0px</dimen> <dimen name="x312">312.0px</dimen> <dimen name="x313">313.0px</dimen> <dimen name="x314">314.0px</dimen> <dimen name="x315">315.0px</dimen> <dimen name="x316">316.0px</dimen> <dimen name="x317">317.0px</dimen> <dimen name="x318">318.0px</dimen> <dimen name="x319">319.0px</dimen> <dimen name="x320">320px</dimen> </resources>

?

?

那么1080*1960分辨率下是什么樣子呢?我們可以看下,由于1080和320是3.37倍的關(guān)系,所以x1=3.37px

<?xml version="1.0" encoding="utf-8"?> <resources><dimen name="x1">3.37px</dimen> <dimen name="x2">6.75px</dimen> <dimen name="x3">10.12px</dimen> <dimen name="x4">13.5px</dimen> <dimen name="x5">16.87px</dimen> <dimen name="x6">20.25px</dimen> <dimen name="x7">23.62px</dimen> <dimen name="x8">27.0px</dimen> <dimen name="x9">30.37px</dimen> <dimen name="x10">33.75px</dimen> ...省略好多行 <dimen name="x300">1012.5px</dimen> <dimen name="x301">1015.87px</dimen> <dimen name="x302">1019.25px</dimen> <dimen name="x303">1022.62px</dimen> <dimen name="x304">1026.0px</dimen> <dimen name="x305">1029.37px</dimen> <dimen name="x306">1032.75px</dimen> <dimen name="x307">1036.12px</dimen> <dimen name="x308">1039.5px</dimen> <dimen name="x309">1042.87px</dimen> <dimen name="x310">1046.25px</dimen> <dimen name="x311">1049.62px</dimen> <dimen name="x312">1053.0px</dimen> <dimen name="x313">1056.37px</dimen> <dimen name="x314">1059.75px</dimen> <dimen name="x315">1063.12px</dimen> <dimen name="x316">1066.5px</dimen> <dimen name="x317">1069.87px</dimen> <dimen name="x318">1073.25px</dimen> <dimen name="x319">1076.62px</dimen> <dimen name="x320">1080px</dimen> </resources>

?

?

無論在什么分辨率下,x320都是代表屏幕寬度,y480都是代表屏幕高度。

那么,我們應(yīng)該如何使用呢?

首先,我們要把生成的所有values文件夾放到res目錄下,當(dāng)設(shè)計(jì)師把UI高清設(shè)計(jì)圖給你之后,你就可以根據(jù)設(shè)計(jì)圖上的尺寸,以某一個(gè)分辨率的機(jī)型為基礎(chǔ),找到對應(yīng)像素?cái)?shù)的單位,然后設(shè)置給控件即可。

下圖還是兩個(gè)Button,不同的是,我們把單位換成了我們在values文件夾下dimen的值,這樣在你指定的分辨率下,不管寬度是320dp、360dp,還是410dp,就都可以完全適配了。

但是,還是有個(gè)問題,為什么下面的三個(gè)沒有適配呢?

這是因?yàn)橛捎谠谏傻膙alues文件夾里,沒有對應(yīng)的分辨率,其實(shí)一開始是報(bào)錯(cuò)的,因?yàn)槟J(rèn)的values沒有對應(yīng)dimen,所以我只能在默認(rèn)values里面也創(chuàng)建對應(yīng)文件,但是里面的數(shù)據(jù)卻不好處理,因?yàn)椴恢婪直媛?#xff0c;我只好默認(rèn)為x1=1dp保證盡量兼容。這也是這個(gè)解決方案的幾個(gè)弊端,對于沒有生成對應(yīng)分辨率文件的手機(jī),會使用默認(rèn)values文件夾,如果默認(rèn)文件夾沒有,就會出現(xiàn)問題。

所以說,這個(gè)方案雖然是一勞永逸,但是由于實(shí)際上還是使用的px作為長度的度量單位,所以多少和google的要求有所背離,不好說以后會不會出現(xiàn)什么不可預(yù)測的問題。其次,如果要使用這個(gè)方案,你必須盡可能多的包含所有的分辨率,因?yàn)檫@個(gè)是使用這個(gè)方案的基礎(chǔ),如果有分辨率缺少,會造成顯示效果很差,甚至出錯(cuò)的風(fēng)險(xiǎn),而這又勢必會增加軟件包的大小和維護(hù)的難度,所以大家自己斟酌,擇優(yōu)使用。

更多信息可參考鴻洋的新文章Android 屏幕適配方案

提供備用位圖

由于 Android 可在具有各種屏幕密度的設(shè)備上運(yùn)行,因此我們提供的位圖資源應(yīng)始終可以滿足各類普遍密度范圍的要求:低密度、中等密度、高密度以及超高密度。這將有助于我們的圖片在所有屏幕密度上都能得到出色的質(zhì)量和效果。

要生成這些圖片,我們應(yīng)先提取矢量格式的原始資源,然后根據(jù)以下尺寸范圍針對各密度生成相應(yīng)的圖片。

  • xhdpi:2.0
  • hdpi:1.5
  • mdpi:1.0(最低要求)
  • ldpi:0.75

也就是說,如果我們?yōu)?xhdpi 設(shè)備生成了 200x200 px尺寸的圖片,就應(yīng)該使用同一資源為 hdpi、mdpi 和 ldpi 設(shè)備分別生成 150x150、100x100 和 75x75 尺寸的圖片。

然后,將生成的圖片文件放在 res/ 下的相應(yīng)子目錄中(mdpi、hdpi、xhdpi、xxhdpi),系統(tǒng)就會根據(jù)運(yùn)行您應(yīng)用的設(shè)備的屏幕密度自動(dòng)選擇合適的圖片。

這樣一來,只要我們引用 @drawable/id,系統(tǒng)都能根據(jù)相應(yīng)屏幕的 dpi 選取合適的位圖。

還記得我們上面提到的圖標(biāo)設(shè)計(jì)尺寸嗎?和這個(gè)其實(shí)是一個(gè)意思。

但是還有個(gè)問題需要注意下,如果是.9圖或者是不需要多個(gè)分辨率的圖片,就放在drawable文件夾即可,對應(yīng)分辨率的圖片要正確的放在合適的文件夾,否則會造成圖片拉伸等問題。

實(shí)施自適應(yīng)用戶界面流程

前面我們介紹過,如何根據(jù)設(shè)備特點(diǎn)顯示恰當(dāng)?shù)牟季?#xff0c;但是這樣做,會使得用戶界面流程可能會有所不同。例如,如果應(yīng)用處于雙面板模式下,點(diǎn)擊左側(cè)面板上的項(xiàng)即可直接在右側(cè)面板上顯示相關(guān)內(nèi)容;而如果該應(yīng)用處于單面板模式下,點(diǎn)擊相關(guān)的內(nèi)容應(yīng)該跳轉(zhuǎn)到另外一個(gè)Activity進(jìn)行后續(xù)的處理。所以我們應(yīng)該按照下面的流程,一步步的完成自適應(yīng)界面的實(shí)現(xiàn)。

確定當(dāng)前布局

由于每種布局的實(shí)施都會稍有不同,因此我們需要先確定當(dāng)前向用戶顯示的布局。例如,我們可以先了解用戶所處的是“單面板”模式還是“雙面板”模式。要做到這一點(diǎn),可以通過查詢指定視圖是否存在以及是否已顯示出來。

public class NewsReaderActivity extends FragmentActivity { boolean mIsDualPane; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); View articleView = findViewById(R.id.article); mIsDualPane = articleView != null && articleView.getVisibility() == View.VISIBLE; } }

?

?

請注意,這段代碼用于查詢“報(bào)道”面板是否可用,與針對具體布局的硬編碼查詢相比,這段代碼的靈活性要大得多。

再舉一個(gè)適應(yīng)各種組件的存在情況的方法示例:在對這些組件執(zhí)行操作前先查看它們是否可用。例如,新聞閱讀器示例應(yīng)用中有一個(gè)用于打開菜單的按鈕,但只有在版本低于 3.0 的 Android 上運(yùn)行該應(yīng)用時(shí),這個(gè)按鈕才會存在,因?yàn)?API 級別 11 或更高級別中的 ActionBar 已取代了該按鈕的功能。因此,您可以使用以下代碼為此按鈕添加事件偵聽器:

Button catButton = (Button) findViewById(R.id.categorybutton); OnClickListener listener = /* create your listener here */; if (catButton != null) { catButton.setOnClickListener(listener); }

?

?

?

根據(jù)當(dāng)前布局做出響應(yīng)

有些操作可能會因當(dāng)前的具體布局而產(chǎn)生不同的結(jié)果。例如,在新聞閱讀器示例中,如果用戶界面處于雙面板模式下,那么點(diǎn)擊標(biāo)題列表中的標(biāo)題就會在右側(cè)面板中打開相應(yīng)報(bào)道;但如果用戶界面處于單面板模式下,那么上述操作就會啟動(dòng)一個(gè)獨(dú)立活動(dòng):

@Override public void onHeadlineSelected(int index) {mArtIndex = index; if (mIsDualPane) { /* display article on the right pane */ mArticleFragment.displayArticle(mCurrentCat.getArticle(index)); } else { /* start a separate activity */ Intent intent = new Intent(this, ArticleActivity.class); intent.putExtra("catIndex", mCatIndex); intent.putExtra("artIndex", index); startActivity(intent); } }

?

?

同樣,如果該應(yīng)用處于雙面板模式下,就應(yīng)設(shè)置帶導(dǎo)航標(biāo)簽的操作欄;但如果該應(yīng)用處于單面板模式下,就應(yīng)使用下拉菜單設(shè)置導(dǎo)航欄。因此我們的代碼還應(yīng)確定哪種情況比較合適:

final String CATEGORIES[] = { "熱門報(bào)道", "政治", "經(jīng)濟(jì)", "Technology" }; public void onCreate(Bundle savedInstanceState) { .... if (mIsDualPane) { /* use tabs for navigation */ actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_TABS); int i; for (i = 0; i < CATEGORIES.length; i++) { actionBar.addTab(actionBar.newTab().setText( CATEGORIES[i]).setTabListener(handler)); } actionBar.setSelectedNavigationItem(selTab); } else { /* use list navigation (spinner) */ actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_LIST); SpinnerAdapter adap = new ArrayAdapter(this, R.layout.headline_item, CATEGORIES); actionBar.setListNavigationCallbacks(adap, handler); } }

?

?

重復(fù)使用其他活動(dòng)中的片段

多屏幕設(shè)計(jì)中的重復(fù)模式是指,對于某些屏幕配置,已實(shí)施界面的一部分會用作面板;但對于其他配置,這部分就會以獨(dú)立活動(dòng)的形式存在。例如,在新聞閱讀器示例中,對于較大的屏幕,新聞報(bào)道文本會顯示在右側(cè)面板中;但對于較小的屏幕,這些文本就會以獨(dú)立活動(dòng)的形式存在。

在類似情況下,通常可以在多個(gè)活動(dòng)中重復(fù)使用相同的 Fragment 子類以避免代碼重復(fù)。例如,在雙面板布局中使用了 ArticleFragment:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <fragment android:id="@+id/headlines" android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/> <fragment android:id="@+id/article" android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" /> </LinearLayout>

?

?

然后又在小屏幕的Activity布局中重復(fù)使用了它 :

ArticleFragment frag = new ArticleFragment(); getSupportFragmentManager().beginTransaction().add(android.R.id.content, frag).commit();

?

?

當(dāng)然,這與在 XML 布局中聲明片段的效果是一樣的,但在這種情況下卻沒必要使用 XML 布局,因?yàn)閳?bào)道片段是此活動(dòng)中的唯一組件。

請務(wù)必在設(shè)計(jì)片段時(shí)注意,不要針對具體活動(dòng)創(chuàng)建強(qiáng)耦合。要做到這一點(diǎn),通常可以定義一個(gè)接口,該接口概括了相關(guān)片段與其主活動(dòng)交互所需的全部方式,然后讓主活動(dòng)實(shí)施該界面:

例如,新聞閱讀器應(yīng)用的 HeadlinesFragment 會精確執(zhí)行以下代碼:

public class HeadlinesFragment extends ListFragment { ... OnHeadlineSelectedListener mHeadlineSelectedListener = null; /* Must be implemented by host activity */ public interface OnHeadlineSelectedListener { public void onHeadlineSelected(int index); } ... public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener listener) { mHeadlineSelectedListener = listener; } }

?

?

然后,如果用戶選擇某個(gè)標(biāo)題,相關(guān)片段就會通知由主活動(dòng)指定的偵聽器(而不是通知某個(gè)硬編碼的具體活動(dòng)):

public class HeadlinesFragment extends ListFragment { ... @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (null != mHeadlineSelectedListener) { mHeadlineSelectedListener.onHeadlineSelected(position); } } ... }

?

?

除此之外,我們還可以使用第三方框架,比如說使用“訂閱-發(fā)布”模式的EventBus來更多的優(yōu)化組件之間的通信,減少耦合。

處理屏幕配置變化

如果我們使用獨(dú)立Activity實(shí)施界面的獨(dú)立部分,那么請注意,我們可能需要對特定配置變化(例如屏幕方向的變化)做出響應(yīng),以便保持界面的一致性。

例如,在運(yùn)行 Android 3.0 或更高版本的標(biāo)準(zhǔn) 7 英寸平板電腦上,如果新聞閱讀器示例應(yīng)用運(yùn)行在縱向模式下,就會在使用獨(dú)立活動(dòng)顯示新聞報(bào)道;但如果該應(yīng)用運(yùn)行在橫向模式下,就會使用雙面板布局。

也就是說,如果用戶處于縱向模式下且屏幕上顯示的是用于閱讀報(bào)道的活動(dòng),那么就需要在檢測到屏幕方向變化(變成橫向模式)后執(zhí)行相應(yīng)操作,即停止上述活動(dòng)并返回主活動(dòng),以便在雙面板布局中顯示相關(guān)內(nèi)容:

public class ArticleActivity extends FragmentActivity { int mCatIndex, mArtIndex; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCatIndex = getIntent().getExtras().getInt("catIndex", 0); mArtIndex = getIntent().getExtras().getInt("artIndex", 0); // If should be in two-pane mode, finish to return to main activity if (getResources().getBoolean(R.bool.has_two_panes)) { finish(); return; } ... }

?

?

通過上面幾個(gè)步驟,我們就完全可以建立一個(gè)可以根據(jù)用戶界面配置進(jìn)行自適應(yīng)的App了。

最佳實(shí)踐

關(guān)于高清設(shè)計(jì)圖尺寸

Google官方給出的高清設(shè)計(jì)圖尺寸有兩種方案,一種是以mdpi設(shè)計(jì),然后對應(yīng)放大得到更高分辨率的圖片,另外一種則是以高分辨率作為設(shè)計(jì)大小,然后按照倍數(shù)對應(yīng)縮小到小分辨率的圖片。

根據(jù)經(jīng)驗(yàn),我更推薦第二種方法,因?yàn)樾》直媛试谏筛叻直媛蕡D片的時(shí)候,會出現(xiàn)像素丟失,我不知道是不是有方法可以阻止這種情況發(fā)生。

而分辨率可以以1280*720或者是1960*1080作為主要分辨率進(jìn)行設(shè)計(jì)。

ImageView的ScaleType屬性

設(shè)置不同的ScaleType會得到不同的顯示效果,一般情況下,設(shè)置為centerCrop能獲得較好的適配效果。

動(dòng)態(tài)設(shè)置

有一些情況下,我們需要?jiǎng)討B(tài)的設(shè)置控件大小或者是位置,比如說popwindow的顯示位置和偏移量等,這個(gè)時(shí)候我們可以動(dòng)態(tài)的獲取當(dāng)前的屏幕屬性,然后設(shè)置合適的數(shù)值

public class ScreenSizeUtil {public static int getScreenWidth(Activity activity) { return activity.getWindowManager().getDefaultDisplay().getWidth(); } public static int getScreenHeight(Activity activity) { return activity.getWindowManager().getDefaultDisplay().getHeight(); } }

?

?

更多參考資料

  • chan奕迅(設(shè)計(jì)師角度)
  • 友盟移動(dòng)指數(shù)(最新的移動(dòng)設(shè)備統(tǒng)計(jì)信息)
  • 手機(jī)屏幕信息大全

轉(zhuǎn)載于:https://www.cnblogs.com/wytiger/p/5204795.html

總結(jié)

以上是生活随笔為你收集整理的【收藏】Android屏幕适配全攻略(最权威的Google官方适配指导)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

国产69精品久久app免费版 | 国产亚洲精品久久久久久大师 | 日韩精品一区二区免费视频 | 狠狠躁日日躁狂躁夜夜躁av | 午夜久久美女 | 91精品视频导航 | 日本中文字幕视频 | www.色就是色 | 中文字幕av在线免费 | 最近免费在线观看 | 91精品啪在线观看国产81旧版 | 亚洲另类人人澡 | 四虎影视成人精品国库在线观看 | 97人人模人人爽人人喊网 | 在线观看色网站 | 97视频免费 | 午夜精品三区 | www色,com | 国产精品美女久久久久久网站 | 日日噜噜噜噜夜夜爽亚洲精品 | 五月的婷婷 | 国产精品av在线免费观看 | 国产精品高 | 国产在线观看你懂得 | 国产高清久久久久 | 国产美女视频免费观看的网站 | 国产精品免费在线视频 | 在线观看色网 | 毛片一区二区 | 狠狠操天天射 | 亚洲精品理论片 | 色婷久久 | 欧洲一区二区在线观看 | 欧美日韩免费观看一区=区三区 | 99精品视频免费观看视频 | 精品成人a区在线观看 | 国产免费又爽又刺激在线观看 | 精品视频区 | 中文字幕中文中文字幕 | 国产一区二区三区四区大秀 | 一区二区三区四区五区在线 | 国产精品毛片一区视频 | 精品欧美一区二区三区久久久 | 久久视频在线观看 | 日韩免费小视频 | 久久99热这里只有精品国产 | av大片网址 | 一区二区三区中文字幕在线观看 | 日本乱视频| 一区二区中文字幕在线播放 | 五月亚洲综合 | 亚洲欧美国产精品va在线观看 | 成年人在线看片 | 91亚色视频在线观看 | 成人丁香花 | 免费精品在线 | 久久影视网 | a级片久久久 | 91精品在线麻豆 | 欧美一级艳片视频免费观看 | 日韩欧美成人网 | 在线看黄色的网站 | 久久99热这里只有精品 | 日日摸日日爽 | 99免费在线播放99久久免费 | 日韩在线观看精品 | 欧美综合色 | 中文字幕一区二区三区精华液 | 91精品国产综合久久福利不卡 | 亚洲国产成人精品久久 | 在线视频99 | 欧美少妇的秘密 | 久久久久久久久综合 | www.天天干.com| 亚洲人成网站精品片在线观看 | 久久字幕 | 国产精品大片免费观看 | 夜色资源站国产www在线视频 | 天天爽天天爽天天爽 | 国产精品久久久久久久久婷婷 | 精品日本视频 | 日韩二区三区在线 | 午夜视频在线观看一区 | 久久久黄色免费网站 | 国产黄色电影 | 97视频一区| 亚洲最新毛片 | 综合久久婷婷 | 亚av在线| 国产午夜精品视频 | 亚洲一区二区三区毛片 | 国产vs久久| 国产亚洲综合精品 | 日本精品在线看 | 国产日韩在线播放 | 成人av网站在线 | 奇米影视8888 | 青青草久草在线 | 国产成人a亚洲精品v | 国产在线91在线电影 | 在线观看黄av | 久久久久久久久久伊人 | 亚洲伊人av | 亚洲国产视频网站 | 国产精品美女久久久久久久 | 国产一级视频在线观看 | 中文字幕欧美日韩va免费视频 | 欧美二区三区91 | 免费欧美精品 | 国产手机视频在线播放 | 午夜精品视频福利 | 又黄又爽的视频在线观看网站 | 2023av在线| 狠狠狠色丁香综合久久天下网 | 国产91粉嫩白浆在线观看 | 91精品国产综合久久久久久久 | 国产日韩一区在线 | 在线不卡视频 | 91网站在线视频 | 日韩电影黄色 | 91av观看 | 狠狠五月婷婷 | 一级黄色片在线免费看 | 草在线| 久久久国产精品成人免费 | 中文字幕色婷婷在线视频 | 精品欧美小视频在线观看 | 成人久久免费 | 国产一区电影在线观看 | www四虎影院 | 免费99视频 | 国语对白少妇爽91 | 亚洲午夜精品在线观看 | 人人爽人人爽人人片av免 | 精品美女国产在线 | 免费日韩 精品中文字幕视频在线 | 天天天综合网 | 亚洲码国产日韩欧美高潮在线播放 | 日本爱爱免费视频 | 国产在线污 | 精品国产成人在线影院 | 国产精品久久久久aaaa九色 | 激情综合国产 | 久久久久久久久久久网 | 日韩午夜网站 | 久久久不卡影院 | 狠狠撸电影 | 精品人妖videos欧美人妖 | 免费一级片在线 | 色在线网| 免费看wwwwwwwwwww的视频 久久久久久99精品 91中文字幕视频 | 久久精品影视 | 日韩mv欧美mv国产精品 | 黄色大全免费观看 | 精品黄色片 | 久久精品999| 国产精品亚洲片夜色在线 | 91精品1区2区 | 在线免费看黄色 | 999视频精品 | 91精品国 | 国产一区二区手机在线观看 | 操操综合网| 日韩av在线资源 | 国产成人一区二区精品非洲 | 亚洲精品1区2区3区 超碰成人网 | 亚洲精品乱码久久久久久高潮 | 99久久99久久精品国产片果冰 | 人人玩人人添人人 | 日韩av片无码一区二区不卡电影 | 在线国产不卡 | 91黄色视屏 | 97视频亚洲 | 久久综合九色综合久99 | 永久免费毛片在线观看 | 岛国av在线 | 免费久久99精品国产婷婷六月 | 伊人亚洲综合 | 91毛片视频 | 人人插人人艹 | 日本黄色免费在线 | 精品一区二区免费视频 | 激情婷婷综合网 | 久草免费在线观看视频 | 日韩精品免费一线在线观看 | 91网页版免费观看 | 999男人的天堂 | 日韩亚洲国产中文字幕 | 亚洲影院国产 | 国产一级黄色电影 | 日韩爱爱片 | 日韩精品一区二区三区在线视频 | 亚洲精品1234区 | 黄色免费网站下载 | 中文字幕av免费观看 | 日韩黄色在线 | 亚洲欧美视频在线播放 | 免费看wwwwwwwwwww的视频 久久久久久99精品 91中文字幕视频 | 色网站免费在线观看 | 国产精品一区二区三区免费视频 | 亚洲电影院 | 在线中文字幕电影 | 国产美女精品人人做人人爽 | 日韩在线色视频 | 毛片基地黄久久久久久天堂 | 狠狠的操狠狠的干 | 色婷婷综合视频在线观看 | 亚洲无吗天堂 | 国产精品久久久久久久电影 | 中文字幕丰满人伦在线 | 欧美 亚洲 另类 激情 另类 | 亚洲欧洲精品久久 | 久热精品国产 | 九九九在线观看 | 97av视频| 欧美日韩国语 | 久久资源总站 | 日韩精品一区二区在线观看视频 | 亚洲成aⅴ人片久久青草影院 | 成人在线播放免费观看 | 国产精品久久久久久麻豆一区 | 日韩久久网站 | 亚洲精品视频第一页 | 精品一区在线 | 日本中文在线 | 欧美黄色成人 | 91九色视频导航 | 日韩精品免费一区二区在线观看 | 精品国产日本 | 99久精品视频 | 久久你懂得 | 久久精品婷婷 | 久久国产精品精品国产色婷婷 | 午夜在线免费观看 | 黄色美女免费网站 | 国产在线第三页 | a在线观看视频 | 免费av网址大全 | 成人精品一区二区三区中文字幕 | 国产亚州精品视频 | 久久免费成人网 | 成人性生交视频 | 国产一区二区在线播放 | 精品国产免费av | 亚洲v欧美v国产v在线观看 | 黄色高清视频在线观看 | 国产成人精品久 | 99久久精品国产一区 | 国产精品久久久久毛片大屁完整版 | av在线不卡观看 | 在线最新av | 国产精品永久免费 | 色在线高清 | 最新一区二区三区 | 日韩高清二区 | 中文字幕日韩一区二区三区不卡 | www天天操 | 色综合色综合久久综合频道88 | 热久久最新地址 | 久久久久久欧美二区电影网 | 中文字幕在线视频一区二区 | 国产视频在线观看免费 | 久草精品视频在线观看 | 久久8精品 | 欧美欧美 | 在线性视频日韩欧美 | 国产福利一区二区三区在线观看 | 日韩欧美在线观看一区二区三区 | 亚洲精品国产欧美在线观看 | 国产精品美女久久久久久久 | 国产一级黄 | 久热国产视频 | 精品视频免费播放 | 一本一本久久a久久精品综合小说 | 97在线免费| 精品一区电影 | 国产色啪 | 99久久精品国产一区二区三区 | 欧美一级特黄高清视频 | 国产精品av一区二区 | 久久深夜 | av超碰在线 | 欧美一区免费观看 | 国产精品久久嫩一区二区免费 | 亚洲理论影院 | 狠狠干狠狠插 | 97精品国产| 日韩欧美高清在线观看 | 亚洲高清视频在线播放 | 国产精品一区久久久久 | 久久久久久草 | 久久综合桃花 | 一区久久久 | 综合在线亚洲 | 人人澡人人爽 | 免费国产在线视频 | 中文字幕在线视频第一页 | 在线视频18在线视频4k | 日韩一区二区三区不卡 | 久草视频看看 | 99夜色 | 激情久久久久久久久久久久久久久久 | 婷婷色网视频在线播放 | 免费视频一级片 | 成人av免费网站 | 最新日韩在线观看 | 四虎在线观看视频 | 在线免费观看黄色小说 | 成人97视频一区二区 | 亚洲精品美女久久17c | 午夜精品一二三区 | 亚洲成a人片在线观看网站口工 | 亚洲精品成人av在线 | 9免费视频 | 久久r精品| 中文网丁香综合网 | 国产精品va在线观看入 | 香蕉在线影院 | 久久久人 | 伊人午夜视频 | 91精品久久久久久久久久入口 | 国产精品99久久久久久武松影视 | 黄色小网站在线 | 国产品久精国精产拍 | 97精品国产一二三产区 | 国产又粗又硬又爽视频 | 国产在线v| 日本久久免费电影 | 五月激情婷婷丁香 | 高清av免费看 | 欧美日本不卡视频 | 国产视频一区在线 | 国产超碰97 | 久久国产精品小视频 | 欧美一级大片在线观看 | 国产成人精品久久久久蜜臀 | 成人啊 v | 国产免费又粗又猛又爽 | 在线免费观看黄网站 | 国产精品久久久久久久婷婷 | 精品欧美小视频在线观看 | 免费在线观看一级片 | 天天爽夜夜爽精品视频婷婷 | 欧美狠狠操 | 九九视频精品免费 | 欧美精品久| 免费在线观看毛片网站 | 国产你懂的在线 | a级国产乱理论片在线观看 特级毛片在线观看 | 久一网站 | 亚洲劲爆av| 亚洲国产精品500在线观看 | 国产综合精品久久 | 麻豆一精品传二传媒短视频 | 亚洲成av人片在线观看 | 日韩理论片中文字幕 | 中文字幕在线视频精品 | 天天se天天cao天天干 | www.夜夜爱 | 天天综合狠狠精品 | 激情五月婷婷综合网 | 日韩超碰 | 日本在线视频一区二区三区 | 久久精品视频播放 | 九九久久国产精品 | 亚洲黄色免费在线看 | 久久久久亚洲a | 黄色亚洲在线 | 亚洲成a人片77777kkkk1在线观看 | 69视频永久免费观看 | 久久久久国产一区二区 | 久久国产精品99久久久久久进口 | 精品国模一区二区三区 | 中文字幕免费高清 | 午夜精品一区二区三区在线播放 | 精品在线观看一区二区三区 | 午夜成人免费影院 | 三级在线播放视频 | 波多野结衣视频一区 | av网站播放 | 麻豆91在线看 | 99九九99九九九视频精品 | 国产精品高 | 日韩免费在线网站 | 在线色亚洲 | 亚洲成人黄色 | 欧美精品乱码久久久久久按摩 | 国产精品aⅴ | 亚洲午夜不卡 | 日韩成年视频 | 日韩午夜精品福利 | 国产专区精品 | 大胆欧美gogo免费视频一二区 | 久久久高清免费视频 | 97精品国产97久久久久久久久久久久 | 久久看免费视频 | 久久久久久久影院 | 国产女人18毛片水真多18精品 | 深爱婷婷 | 337p欧美| 国产在线视频导航 | 怡红院av久久久久久久 | 99免费在线播放99久久免费 | 国产99免费 | 视频成人 | 精品国产一区二区三区日日嗨 | 日韩国产精品久久 | 色综合久久久网 | 人人添人人 | 国产精品永久免费观看 | 中文字幕在线播出 | 91精品在线免费观看 | 国产精品国产三级国产专区53 | 欧美性大胆 | 日本韩国精品在线 | 91传媒视频在线观看 | 日本丰满少妇免费一区 | av线上看| 91人人澡人人爽人人精品 | 久久久亚洲麻豆日韩精品一区三区 | www.久久久| 免费a网站| 最近免费观看的电影完整版 | 日韩av免费一区二区 | 97在线观看视频国产 | 免费在线播放av电影 | 精品国产电影 | 国产h片在线观看 | 九九热中文字幕 | 国产精品99久久久精品 | 97超碰人人澡 | 超碰电影在线观看 | 综合婷婷 | 精品国产一区二区三区不卡 | 婷婷5月激情5月 | 色婷婷色 | 在线观看色网 | 亚洲精品在线观看免费 | 欧美精品v国产精品v日韩精品 | 久久久网址 | 成人免费看黄 | 国产在线观看h | 国产美女精品视频免费观看 | 久草网站在线观看 | 亚洲欧洲成人精品av97 | 亚州精品在线视频 | 91人人爱| 久久草在线免费 | 亚洲精品成人网 | 日韩,精品电影 | 性色视频在线 | 日韩,精品电影 | 欧美日韩国内在线 | 婷婷色婷婷 | 天天射综合网站 | 超碰在线人人草 | 99爱视频 | 天天综合网久久综合网 | 国产69久久 | 一区二区三区 中文字幕 | 欧美精品一区二区在线观看 | 精品久久国产精品 | av网站地址 | 特级西西人体444是什么意思 | 午夜性生活片 | 国产综合精品久久 | 欧美精品久久99 | 欧美小视频在线观看 | 超级碰碰免费视频 | 国产人成看黄久久久久久久久 | 久久黄色网址 | 免费在线观看一区二区三区 | 在线观看国产91 | 日韩性网站 | 在线观看韩日电影免费 | 亚洲视频www | 天天做天天射 | 91成人久久 | 波多野结衣在线中文字幕 | 中文字幕成人一区 | 精品国产亚洲日本 | 在线久草视频 | 久九视频 | 日日夜夜噜 | 日本一区二区三区视频在线播放 | 黄色av免费| 97人人澡人人添人人爽超碰 | www天天干com| 国产精品自拍av | av免费网站观看 | 国产伦精品一区二区三区在线 | 久久99电影 | 五月天久久综合网 | 国产一区二区精品久久91 | 国产黄影院色大全免费 | 香蕉在线观看视频 | 伊人国产女 | 免费观看黄色12片一级视频 | 久久精品综合视频 | 国产精品九九九 | 久久久久网址 | 婷婷精品国产欧美精品亚洲人人爽 | 日本韩国精品在线 | 天天五月天色 | 国产精品亚洲片在线播放 | 国产高清一区二区 | 99色亚洲| 久久精品99久久 | 免费观看成人网 | 精品国精品自拍自在线 | 色综合天天狠天天透天天伊人 | 综合激情伊人 | 欧美 日韩 久久 | 最近中文字幕国语免费av | 久久免费国产精品1 | 国产麻豆果冻传媒在线观看 | 国产v亚洲v | 午夜视频在线观看网站 | 日韩免费电影在线观看 | 国产又粗又猛又黄又爽视频 | av免费观看高清 | 91香蕉视频好色先生 | 日韩精品免费一区二区在线观看 | 久久99国产精品久久 | 在线观看一区二区视频 | 亚洲第一区在线播放 | 欧美激情第八页 | 伊人伊成久久人综合网站 | 日韩高清精品一区二区 | 午夜视频亚洲 | 国产精品久久久一区二区三区网站 | 午夜国产在线 | 午夜在线免费视频 | 中文字幕高清免费日韩视频在线 | 日韩欧美在线国产 | 国产丝袜美腿在线 | 国产h片在线观看 | 国产丝袜一区二区三区 | 久久综合久久久 | 亚洲精品中文在线资源 | 日韩午夜av | 国产五月天婷婷 | 超碰在线观看97 | 国产午夜精品福利视频 | 日日夜夜狠狠干 | 欧美日韩免费观看一区二区三区 | 三级av免费观看 | 射九九 | 在线观看视频黄色 | 国产精品久久麻豆 | 欧美黄色成人 | 久久久久久久久久久影院 | 99热最新 | 免费视频在线观看网站 | 免费看久久久 | 亚洲一区美女视频在线观看免费 | 狠狠狠狠狠狠狠干 | 国产91精品高清一区二区三区 | 国产91精品一区二区麻豆亚洲 | 一区二区三区动漫 | 久久九九国产视频 | 亚洲精品乱码久久久久v最新版 | 午夜久久精品 | 91精品国产综合久久福利不卡 | 国产专区日韩专区 | 美女视频一区 | 337p西西人体大胆瓣开下部 | 亚洲免费在线视频 | 国产夫妻av在线 | 精品亚洲午夜久久久久91 | 91成人在线免费观看 | 成人免费观看视频网站 | 99免费视频 | 久久综合久久久 | 国产精品久久久久久久久久ktv | 免费a视频| 国产精品免费在线播放 | 国产精品免费在线播放 | 亚洲国产视频直播 | 日本mv大片欧洲mv大片 | 黄色三级av | 欧美日bb| 伊人中文字幕在线 | 免费在线观看成年人视频 | 91传媒91久久久 | 在线观看日本韩国电影 | 在线观看成年人 | 黄色免费高清视频 | 韩国中文三级 | 激情五月在线 | 亚洲天堂网视频在线观看 | 麻豆视频免费看 | 五月天狠狠操 | 在线亚洲人成电影网站色www | 人人射网站 | 国产精品网站一区二区三区 | 美女国产网站 | 国产va精品免费观看 | 97国产情侣爱久久免费观看 | 91社区国产高清 | 精品国产视频在线观看 | 久久在线观看视频 | 不卡的av | 91在线播放综合 | 国产成人三级在线 | 国产片免费在线观看视频 | 日韩毛片一区 | 四虎影视精品成人 | 中文字幕在线专区 | 91成人网在线观看 | 久久国产成人午夜av影院潦草 | 日韩欧美在线综合网 | 91九色性视频 | 免费人成网 | 99国产一区二区三精品乱码 | 久久视频这里只有精品 | 国产一区在线播放 | 99热在线免费观看 | 国产一级做a爱片久久毛片a | 精品国内自产拍在线观看视频 | 国产一级免费电影 | 亚洲 欧美 变态 国产 另类 | 特黄特色特刺激视频免费播放 | 免费黄色小网站 | 天天操夜夜想 | 久久久久免费网站 | 中文字幕免费国产精品 | 欧美大香线蕉线伊人久久 | 国产毛片久久 | 日本久久成人中文字幕电影 | 国产又粗又长的视频 | 国产96av | 五月婷婷影院 | 探花视频免费观看高清视频 | 日韩在线免费视频观看 | 免费在线观看中文字幕 | 香蕉精品在线观看 | 不卡的av在线播放 | 天天五月天色 | 久久精品美女视频 | 免费色视频网址 | 4438全国亚洲精品在线观看视频 | 国产一级一片免费播放放 | 一区二区高清在线 | 国产麻豆精品久久 | 久久久久免费精品视频 | 草久在线 | 欧美一级电影在线观看 | 香蕉国产91 | 成人免费大片黄在线播放 | 色诱亚洲精品久久久久久 | 欧美日韩免费视频 | 丁香av在线| 成人黄色在线 | 久久人操| 91网页版免费观看 | 玖玖在线播放 | 国产一区在线视频 | 91热这里只有精品 | 欧美日韩国产免费视频 | www狠狠操 | 十八岁免进欧美 | 久久激情久久 | 午夜av电影| 亚洲国产精品免费 | 国产一级免费在线 | 天天干天天做 | 91亚洲视频在线观看 | 日韩免费中文字幕 | 一级国产视频 | av中文字幕免费在线观看 | 国产精品96久久久久久吹潮 | 激情综合啪 | 一区二区三区在线观看中文字幕 | 国产一级电影 | 天天操天天操天天操天天操天天操天天操 | 在线看国产 | 国产一区二区精品91 | 999国内精品永久免费视频 | 欧美日韩激情视频8区 | 91av片| 91免费国产在线观看 | 成人资源在线 | 成人黄色小说在线观看 | 伊人久久一区 | 成人a在线观看高清电影 | 在线观看日本高清mv视频 | 最新日韩电影 | 日韩精品久久中文字幕 | 一区二区三区日韩在线观看 | 免费看十八岁美女 | 亚洲精品字幕在线观看 | av黄网站 | 国产最新在线观看 | 欧美日韩18 | 91精品视频免费 | 亚洲精品在线观看视频 | 国产视频2区 | 亚洲精品国偷自产在线91正片 | 久久精品三级 | 麻豆av一区二区三区在线观看 | 精品久久久久免费极品大片 | 麻豆果冻剧传媒在线播放 | 久草视频免费在线播放 | 日韩免费在线播放 | 日韩一区二区三区在线观看 | 久草久热 | 国产在线 一区二区三区 | 天天综合色天天综合 | 欧美天天综合网 | 国产亚洲精品综合一区91 | 国产黄色精品网站 | 欧美日本一二三 | 欧美成人亚洲成人 | 精品国产美女 | 国产福利91精品一区二区三区 | 中文字幕第一 | 亚洲三级网站 | 最新av在线播放 | 99欧美| 久久99久久精品国产 | 精品免费国产一区二区三区四区 | 欧美a在线免费观看 | 日韩二区三区在线 | 91精品国产电影 | 99免费在线播放99久久免费 | 久久久五月天 | 97在线超碰 | 久久久久一区二区三区四区 | 日韩精品视频免费专区在线播放 | 日韩在线视频一区 | 又黄又刺激又爽的视频 | 中文字幕成人 | 国产精品免费不卡 | 国产精品高清免费在线观看 | 久久99国产精品二区护士 | 久久一区二区三区超碰国产精品 | 久久精品一二三区白丝高潮 | 97在线视频免费 | 亚洲天堂在线观看完整版 | 91在线免费观看国产 | 日韩性片| 在线天堂v| 亚洲精品乱码 | 日韩免费视频一区二区 | 亚洲精品字幕在线观看 | 欧美91精品 | 日韩精品一区二区在线观看 | 色射爱| 欧美激情视频在线观看免费 | 91网在线看 | 日韩午夜在线播放 | 国产日产亚洲精华av | 一区在线播放 | 香蕉视频在线看 | 黄色片视频免费 | 天天色天天爱天天射综合 | 九九九热精品免费视频观看网站 | 91av手机在线观看 | 91在线国内视频 | 97国产情侣爱久久免费观看 | 亚洲视频电影在线 | 欧美最猛性xxxx | 久久国产精品99久久久久久老狼 | 日韩手机在线观看 | 808电影| 久久午夜精品视频 | 久久视频在线观看免费 | 综合色播| 91插插影库| 99r精品视频在线观看 | www.久久久.com| 黄色成人在线观看 | 97在线视频网站 | 国产首页 | 黄网站免费大全入口 | 婷婷丁香国产 | 国产精品99久久久久久久久久久久 | 亚洲成人精品久久久 | 亚洲精品视频在线 | 成年人在线免费看视频 | www.狠狠操.com | 日韩一级黄色大片 | 国产精品自产拍在线观看中文 | www久久九 | 黄色一级性片 | 青青河边草免费视频 | 黄色大片入口 | 欧美va天堂在线电影 | 色综合久久中文字幕综合网 | 人人舔人人舔 | 精品久久久亚洲 | 日韩视频一区二区在线观看 | 免费观看久久 | 91av视频免费观看 | 天堂在线一区 | 久久国色夜色精品国产 | av中文在线影视 | 日韩三区在线 | 欧美91精品久久久久国产性生爱 | 欧美精品乱码99久久影院 | 国产精品亚洲人在线观看 | 色婷婷激情电影 | 日韩在线电影一区二区 | 欧美日韩在线观看一区 | 国产免费亚洲高清 | 国精产品999国精产品视频 | 久久与婷婷 | 中文字幕一区二区三区乱码不卡 | 婷婷视频 | 久久久网址 | 免费在线观看av网址 | 久久精品这里热有精品 | 亚洲高清精品在线 | 91免费观看国产 | 狠狠狠干| 天天操天天添 | 国产成人黄色网址 | 99亚洲天堂| 午夜三级毛片 | 久久精品—区二区三区 | 国产精品久久久久久久久久久免费看 | 久久国产视屏 | www.夜夜干.com | 久久午夜羞羞影院 | 一区二区三区在线观看 | 天天操天天拍 | 国产精品视频最多的网站 | 欧美做受高潮1 | 在线观看成年人 | 精品国内自产拍在线观看视频 | 99久久精品免费看国产麻豆 | 日韩久久久久久久久久久久 | 美女在线免费视频 | 欧美成人tv | 中文字幕精品www乱入免费视频 | 亚洲成av人片在线观看无 | 国产精品毛片网 | 少妇自拍av| 中文在线a在线 | 日本特黄一级片 | 天天av在线播放 | 一区二区三区高清在线观看 | 久久资源总站 | 国产在线超碰 | 狠狠干综合 | 久草免费色站 | 手机看片| 久久久亚洲国产精品麻豆综合天堂 | 在线看片一区 | 久日视频 | 欧美日韩另类在线 | 久久久久久久久久伊人 | 中文字幕中文字幕中文字幕 | 日日操网| 国内视频在线观看 | 亚洲国产精品999 | 精品麻豆 | 国产一区二区精品久久91 | 99热这里| 久久久私人影院 | 激情综合色播五月 | av夜夜操| 久草视频在线观 | av免费网页| 欧美一区二区在线免费观看 | 狠狠操天天操 | 精品国产精品久久一区免费式 | 亚洲国产精品视频在线观看 | 久草精品视频在线播放 | 超碰成人免费电影 | 在线看毛片网站 | 国产精品成人久久久 | 99精品国产视频 | 久久不卡日韩美女 | 91超碰免费在线 | 国产精品美女久久久久久2018 | 婷婷五情天综123 | 一本一本久久a久久 | 国产不卡av在线 | 日韩在线观看一区 | 青春草视频在线播放 | 国产不卡一 | 2023年中文无字幕文字 | 久久婷综合 | 久久成人午夜 | 色综合欧洲 | 夜夜看av | 欧美激情精品久久久久久免费 | 日韩欧美一区二区在线观看 | 在线观看国产高清视频 | 久久激情五月婷婷 | 国产精品人人做人人爽人人添 | 99久久精品久久久久久清纯 | 婷婷综合久久 | 激情开心站| www.夜色.com| 免费网站在线观看人 | 成人在线视频免费观看 | 色综合久久久久久中文网 | 激情视频久久 | 日韩电影在线观看中文字幕 | 怡红院av久久久久久久 | 天天插天天色 | 久久久久久久久久久电影 | 国产在线观看免 | 99爱爱 | 在线看v片成人 | 国产中文| 久章草在线观看 | 久久精品福利 | 男女视频国产 | 欧美在线观看视频一区二区三区 | 涩av在线| 综合伊人av| www久久九 | 国产一区二区播放 | 久久国产美女 | 四虎免费在线观看视频 | 国产一区二区在线看 | 伊人国产在线播放 | 国产精品电影一区 | 婷婷色影院 | 免费a视频| 天天操天天怕 | 96精品高清视频在线观看软件特色 | 久久国语| 天天天天天天天天操 | 国产精品一区专区欧美日韩 | 伊人久在线 | 国产一区二区在线影院 | www国产亚洲精品久久麻豆 | 亚洲一区免费在线 | 国产午夜视频在线观看 | 国产日韩精品一区二区 | 99综合电影在线视频 | 伊人av综合 | 又色又爽又黄高潮的免费视频 | 国内精品亚洲 | 亚洲天天在线日亚洲洲精 | 欧美日韩一级在线 | 久久在视频 | 天天干天天天 | 久久91网 | 国产麻豆视频免费观看 | www.在线看片.com | 亚洲视频免费在线观看 | 在线观看视频你懂得 | 国产视频在线免费观看 | 99r精品视频在线观看 | 在线成人欧美 | 99精品久久久久久久久久综合 | 91香蕉视频好色先生 | 日韩艹 | 亚洲精品久久激情国产片 | 五月开心色 | 伊人资源站 | 深爱开心激情网 | 婷婷在线网 | 亚洲精选视频在线 | 日日爽天天 | 91av在线免费观看 | 亚州国产精品 | 人人插人人艹 | 久久五月精品 | 欧美日韩一区二区三区在线观看视频 | 韩国av一区二区三区 | 天堂av影院 | 玖玖国产精品视频 | 狠狠躁日日躁狂躁夜夜躁av | 国产精品96久久久久久吹潮 | 九色精品在线 | 又爽又黄又无遮挡网站动态图 | 亚洲九九影院 | 怡红院av| 日韩色av色资源 | 久久免费观看少妇a级毛片 久久久久成人免费 | h文在线观看免费 | 国产系列 在线观看 | 中文字幕乱码亚洲精品一区 | 国产黄色片免费在线观看 | 又黄又爽的免费高潮视频 | 日日夜夜狠狠 | 黄色国产高清 | 国产视频在线观看一区二区 | 久久综合久久八八 | 一区二区三区在线播放 | 91精品久久久久久粉嫩 | 免费看三级网站 | 丝袜精品视频 | 91成人短视频在线观看 | 久久久片 | 精品成人a区在线观看 | 丁香久久久 | 免费视频91蜜桃 | 狠狠干夜夜爽 | 婷婷.com| 狠狠狠狠狠狠狠狠 |