概述
在项目中,我们经常会遇到一种情况,要求动态的生成控件,如TextView,Button,ImageView等。在使用代码生成完这些控件后,你还需要对它们的属性进行设置,如控件大小,背景,权重等。但是你会发现并不是所有的属性,都能够通过该控件自身去设置。比如说:layout_width,layout_height等。后来通过查看文档,知道如果想要设置控件中一些类似“android:layout_xxx”的属性时,你必须要通过LayoutParams来设置。
LayoutParams
LayoutParams这个类是用于子view向parent view (父view)传达自己的意愿的东西,比如子view的宽(layout_width),高(layout_height),外距(layout_margin)的值。其中子view和父view可以简单理解为,一个LinearLayout和这个LinearLayout中包含的TextView的关系。TextView就是LinearLayout的子view。
每一个ViewGroup类都实现了一个继承了ViewGroup.LayoutParams的嵌套类。这个子类包含了为每一个对于view group适当的child view定义尺寸和位置的属性类型。如下图所示:
动态创建一个控件,代码示例:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this); //创建一个LinearLayout布局
linearLayout.setOrientation(LinearLayout.VERTICAL); //设置布局方向为垂直方向
linearLayout.setBackgroundColor(Color.GRAY); //设置LinearLayout的背景色
TextView textView = new TextView(this); //创建一个TextView控件
textView.setText("textview");
textView.setBackgroundColor(Color.RED);
LayoutParams lp = textView.getLayoutParams(); //取得该控件的LayoutParams对象
if(lp !=null){
lp.width = LayoutParams.MATCH_PARENT;
lp.height=LayoutParams.WRAP_CONTENT;
}
lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); //如果为空则重新创建,并设置该控件为MATCH_PARENT形式
textView.setLayoutParams(lp); //将该LayoutParams添加进去
linearLayout.addView(textView); //把TextView加入到LinearLayout布局中来
setContentView(linearLayout);
}
关于setLayoutParams报错问题
在继承BaseAdapter的时候,用getView返回View的时候,用代码控制布局,需要用到View.setLayoutParams,但是会报错,报的是类型转换错误。经过研究,发现,这里不能使用ViewGroup.LayoutParams而必须使用对应父View的LayoutParams类型。如:某View被LinearLayout包含,则该View的setLayoutParams参数类型必须是LinearLayout.LayoutParams。原因在于LinearLayout(或其他继承自ViewGroup的layout,如:RelativeLayout)在进行递归布局的时候,LinearLayout会获取子View的LayoutParams,并强制转换成LinearLayout.LayoutParams,
如:
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();