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