动态添加综合布局---动态添加控件及将某XML动态加入到Activity显示(续)

前言:之前曾写过一篇关于动态生成控件的文章《动态添加控件及将某XML动态加入到Activity显示》,比较浅显,对于RelativeLayout的相关布局设置方法及相对布局与线性布局的混合使用的相关内容都没有进行深刻讨论。今天再次涉及到这些内容,就再也不单独讨论相对布局的相关设置内容了,直接从相对布局与线性布局的混合应用开始。html

相关文章:《动态添加控件及将某XML动态加入到Activity显示》
java

总效果:android

这里动态生成十个相同的列表,这是最终效果,但凡事都是从易而难的,下面咱们就从XML生成一项内容开始讲解。app

1、利用XML生成一项列表

这里先利用XML生成一项列表开始,先看一项列表的效果图及对应代码:ide

对应的XML代码为:函数

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout_root"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#19000000"
        android:gravity="center_horizontal"
        android:paddingBottom="20dip"
        android:paddingTop="20dip"
        android:text="尝试动态生成列表"
        android:textColor="#ff0000"
        android:textSize="24sp" />

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical" >

        <LinearLayout
            android:id="@+id/list_Lin"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <!-- 动态生成部分开始 -->
             <RelativeLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" >

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="5dip"
                    android:layout_marginRight="10dip"
                    android:layout_toLeftOf="@+id/image"
                    android:background="#ff00ff00"
                    android:orientation="horizontal"
                    android:padding="5dip" >

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="个人第一次经历"
                        android:textColor="#ff000000"
                        android:textSize="20dip" />
                </LinearLayout>

                <ImageView
                    android:id="@+id/image"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:clickable="true"
                    android:padding="5dip"
                    android:src="@drawable/plus" />
            </RelativeLayout>
            <!-- 动态生成部分结束 -->

        </LinearLayout>
    </ScrollView>

</LinearLayout>

动态生成注释里的部分就是咱们将要用代码生成的部分,这里写出来是为了在写代码时参考,如今把注释里的部分删掉,开始在代码中生成。布局

2、使用XML和JAVA代码生成界面

 先贴出完整的代码,而后再逐步讲解。this

 完整代码:spa

package com.example.trydynamiclayout;
/**
 * write by harvic
 * 2014-4-25
 * http://blog.csdn.net/harvic880925
 */
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	private static int id = 100;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		final LinearLayout lin = (LinearLayout) findViewById(R.id.list_Lin); 
		LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		RelativeLayout newSingleRL=new RelativeLayout(this);
		
		for(int i=0;i<10;)
		{
			newSingleRL=generateSingleLayout(id,"第"+(++i)+"个动态列表");
			lin.addView(newSingleRL,LP_FW);//所有用父结点的布局参数
		}
		
		
//		final LinearLayout root = (LinearLayout) findViewById(R.id.layout_root); //获取总根结点
//		setContentView(root); //这里必须是总根结点		
	}
	/**
	 * 新建一个列表item
	 * @param imageID 新建imageView的ID值
	 * @param str  TextView要显示的文字
	 * @return 新建的单项布局变量
	 */
	private RelativeLayout generateSingleLayout(int imageID,String str)
	{
		RelativeLayout layout_root_relative=new RelativeLayout(this);
		
		LinearLayout layout_sub_Lin=new LinearLayout(this);
		layout_sub_Lin.setBackgroundColor(Color.argb(0xff, 0x00, 0xff, 0x00));
		layout_sub_Lin.setOrientation(LinearLayout.VERTICAL);
		layout_sub_Lin.setPadding(5, 5, 5, 5);
		
		TextView tv = new TextView(this);
		LinearLayout.LayoutParams LP_WW = new LinearLayout.LayoutParams(
		LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		tv.setText(str);
		tv.setTextColor(Color.argb(0xff, 0x00, 0x00, 0x00));
		tv.setTextSize(20);
		tv.setLayoutParams(LP_WW);
		layout_sub_Lin.addView(tv);
		
		RelativeLayout.LayoutParams RL_MW = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
				RelativeLayout.LayoutParams.WRAP_CONTENT);//尤为注意这个位置,用的是父容器的布局参数
		RL_MW.setMargins(5, 5, 10, 5);
		RL_MW.addRule(RelativeLayout.LEFT_OF,imageID);
		layout_root_relative.addView(layout_sub_Lin,RL_MW);
		
		
		 ImageView imageView = new ImageView(this);    
		 RelativeLayout.LayoutParams RL_WW = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
					RelativeLayout.LayoutParams.WRAP_CONTENT);
		 imageView.setPadding(5, 5, 5, 5);
		 RL_WW.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
	     imageView.setLayoutParams(RL_WW);  
	     imageView.setClickable(true);
	     imageView.setId(imageID);
	     imageView.setImageResource(R.drawable.plus);
	     layout_root_relative.addView(imageView);
	     
	     return layout_root_relative;
		
	}

}

讲解:
.net

 1、先看generateSingleLayout(int imageID,String str)

 一、看这段代码: 

RelativeLayout layout_root_relative=new RelativeLayout(this);

LinearLayout layout_sub_Lin=new LinearLayout(this);
layout_sub_Lin.setBackgroundColor(Color.argb(0xff, 0x00, 0xff, 0x00));
layout_sub_Lin.setOrientation(LinearLayout.VERTICAL);
layout_sub_Lin.setPadding(5, 5, 5, 5);

TextView tv = new TextView(this);
LinearLayout.LayoutParams LP_WW = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
tv.setText(str);
tv.setTextColor(Color.argb(0xff, 0x00, 0x00, 0x00));
tv.setTextSize(20);
tv.setLayoutParams(LP_WW);
layout_sub_Lin.addView(tv);

RelativeLayout.LayoutParams RL_MW = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
		RelativeLayout.LayoutParams.WRAP_CONTENT);//尤为注意这个位置,用的是父容器的布局参数
RL_MW.setMargins(5, 5, 10, 5);
RL_MW.addRule(RelativeLayout.LEFT_OF,imageID);
layout_root_relative.addView(layout_sub_Lin,RL_MW);

根据上面的XML能够,咱们要首先生成一个RelativeLayout,这就是layout_root_relative。
注意一: (控件的布局参数选择方式)

而后生成其第一个字布局LinearLayout  layout_sub_Lin;而后再生成layout_sub_Lin里惟一的一个控件,注意这里设置LayoutParams的方式,使用的是LinearLayout 参数!!!!对于如何选择当前控件的布局layout_width、layout_height的参数的方法,主要是看其父布局!!!!若是其父布局是LinearLayout 设置其LayoutParams参数时就要使用LinearLayout.LayoutParams,正如这里的TextView tv。而若是其父容器的相对布局呢,同样,换它父布局的来,使用RelativeLayout.LayoutParams RL_MW,如这里的LinearLayout layout_sub_Lin,因此即使layout_sub_Lin本身是布局控件也要按其父容器的布局方法写!!!!  

注意二: layout_toLeftOf的代码书写方法 

在XML中,对于此LinearLayout的相对布局,用到了android:layout_toLeftOf="@+id/image",而在代码中是动态生成的控件,如何利用此规则呢。
首先给动态生成的ImageView设置一个ID值,此ID值在些Acitivity中必须是惟一的,不可冲突的,若是冲突,关于用到此ID值的任何代码都将是无效的!这也就是后面代码中会看到的imageView.setId(imageID);
而后利用addRule()添加规则。

 二、剩余代码就没什么好讲的了,就是生成一个imageView设置ID值及其它参数,而后添加到RelativeLayout中,并将layout_root_relative返回。

 2、onCreate()函数

 这段代码以下:

final LinearLayout lin = (LinearLayout) findViewById(R.id.list_Lin); 
LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(
		LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout newSingleRL=new RelativeLayout(this);

for(int i=0;i<10;)
{
	newSingleRL=generateSingleLayout(id,"第"+(++i)+"个动态列表");
	lin.addView(newSingleRL,LP_FW);//所有用父结点的布局参数
}


final LinearLayout root = (LinearLayout) findViewById(R.id.layout_root); //获取总根结点
setContentView(root); //这里必须是总根结点

一、先看For循环及其上部的代码:

final LinearLayout lin = (LinearLayout) findViewById(R.id.list_Lin);

找到当前新生成的ITEM项的插入位置。

LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(
		LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
newSingleRL=generateSingleLayout(id,"第"+(++i)+"个动态列表");
lin.addView(newSingleRL,LP_FW);//所有用父结点的布局参数

这里是两块代码,先看第二块,先是新生成一项,注意这一项返回的结点是RelativeLayout layout_root_relative,而后将其插入到列表位置中去,注意要插入的布局是LinearLayout lin,也就是layout_root_relative的父结点是LinearLayout,因此这也就是在addView时为何它对应的布局参数使用LinearLayout.LayoutParams的缘由了!
 二、setContentView(root);显示视图 

 这段代码以下:

final LinearLayout root = (LinearLayout) findViewById(R.id.layout_root); //获取总根结点
setContentView(root); //这里必须是总根结点

这里最注意的一点,setContentView()所设置的视图结点是整个XML的根结点!!!!设置为其它结点会发生异常!!!很容易理解。

 

更正:

在原来的onCreate代码中,在代码的最后,加上了

final LinearLayout root = (LinearLayout) findViewById(R.id.layout_root); //获取总根结点
setContentView(root); //这里必须是总根结点
其实这样作是彻底没有必要的,直接将这两句删除,效果是彻底同样的。

缘由在于,在其上面的代码中,咱们经过

final LinearLayout lin = (LinearLayout) findViewById(R.id.list_Lin);
找到了要插入布局的结点位置,直接在其下面插入布局代码,界面会自动更新,根本不须要从新setContentView()

在博客中,我将这两句无关代码注释了起来,而源码中没有更改过来,请你们注意一下,因为当时刚接触这部分,对你们形成的误导,深表歉意……


 (源码中有两句代码彻底没必要要加,请看博客“更正”部分)

 源码下载地址:http://download.csdn.net/detail/harvic880925/7250631,不要分,仅供分享!

 

3、彻底使用JAVA代码生成UI界面

这部分其实在上面的改动不大,只是彻底使用代码构建整个界面,因为这种方法构建UI可维护性不好,因此不推荐使用。

其它代码不变,OnCreate()函数代码以下:

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
//		setContentView(R.layout.activity_main);
		
		final LinearLayout lin = new LinearLayout(this);
		lin.setOrientation(LinearLayout.VERTICAL);
		LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		RelativeLayout newSingleRL=new RelativeLayout(this);
		
		for(int i=0;i<10;)
		{
			newSingleRL=generateSingleLayout(id,"第"+(++i)+"个动态列表");
			lin.addView(newSingleRL,LP_FW);//所有用父结点的布局参数
		}
		
		setContentView(lin); //这里必须是总根结点		
	}
效果图:


该部分源码地址:http://download.csdn.net/detail/harvic880925/7692059



请你们尊重做者原创版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/24464537