LayoutParams
每個 ViewGroup (例如 LinearLayout , RelativeLayout , CoordinatorLayout 等)都需要儲存有關其子項屬性的資訊。關於他們的孩子在這裡鋪設的方式 5。此資訊儲存在包裝類 ViewGroup.LayoutParams 的物件中。
要包含特定佈局型別的引數,ViewGroups 使用 ViewGroup.LayoutParams 類的子類。
例如
LinearLayout它是LinearLayout.LayoutParamsRelativeLayout它是RelativeLayout.LayoutParamsCoordinatorLayout它是CoordinatorLayout.LayoutParams- …
大多數 ViewGroups 都重新使用了為孩子設定 margins 的能力,因此他們不直接將 ViewGroup.LayoutParams 子類化,但是他們將 ViewGroup.MarginLayoutParams 子類化 (它本身是 ViewGroup.LayoutParams 的子類)。
LayoutParams in xml
LayoutParams 物件是基於膨脹的佈局 xml 檔案建立的。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="right"
android:gravity="bottom"
android:text="Example text"
android:textColor="@android:color/holo_green_dark"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@android:color/holo_green_dark"
android:scaleType="centerInside"
android:src="@drawable/example"/>
</LinearLayout>
所有以 layout_ 開頭的引數都指定了封閉佈局應該如何工作。當佈局膨脹時,這些引數被包裹在一個合適的 LayoutParams 物件中,Layout 稍後將使用該物件將特定的 View 正確定位在 ViewGroup 內。View 的其他屬性直接與 View 相關,並由 View 本身處理。
對於 TextView:
layout_width,layout_height和layout_gravity將儲存在LinearLayout.LayoutParams物件中並由LinearLayout使用gravity,text和textColor將由TextView本身使用
對於 ImageView:
layout_width,layout_height和layout_weight將儲存在LinearLayout.LayoutParams物件中並由LinearLayout使用ImageView,scaleType和src將由ImageView本身使用
獲取 LayoutParams 物件
getLayoutParams 是一個 View's 方法,允許檢索當前的 LayoutParams 物件。
因為 LayoutParams 物件與封閉的 ViewGroup 直接相關,所以只有當 View 附加到 ViewGroup 時,此方法才會返回非空值。你需要記住,此物件可能始終不存在。特別是你不應該依賴於 View's 建構函式。
public class ExampleView extends View {
public ExampleView(Context context) {
super(context);
setupView(context);
}
public ExampleView(Context context, AttributeSet attrs) {
super(context, attrs);
setupView(context);
}
public ExampleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupView(context);
}
private void setupView(Context context) {
if (getLayoutParams().height == 50){ // DO NOT DO THIS!
// This might produce NullPointerException
doSomething();
}
}
//...
}
如果你想依賴 LayoutParams 物件,你應該使用 onAttachedToWindow 方法代替。
public class ExampleView extends View {
public ExampleView(Context context) {
super(context);
}
public ExampleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExampleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (getLayoutParams().height == 50) { // getLayoutParams() will NOT return null here
doSomething();
}
}
//...
}
轉換 LayoutParams 物件
你可能需要使用特定於 ViewGroup 的功能(例如,你可能希望以程式設計方式更改 RelativeLayout 的規則)。為此,你需要知道如何正確地投射 ViewGroup.LayoutParams 物件。
當為一個孩子獲得一個 LayoutParams 物件時,這可能有點令人困惑,這實際上是另一個 ViewGroup。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/outer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/inner_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="right"/>
</LinearLayout>
重要提示: LayoutParams 物件的型別與 ENCLOSING ViewGroup 的型別直接相關。
***** 轉換錯誤* :
FrameLayout innerLayout = (FrameLayout)findViewById(R.id.inner_layout);
FrameLayout.LayoutParams par = (FrameLayout.LayoutParams) innerLayout.getLayoutParams();
// INCORRECT! This will produce ClassCastException
正確轉換 :
FrameLayout innerLayout = (FrameLayout)findViewById(R.id.inner_layout);
LinearLayout.LayoutParams par = (LinearLayout.LayoutParams) innerLayout.getLayoutParams();
// CORRECT! the enclosing layout is a LinearLayout