动态布局还是先从我们的需求出发,近期做的一个项目中提到了了一个需求:

 

需要动态的生成一个表单,表单中的标题、选项、提示文字等都是可以动态的增加删除的,而且动态的配置文件是xml文件。

 

我们在写html的使用常常就用如此的方式来制作配置自己的html页面,因为接到这个需求的时候正是该网站向拓展自己的无线业务,故此,直接将自己的网页端应用数据与无线端绑定到一起去了。

如:

<!-- 机械 -->
	<machine>
        
        <hint>请简单描述机械综合状况。。。如:启动车辆,发动机运转正常,怠速平稳无异响,行驶过程中转向、制动良好。</hint>
        
		<question>
			<title>发动机</title>
			<option>运转正常</option>
			<option>轻微异响</option>
			<option>异响</option>				
		</question>
		
		
		<question>
			<title>变速箱</title>
			<option>怠速平稳</option>
			<option>轻微冲档</option>
			<option>冲档</option>
		</question>
		
		<question>
			<title>刹车制动</title>
			<option>良好</option>
			<option>一般</option>
			<option>需要修理</option>
		</question>
		
		<question>
			<title>引擎箱</title>
			<option>清洁</option>
			<option>轻微渗油</option>
			<option>室盖渗油</option>
		</question>
        
	</machine>


我们希望解析此段xml数据能够得到与网站类似的界面


android 动态加载xml文件 安卓动态加载xml布局_android 动态加载xml文件

分析

         Android的界面布局就是有N多个layout.xml组成的。所以,解析xml对于Android系统来说是完全可行的。

 

 在移动Android平台上我们能够用Simple API forXML(SAX) 、 Document Object Model(DOM)和Android附带的pull解析器解析XML文件。

1. SAX解析XML文件

        SAX是一个解析速度快并且占用内存少的xml解析器,采用的是事件驱动,非常适合用于Android等移动设备。

2. DOM解析XML文件

     DOM解析XML文件时,会将XML文件的所有内容读取到内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来比较直观。

3.Pull解析与SAX类似

 

实际上我们使用的是一个开源的Html、Xml解析器Jsoup。jsoup 是一款 Java 的HTML 解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操作数据。最主要的原因是,开源小巧,我们可以方便的移植到后代的Jsp服务端去。

Jsoup的使用也比较简单,可以去到官网:http://jsoup.org/看看简单的demo就会了。下面是我用Jsoup解析之前的xml代码段。


public Questions getData(String tagName)
    {
        AssetManager am = null;
        am = m_context.getAssets();

        try
        {
            //打开Assets文件夹下的 question.xml文件 获得输入流
            inputStream = am.open(Constant.QUESTION_XML_PATH);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        Questions questionList = new Questions(m_context);
        Question question = null;
        Document doc = null;
        try
        {   
            //使用Jsoup载入xml文件中的数据,默认编码UTF-8
            doc = Jsoup.parse(inputStream, "UTF-8", "");
        }
        catch (IOException e1)
        {
            e1.printStackTrace();
        }
        //得到首个元素
        Element element = doc.select(tagName).first();
        //得到<hint></hint>中的值
        String hint = element.getElementsByTag("hint").html();
        questionList.setHint(hint);
        //获取每一个<question>中的数据,并且打包为question 类
        Elements qElements = element.getElementsByTag("question");
        for (Element e : qElements)
        {
            question = new Question();
            Elements optionElements = e.getAllElements();
            for (Element op : optionElements)
            {
                String name = op.tagName();
                //获取<title></title>中的值
                if ("title".equalsIgnoreCase(name) )
                    question.setTitle(op.html());
                //将多个<option>添加如列表
                else if ("option".equalsIgnoreCase(name))
                {
                    if (question.options == null)
                        question.options = new ArrayList<String>();
                    question.options.add(op.html());
                }
            }
            if (questionList.questions == null)
                questionList.questions = new ArrayList<Question>();
            questionList.questions.add(question);
        }
        close();
        return questionList;
    }



而question类中我们只需要存储几个较为简单的数据就可以了。



/**
 * @author zhoushengtao
 * @since 2013-6-26 上午9:36:17
 */

package com.stchou.paiche.pojo;

import java.util.ArrayList;

public class Question
{
    private String title;
    private String select = "";//存储选择的结果,方便输出
    public ArrayList<String> options = new ArrayList<String>();

    public String getTitle()
    {
        return this.title;
    }

    public void setTitle(String title)
    {
        this.title = title;
    }

    public String getSelect()
    {
        return this.select;
    }

    public void setSelect(String select)
    {
        this.select = select;
    }

    public int getPosition()
    {
        for(int i=0;i<options.size();i++)
            if(options.get(i).equals(select))
                return i;
        return 0;
    }
    
    @Override
    public String toString()
    {
        if (select.length() == 0)
            select = options.get(0);
        String textString = "<question>\n";
        textString += "<title>" + title + "</title>\n";
        if (options != null)
            for (String text : options)
                textString += "<option>" + text + "</option>\n";
        textString += "<selected>" + select + "</selected>\n";
        textString += "</question>\n";
        return textString;
    }

}





   获得了我们根据xml解析来的数据之后再界面上的布局就很简单了,但是值得注意的是,我们平时使用的是layout.xml文件针对Android的Activity来布局,这里我们获得的是Question类,只能在代码中给其进行布局。这个没有一个所见即所得的界面写起来还是有点吃力。所以,根据布局还是的分析好自己的布局方式,在layout中写写,看看出来的效果,再从代码上各具xml自动生成的布局方式去布局,这样做起来比较简单。

效果图


android 动态加载xml文件 安卓动态加载xml布局_Android_02