Android最便捷的螢幕適配,堪稱螢幕適配終結者
效果圖
最大幅度解決適配問題,並且最大化方便開發者。
so,看下用法:
你沒有看錯,拿到設計稿,在佈局檔案裡面直接填寫對應的px即可,px:這裡的px並非是Google不建議使用的px,在內部會進行轉化處理。
ok,拿一些實際專案的頁面,看下不同解析度下的效果:
左為:768 * 1280 ; 右為:1080 * 1920
上述兩個機器的解析度差距挺大了,但是完美實現了適配,最為重要的是:
- 再也不用拿著設計稿去想這控制元件的寬高到底取多少dp
- 再也不用去為多個螢幕去寫多個dimens
- 再也不用去計算百分比了(如果使用百分比控制元件完成適配)
- 再也不用去跟UI MM去解釋什麼是dp了
你所要做的就是抄抄設計稿上面的px,直接寫入佈局檔案。
還有很多好處,比如上面的Item裡面元素比較多,如果標識的比較全面,一個FrameLayout,裡面的View填寫各種marginLeft,marginTop就能完美實現,幾乎不需要嵌套了。
引入
- Android Studio
dependencies { compile project(':autolayout') }
也可以直接
dependencies {
compile 'com.zhy:autolayout:1.4.3'
}
- Eclipse
建議使用As,方便版本更新。實在不行,只有複製貼上原始碼了。
用法
第一步:
在你的專案的AndroidManifest中註明你的設計稿
<meta-data android:name="design_width" android:value="768"> </meta-data> <meta-data android:name="design_height" android:value="1280"> </meta-data>
第二步:
讓你的Activity繼承自AutoLayoutActivity
.
非常簡單的兩個步驟,你就可以開始愉快的編寫佈局了,詳細可以參考sample。
其他用法
如果你不希望繼承AutoLayoutActivity
,可以在編寫佈局檔案時,將
- LinearLayout -> AutoLinearLayout
- RelativeLayout -> AutoRelativeLayout
- FrameLayout -> AutoFrameLayout
這樣也可以完成適配。
目前支援屬性
- layout_width
- layout_height
- layout_margin(left,top,right,bottom)
- pading(left,top,right,bottom)
- textSize
- maxWidth, minWidth, maxHeight, minHeight
配置
預設使用的高度是裝置的可用高度,也就是不包括狀態列和底部的操作欄的,如果你希望拿裝置的物理高度進行百分比化:
可以在Application的onCreate方法中進行設定:
public class UseDeviceSizeApplication extends Application { @Override public void onCreate() { super.onCreate(); AutoLayoutConifg.getInstance().useDeviceSize(); } }
預覽
大家都知道,寫佈局檔案的時候,不能實時的去預覽效果,那麼體驗真的是非常的不好,也在很大程度上降低開發效率,所以下面教大家如何用好,用對PreView(針對該庫)。
首先,你要記得你設計稿的尺寸,比如 768 * 1280
然後在你的PreView面板,選擇於設計圖解析度一致的裝置:
然後你就可以看到最為精確的
預覽了:
兩個注意事項:
- 你們UI給的設計圖的尺寸並非是主流的設計圖,該尺寸沒找到,你可以自己去新建一個裝置。
- 不要在PreView中去檢視所有解析度下的顯示,是看不出來適配效果的,因為有些計算是動態的。
擴充套件
對於其他繼承系統的FrameLayout、LinearLayout、RelativeLayout的控制元件,比如CardView
,如果希望再其內部直接支援"px"百分比化,可以自己擴充套件,擴充套件方式為下面的程式碼,也可參考issue#21:
package com.zhy.sample.view;
import android.content.Context;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import com.zhy.autolayout.AutoFrameLayout;
import com.zhy.autolayout.utils.AutoLayoutHelper;
/**
* Created by zhy on 15/12/8.
*/
public class AutoCardView extends CardView
{
private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
public AutoCardView(Context context)
{
super(context);
}
public AutoCardView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public AutoCardView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
}
@Override
public AutoFrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new AutoFrameLayout.LayoutParams(getContext(), attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (!isInEditMode())
{
mHelper.adjustChildren();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
注意事項
ListView、RecyclerView類的Item的適配
sample中包含ListView、RecyclerView例子,具體檢視sample
- 對於ListView
對於ListView這類控制元件的item,預設根區域性寫“px”進行適配是無效的,因為外層非AutoXXXLayout,而是ListView。但是,不用怕,一行程式碼就可以支援了:
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false); convertView.setTag(holder); //對於listview,注意新增這一行,即可在item上使用高度 AutoUtils.autoSize(convertView); } else { holder = (ViewHolder) convertView.getTag(); } return convertView; }
注意AutoUtils.autoSize(convertView);
這行程式碼的位置即可。demo中也有相關例項。
- 對於RecyclerView
public ViewHolder(View itemView) { super(itemView); AutoUtils.autoSize(itemView); } //... @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View convertView = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_item, parent, false); return new ViewHolder(convertView); }
一定要記得LayoutInflater.from(mContext).inflate
使用三個引數的方法!
指定設定的值參考寬度或者高度
由於該庫的特點,佈局檔案中寬高上的1px是不相等的,於是如果需要寬高保持一致的情況,佈局中使用屬性:
app:layout_auto_basewidth="height"
,代表height上編寫的畫素值參考寬度。
app:layout_auto_baseheight="width"
,代表width上編寫的畫素值參考高度。
如果需要指定多個值參考寬度即:
app:layout_auto_basewidth="height|padding"
用|隔開,類似gravity的用法,取值為:
- width,height
- margin,marginLeft,marginTop,marginRight,marginBottom
- padding,paddingLeft,paddingTop,paddingRight,paddingBottom
- textSize.
TextView的高度問題
設計稿一般只會標識一個字型的大小,比如你設定textSize="20px",實際上TextView所佔據的高度肯定大於20px,字的上下都會有一定的間隙,所以一定要靈活去寫字型的高度,比如對於text上下的margin可以選擇儘可能小一點。或者選擇別的約束條件去定位(比如上例,選擇了marginBottom)
常見問題
(1)匯入後出現org/gradle/api/publication/maven/internal/DefaultMavenFactory
最簡單的方式,通過compile 'com.zhy:autolayout:x.x.x'
進行依賴使用,如果一定要以module引用,參考該issue#74
(2)RadioGroup,Toolbar等控制元件中的子View無法完成適配
這個其實上文已經提到過了,需要自己擴充套件。不過這個很多使用者貢獻了他們的擴充套件類可以直接使用,參考autolayout-widget,如果沒有發現你需要的容器類,那麼你就真的需要自行擴充套件了,當然如果你完成了擴充套件,可以給我發個PR,或者讓我知道,我可以加入到autolayout-widget
中方便他人,ps:需要用到哪個copy就好了,不要直接引用autolayout-widget
,因為其引用了大量的庫,可能很多庫你是用不到的。
(3)java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
這個問題是因為預設AutoLayoutActivity會繼承自AppCompatActivity,所以預設需要設定Theme.AppCompat的theme;
如果你使用的依舊是FragmentActivity等,且不考慮使用AppCompatActivity,你可以選擇自己編寫一個MyAutoLayoutActivity extends 目前你使用的Activity基類
,例如MyAutoLayoutActivity extends FragmentActivity
,然後將該庫中AutoLayoutActivity中的邏輯拷貝進去即可,以後你就繼承你的MyAutoLayoutActivity
就好了。
ps:還是建議儘快更新SDK版本使用AppCompatActivity
.
原文連結: