使用Android源生解析xml文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Marswin89/article/details/45722407

 TypedArray相信大家都不陌生,他用于android自定义View中对自定义属性的解析。他的方便之处在于可以直接将例如@drawable/test_drawable这样的图片直接解析成一个Drawable对象,又可以将10dp这样的单位,在代码中直接拿到换算好的px值,方便之处不言而喻。

ok,现在问题来了,如果我只想用一个xml文件作为我一个模块的配置文件,又不想自己去pull解析xml,去解析哪些dp,reference的字符串,该怎么办呢?

废话结束。

首先在values文件夹下创建attrs.xml文件用来编写约束的描述

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="test_attrs">
        <attr name="key" format="string" />
        <attr name="vercode" format="integer" />
        <attr name="background" format="reference" />
        <attr name="height" format="dimension" />
        <attr name="width" format="dimension" />
    </declare-styleable>
</resources>


然后在xml文件夹下创建被约束的配置文件test.xml

<?xml version="1.0" encoding="utf-8"?>
<resource xmlns:aaa="http://schemas.android.com/apk/res/com.example.test1">
    <test
        aaa:key="key_test"
        aaa:vercode="1002"
        aaa:background="@drawable/bubble"
        aaa:height="100dp"
        aaa:width="200dp"
        ></test>
</resource>


最后就可以在代码中获取这些数据了

public static void parse(Context context, int resourceId){
		TypedArray typedArray = getTypedArrayFromResource(context, resourceId, R.styleable.guide, "test");
		if(typedArray == null){
			return null;
		}
		String key = typedArray.getString(R.styleable.test_attrs_key);
		int vercode = typedArray.getInteger(R.styleable.test_attrs_vercode, 0);
		Drawable background = typedArray.getDrawable(R.styleable.<span style="font-family: Arial, Helvetica, sans-serif;">test_attrs_background</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
		int height = typedArray.getInteger(R.styleable.test_attrs_height, 0);
		int width = typedArray.getInteger(R.styleable.test_attrs_width, 0);
		if(typedArray != null){
			typedArray.recycle();
		}
		//TODO do something you want
		
	}
	
	
	
	/**
	 * 通过xml资源文件、其对应的attrs约束文件,获取对应TypedArray</br>
	 * <b>记得用完要释放。</b>
	 * @param context
	 * @param resourceId xml资源id
	 * @param attributeSchema attrs约束定义文件id
	 * @param tagName 需要解析的标签名称
	 * @return
	 */
	@SuppressLint("Recycle")
	private static TypedArray getTypedArrayFromResource(Context context, int resourceId, int[] attributeSchema, String tagName){
		TypedArray typedArray = null;
		try {
			if(context == null){
				throw new Exception("Context is null in GuiderFactory, cannot fetch TypedArray.");
			}
		    Resources resource = context.getResources();
		    if(resource == null){
		    	throw new Exception("Resource is null in GuiderFactory, cannot fetch TypedArray.");
		    }
		    XmlResourceParser parser = resource.getLayout(resourceId);
		    if(parser == null){
		    	throw new Exception("Parser is null in GuiderFactory, cannot fetch TypedArray.");
		    }
		    AttributeSet attributeSet = null;
		    int state = 0;
		    do {
		        if (state == XmlPullParser.START_TAG && parser.getName().equals(tagName)) {
		        	attributeSet = Xml.asAttributeSet(parser);
		        	break;
		        }
		    } while(state != XmlPullParser.END_DOCUMENT);
		    if(attributeSet == null){
		    	throw new Exception("AtrributeSet is null in GuiderFactory, cannot fetch TypedArray.");
		    }
		    typedArray = context.obtainStyledAttributes(attributeSet, attributeSchema);
		}catch (Exception e) {
			e.printStackTrace();
		}
		return typedArray;
	}


其实就是将没用的标签过滤掉没用的标签,拿到想要的标签对象。然后生成 AttributeSet, 就可以像在自定义view的构造方法中那样obtain一个TypedArray了。至于其中源码的分析以后有时间再写。最后把attrs可以定义的几种format写一下。


reference  资源引用

string 字符串

color 颜色值,可以直接获取到Color

boolean 布尔值

demension 像素值,自动获取本机的对应demention并且换算为px

float 浮点

integer 整型

fraction 百分数,这个说一下,用在animation的定义上,rotateanimation中的属性pivotX="50%"

enum 枚举。写法为

<declare-styleable name="名称"> 
                   <attr name="orientation"> 
                          <enum name="horizontal" value="0" /> 
                          <enum name="vertical" value="1" /> 
                   </attr>             
</declare-styleable>

flag 位或运算。其实就是枚举是单选,位或运算可以是多选。写法如下

<declare-styleable name="名称"> 
                    <attr name="windowSoftInputMode"> 
                            <flag name = "stateUnspecified" value = "1" /> 
                            <flag name = "stateUnchanged" value = "2" /> 
<pre name="code" class="html"><span style="white-space:pre">			</span>    <flag name = "stateHiden" value = "4" /> 
                 /**.......*/                     </declare-styleable> 
 
 
这样用户在设置的属性的时候可以设置 stateUnspecified |  stateUnchanged,与或非用好了真心能解决不少问题。今天就到这里


猜你喜欢

转载自blog.csdn.net/Marswin89/article/details/45722407