自動縮放佈局,以後再也不用擔心適配問題了

做過安卓開發的都知道,屏幕適配是一件非常困難的事情。
Google官方的解決方案:screens_support 需要寫多個layout文件以及dimens.xml,工作量大不說,維護也麻煩。

其實很多時候我們的需求很簡單,就是要求不同的屏幕看上去效果一樣就可以了。這樣就需要我們佈局的時候採用百分比來定位。
說到百分比,我們第一時間想到的是layout_weight,但是layout_weight實際使用效果並不是很好,特別是一些複雜情況下需要層層嵌套。也無法解決所有問題,比如文字大小。

我想到的解決方案是根據屏幕大小重新對佈局以及佈局內部對象的大小進行調整。之前做過的一些項目裏面的自定義view也用過這種方法。
我在網上也搜到了一些相關資料,比如 Vanteon Electronic Design  。說明這種方法是可行的。剩下的問題就是怎麼把這種方式封裝成一個通用的解決方案,能以最簡便的方式融入到開發中來。

經過一番實驗,我初步開發出來了AutoScalingLayout
源碼:https://github.com/Junhua102/AutoScalingLayout


實現原理:

原理類似我們用播放器看視頻的時候,無論怎麼調整窗口大小,播放器都可以自動調整視頻大小適合窗口大小。因爲視頻有一個原始分辨率,播放器會根據窗口實際大小對視頻進行縮放。

我們寫佈局的時候一般是根據某個基準分辨率來(比如UI給的原型圖),自動縮放佈局的作用就是將這個基準佈局乘以一個縮放比例,達到適配所有分辨率的目的。

計算縮放比例公式: 實際大小 / 設計大小 = 縮放比例
只需要給定一個設計大小,就可以計算出縮放比例,然後將佈局內部所有元素的尺寸都乘以這個縮放比例,就可以適配實際屏幕了。


使用方法:
studio用戶使用release/AutoScalingLayout.aar
eclipse用戶使用release/AutoScalingLayout.jar,並將attr.xml複製到value目錄

替換佈局:

只需要替換需要縮放的根佈局即可,內部子佈局會自動縮放

原佈局 自動縮放佈局
RelativeLayout  ASRelativeLayout
LinearLayout  ASLinearLayout
FrameLayout  ASFrameLayout

目前只支持以上3種佈局

添加屬性:
[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. xmlns:custom="http://schemas.android.com/apk/res-auto"  
  2. custom:designWidth="384dp"  
  3. custom:designHeight="575dp"  

designWidth和designHeight就是你在可視化編輯xml時使用的屏幕大小。比如我使用的是Nexus 4,屏幕尺換算成dp就是384dp和575dp(減去狀態欄和操作欄)


注意事項

1.designWidth和designHeight非常重要,千萬不要填錯,否則縮放出來就不是你想要的效果了。
2.如果designWidth和designHeight的單位是dp,那麼所有內部子view的單位都必須是dp,不能寫px、pt等其他單位。文字大小也不能用sp。如果你想無腦照抄UI給出的像素值,就全部單位用px就可以了。

3.AutoScalingLayout縮放時會保持deginWidth和designHeight的縱橫比,不用擔心正方形變矩形。


以sample中的 activity_login_dp.xml 爲例

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <me.dreamheart.autoscalinglayout.ASRelativeLayout  
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     xmlns:custom="http://schemas.android.com/apk/res-auto"  
  5.     custom:designWidth="384dp"  
  6.     custom:designHeight="575dp"  
  7.     custom:autoScaleEnable="true"  
  8.     android:layout_width="match_parent"  
  9.     android:layout_height="match_parent"  
  10.     android:orientation="vertical"  
  11.     tools:context=".LoginActivity"  
  12.     android:background="@drawable/login_bg"  
  13.     >  
  14.   
  15.     <TextView  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:layout_marginTop="60dp"  
  19.         android:text="Title"  
  20.         android:textSize="30dp"  
  21.         android:textColor="#fff"  
  22.         android:layout_centerHorizontal="true"  
  23.         />  
  24.   
  25.     <View android:id="@+id/login_input_form"  
  26.         android:layout_width="270dp"  
  27.         android:layout_height="100dp"  
  28.         android:layout_marginTop="125dp"  
  29.         android:layout_centerHorizontal="true"  
  30.         android:background="@drawable/login_input_form"  
  31.         />  
  32.   
  33.     <TextView android:id="@+id/user_name_tv"  
  34.         android:layout_width="wrap_content"  
  35.         android:layout_height="wrap_content"  
  36.         android:layout_marginTop="140dp"  
  37.         android:layout_marginLeft="16dp"  
  38.         android:layout_alignLeft="@+id/login_input_form"  
  39.         android:text="@string/user_name"  
  40.         android:textSize="15dp"  
  41.         android:textColor="#666"  
  42.         />  
  43.   
  44.     <TextView android:id="@+id/password_tv"  
  45.         android:layout_width="wrap_content"  
  46.         android:layout_height="wrap_content"  
  47.         android:layout_marginTop="190dp"  
  48.         android:layout_alignLeft="@+id/user_name_tv"  
  49.         android:text="@string/password"  
  50.         android:textSize="15dp"  
  51.         android:textColor="#666"  
  52.         />  
  53.   
  54.     <EditText android:id="@+id/user_name"  
  55.         android:layout_toRightOf="@+id/user_name_tv"  
  56.         android:layout_marginLeft="10dp"  
  57.         android:layout_alignBaseline="@+id/user_name_tv"  
  58.         android:layout_height="wrap_content"  
  59.         android:layout_width="190dp"  
  60.         android:textSize="15dp"  
  61.         android:textColor="#444"  
  62.         android:hint="@string/prompt_name"  
  63.         android:inputType="text"  
  64.         android:maxLines="1"  
  65.         android:singleLine="true" />  
  66.   
  67.     <EditText android:id="@+id/password"  
  68.         android:layout_toRightOf="@+id/user_name_tv"  
  69.         android:layout_marginLeft="10dp"  
  70.         android:layout_alignBaseline="@+id/password_tv"  
  71.         android:layout_height="wrap_content"  
  72.         android:layout_width="190dp"  
  73.         android:textSize="15dp"  
  74.         android:textColor="#444"  
  75.         android:hint="@string/prompt_password"  
  76.         android:inputType="textPassword"  
  77.         android:maxLines="1" android:singleLine="true" />  
  78.   
  79.     <Button android:id="@+id/email_sign_in_button"  
  80.         android:background="@drawable/login_btn_selector"  
  81.         android:layout_marginTop="260dp"  
  82.         android:layout_centerHorizontal="true"  
  83.         android:layout_width="270dp"  
  84.         android:layout_height="40dp"  
  85.         android:text="@string/action_sign_in"  
  86.         android:textSize="20dp"  
  87.         android:textColor="#444"  
  88.         android:textStyle="bold" />  
  89.   
  90. </me.dreamheart.autoscalinglayout.ASRelativeLayout> 


未使用AutoScalingLayout



使用AutoScalingLayout


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章