android 中布局一般都是在layout中用xml写好的,但有时候为了简化,也会用java代码生成布局,今天就简单讲讲。
在layout中用xml写的布局
<?xml version="1.0" encoding="utf-8"?><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:id="@+id/text_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="TextView1" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_camera2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_gravity="center"
android:text="TextView2" />
</FrameLayout>
</LinearLayout>
用xml一目了然,但若用代码的话,首先最外层LinearLayout LinearLayout mLinearLayout = new LinearLayout(this);
对应xml布局中:
// android:layout_width="match_parent"
// android:layout_height="match_parent"
mLinearLayout.setLayoutParams(new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// 设置方向,对应xml布局中:
// android:orientation="vertical"
mLinearLayout.setOrientation(LinearLayout.VERTICAL);
TextView mTextView1 = new TextView(this);
mTextView1.setText("TextView1");
// 控件的宽和高,如同上面
LinearLayout.LayoutParams mLayoutParams = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// 在父类布局中添加它,及布局样式
mLinearLayout.addView(mTextView1, mLayoutParams);
// 帧布局
FrameLayout mFrameLayout = new FrameLayout(this);
mFrameLayout.setLayoutParams(new FrameLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
// TextView 布局,第二种写法
TextView mTextView2 = new TextView(this);
mTextView2.setText("TextView2");
// 控件的宽和高,如同上面
FrameLayout.LayoutParams mLayoutParams2 = new FrameLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mLayoutParams2.leftMargin = 20;
mLayoutParams2.topMargin = 20;
mLayoutParams2.rightMargin = 20;
mLayoutParams2.bottomMargin = 20;
mLayoutParams2.gravity = Gravity.CENTER;
mTextView2.setLayoutParams(mLayoutParams2);
mFrameLayout.addView(mTextView2);
mLinearLayout.addView(mFrameLayout);
如此,java代码也基本完成布局,还欠缺一个id
在values文件夹中创建ids.xml,添加如下代码,name为引用的名称,type表示该资源类型是一个id
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="text_camera" type="id">text_camera</item>
<item name="text_camera2" type="id">text_camera2</item>
</resources>
mTextView1.setId(R.id.text_camera);
mTextView2.setId(R.id.text_camera2);完工。
在这里要注意几点,比如说text2,外面是个帧布局,并且为居中,所以,设置居中属性应该在自己的LayoutParams里面设置,设置LayoutParams 时,通过LayoutParams 设置view控件的大小,margin值和pandding值,然后是一些线性、相对、帧布局等私有属性。如果一个textview已经设置过大小,想从新设置大小和一些属性,则可以代码 LayoutParams layoutParams = mTextView2.getLayoutParams();此时,默认的LayoutParams是ViewGroup.LayoutParams,如果用这个只能用ViewGroup.LayoutParams的
属性,public int width; public int height; 宽和高两个属性;如果读过几大布局和ViewGroup的代码,会发现LayoutParams继承关系,LayoutParams设置时层层嵌套,ViewGroup.LayoutParams是顶级父类,第一个关联的子类便是MarginLayoutParams,所以public int leftMargin;public int topMargin;public int rightMargin;public int bottomMargin;这四个属性也可以设置使用了,比着ViewGroup.LayoutParams多出了四个属性;再进一步,常用的有 LinearLayout.LayoutParams FrameLayout.LayoutParams 和
RelativeLayout.LayoutParams,比如说,上述强转时用哪个呢?这个不是随便用的,而是根据这个text2的父容器是什么类型,是相对、线性还是帧布局,就要转换成对应的LayoutParams才会运行成功。上述text2是在帧布局中,则FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mTextView2.getLayoutParams();
这样,public int gravity = -1;这个属性可以使用,设置居中,居左或是局右等等;如果是LinearLayout.LayoutParams, public float weight;public int gravity = -1;可以设置权
重和位置;至于一些例如padding,text,background等等,是通过View来提供接口设置值。
ViewGroup是如何添加元素呢,看源码
public void addView(View child) {
addView(child, -1); // 方法重载,默认添加到下一个位置
}
public void addView(View child, int index) {
LayoutParams params = child.getLayoutParams();//获取LayoutParams
if (params == null) {
params = generateDefaultLayoutParams();//如果没有,则设置一个默认的值,大小为包裹内容
if (params == null) {
throw new IllegalArgumentException("generateDefaultLayoutParams() cannot
return null");
}
}
addView(child, index, params);
}
protected LayoutParams generateDefaultLayoutParams() {
//设置一个大小为包裹内容的值
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
public void addView(View child, LayoutParams params) {
addView(child, -1, params);
}
public void addView(View child, int index, LayoutParams params) {
if (DBG) {
System.out.println(this + " addView");
}
requestLayout();//重新布局
invalidate(true);//刷新
addViewInner(child, index, params, false);//内容太多,具体添加在这
}