LayoutParams分类和作用
LayoutParams是ViewGroup类中的子类,而ViewGroup我们都知道,它是容纳组件的容器。比如说:LinearLayout,ListView都是继承ViewGroup的。LayoutParams主要设置的是子view在父类布局的参数,有如下两种方式:
(1)通过XML文件定义
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">
<textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="xiaotang">
</textview></relativelayout>
可以看到,TextView需要设置layout_width和layout_height参数,才能在父布局中显示出来。
(2)通过java代码添加View
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout contentView = (RelativeLayout) View.inflate(this,
R.layout.activity_main, null);
TextView tv = new TextView(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
new LayoutParams(-1, -1));
tv.setText("xiaotang");
contentView.addView(tv);
}
可以看到在java代码中添加view,需要设置其在父布局中的布局参数,才能顺利显示出来.当然在这里,你不申明lp布局参数也可,contentView.addView(tv)会判断你是否设置view的布局参数,若没设置,则默认提供Warp_content类的布局参数.那么View的LayoutParams为什么要设置成RelativeLayout类型呢?后面我们会详细讨论的.
View的LayoutParams与父类的关系
View的LayoutParams设置在父类里面才能起到效果.大家应该重视这句话,你真正理解了这句话了吗?接下来,我们用一个Code来说明:
我们在Layout里面申明了一个textview.xml文件,内容如下:
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">
<textview android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/red" android:text="xiaotang">
</textview></linearlayout>
MainActivity代码如下:
运行截图如下:
可以看到在textview.xml中申明的LayoutParams为fill_parent,但是显示的时候却还是warp_content,那么要全屏显示TextView,我们该如何做呢?
代码如下:
运行截图如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout contentView = (RelativeLayout) View.inflate(this,
R.layout.activity_main, null);
View view = View.inflate(this, R.layout.textview, null);
contentView.addView(view);
}
在这里,我没有设置view的LayoutParams,contentView.addView()时会添加warp_content的布局参数。有朋友就要问了,在textview.xml中不是已经设置View的布局为Fill_Parent吗?为什么还要设置呢?还是我说的那句话,view的布局参数只有在父类中申明(也就是父类.LayoutParams)才能正确显示,我们看结果就能说明一切了.
运行截图如下:

可以看到在textview.xml中申明的LayoutParams为fill_parent,但是显示的时候却还是warp_content,那么要全屏显示TextView,我们该如何做呢?
代码如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout contentView = (RelativeLayout) View.inflate(this,
R.layout.activity_main, null);
View view = View.inflate(this, R.layout.textview, null);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
view.setLayoutParams(lp);
contentView.addView(view);
setContentView(contentView);
}
通过将view的布局参数设置为FILL_PARENT,那么TextView组件的背景就全屏显示了,说明布局起到了作用!
运行截图如下:

为什么view的LayoutParams要是父容器的的LayoutParams
大家看我上面的举的实例中,细心的你就会发现。为什么view放在contentView中,申明的lp(布局参数)都是RelativeLayout类的?原因就是装载该View的容器就是RelativeLayout.我们再看看下面这个例子:
Display display = this.getWindowManager().getDefaultDisplay();
int width = display.getWidth(); // 获取屏幕宽度
int height = display.getHeight(); // 获取屏幕高度
View head = View.inflate(this, R.layout.head, null);
AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, this.getResources()
.getDimensionPixelOffset(R.dimen.top_bg_height));
head.setLayoutParams(layoutParams);
listView.addHeaderView(head);
这是ListView添加View的例子,可以看到view的LayoutParams的类型就是AbsListView(ListView继承AbsListView并且在ListView中没有修改该LayoutParams).
原因分析:
我们都知道,每一个视图的绘制过程都必须经历三个最主要的阶段,即onMeasure()、onLayout()和onDraw(),父容器不仅要负责自己的显示,而且还要遍历取负责子组件的显示.我们查看容器的onMeasure()方法就能看到有如下操作:
这里以RelativeLayout为例:
这里以RelativeLayout为例:
LayoutParams params = (LayoutParams) child.getLayoutParams(); //这里的LayoutParams是RelativeLayout类型
个人疑惑
大家请看下面代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout contentView = (RelativeLayout) View.inflate(this,
R.layout.activity_main, null);
View view = View.inflate(this, R.layout.textview, null);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
lp.topMargin=20;
view.setLayoutParams(lp);
contentView.addView(view);
setContentView(contentView);
}