可参考XmlResourceParser类对xml标签的解析:
public SoftKeyboard loadKeyboard(int resourceId, int skbWidth, int skbHeight) {
if (null == mContext) return null;
Resources r = mResources;
SkbPool skbPool = SkbPool.getInstance();
XmlResourceParser xrp = mContext.getResources().getXml(resourceId);
mSkbTemplate = null;
SoftKeyboard softKeyboard = null;
Drawable skbBg;
Drawable popupBg;
Drawable balloonBg;
SoftKey softKey = null;
KeyCommonAttributes attrDef = new KeyCommonAttributes(xrp);
KeyCommonAttributes attrSkb = new KeyCommonAttributes(xrp);
KeyCommonAttributes attrRow = new KeyCommonAttributes(xrp);
KeyCommonAttributes attrKeys = new KeyCommonAttributes(xrp);
KeyCommonAttributes attrKey = new KeyCommonAttributes(xrp);
mKeyXPos = 0;
mKeyYPos = 0;
mSkbWidth = skbWidth;
mSkbHeight = skbHeight;
try {
mKeyXMargin = 0;
mKeyYMargin = 0;
mXmlEventType = xrp.next();
while (mXmlEventType != XmlResourceParser.END_DOCUMENT) {
mNextEventFetched = false;
if (mXmlEventType == XmlResourceParser.START_TAG) {
String attr = xrp.getName();
// 1. Is it the root element, "keyboard"?
if (XMLTAG_KEYBOARD.compareTo(attr) == 0) {
// 1.1 Get the keyboard template id.
int skbTemplateId = xrp.getAttributeResourceValue(null,
XMLATTR_SKB_TEMPLATE, 0);
// 1.2 Try to get the template from pool. If it is not
// in, the pool will try to load it.
mSkbTemplate = skbPool.getSkbTemplate(skbTemplateId,
mContext);
if (null == mSkbTemplate
|| !attrSkb.getAttributes(attrDef)) {
return null;
}
boolean cacheFlag = getBoolean(xrp,
XMLATTR_SKB_CACHE_FLAG, DEFAULT_SKB_CACHE_FLAG);
boolean stickyFlag = getBoolean(xrp,
XMLATTR_SKB_STICKY_FLAG,
DEFAULT_SKB_STICKY_FLAG);
boolean isQwerty = getBoolean(xrp, XMLATTR_QWERTY,
false);
boolean isQwertyUpperCase = getBoolean(xrp,
XMLATTR_QWERTY_UPPERCASE, false);
softKeyboard = new SoftKeyboard(resourceId,
mSkbTemplate, mSkbWidth, mSkbHeight);
softKeyboard.setFlags(cacheFlag, stickyFlag, isQwerty,
isQwertyUpperCase);
mKeyXMargin = getFloat(xrp, XMLATTR_KEY_XMARGIN,
mSkbTemplate.getXMargin());
mKeyYMargin = getFloat(xrp, XMLATTR_KEY_YMARGIN,
mSkbTemplate.getYMargin());
skbBg = getDrawable(xrp, XMLATTR_SKB_BG, null);
popupBg = getDrawable(xrp, XMLATTR_POPUP_BG, null);
balloonBg = getDrawable(xrp, XMLATTR_BALLOON_BG, null);
if (null != skbBg) {
softKeyboard.setSkbBackground(skbBg);
}
if (null != popupBg) {
softKeyboard.setPopupBackground(popupBg);
}
if (null != balloonBg) {
softKeyboard.setKeyBalloonBackground(balloonBg);
}
softKeyboard.setKeyMargins(mKeyXMargin, mKeyYMargin);
} else if (XMLTAG_ROW.compareTo(attr) == 0) {
if (!attrRow.getAttributes(attrSkb)) {
return null;
}
// Get the starting positions for the row.
mKeyXPos = getFloat(xrp, XMLATTR_START_POS_X, 0);
mKeyYPos = getFloat(xrp, XMLATTR_START_POS_Y, mKeyYPos);
int rowId = getInteger(xrp, XMLATTR_ROW_ID,
KeyRow.ALWAYS_SHOW_ROW_ID);
softKeyboard.beginNewRow(rowId, mKeyYPos);
} else if (XMLTAG_KEYS.compareTo(attr) == 0) {
if (null == softKeyboard) return null;
if (!attrKeys.getAttributes(attrRow)) {
return null;
}
String splitter = xrp.getAttributeValue(null,
XMLATTR_KEY_SPLITTER);
splitter = Pattern.quote(splitter);
String labels = xrp.getAttributeValue(null,
XMLATTR_KEY_LABELS);
String codes = xrp.getAttributeValue(null,
XMLATTR_KEY_CODES);
if (null == splitter || null == labels) {
return null;
}
String labelArr[] = labels.split(splitter);
String codeArr[] = null;
if (null != codes) {
codeArr = codes.split(splitter);
if (labelArr.length != codeArr.length) {
return null;
}
}
for (int i = 0; i < labelArr.length; i++) {
softKey = new SoftKey();
int keyCode = 0;
if (null != codeArr) {
keyCode = Integer.valueOf(codeArr[i]);
}
softKey.setKeyAttribute(keyCode, labelArr[i],
attrKeys.repeat, attrKeys.balloon);
softKey.setKeyType(mSkbTemplate
.getKeyType(attrKeys.keyType), null, null);
float left, right, top, bottom;
left = mKeyXPos;
right = left + attrKeys.keyWidth;
top = mKeyYPos;
bottom = top + attrKeys.keyHeight;
if (right - left < 2 * mKeyXMargin) return null;
if (bottom - top < 2 * mKeyYMargin) return null;
softKey.setKeyDimensions(left, top, right, bottom);
softKeyboard.addSoftKey(softKey);
mKeyXPos = right;
if ((int) mKeyXPos * mSkbWidth > mSkbWidth) {
return null;
}
}
} else if (XMLTAG_KEY.compareTo(attr) == 0) {
if (null == softKeyboard) {
return null;
}
if (!attrKey.getAttributes(attrRow)) {
return null;
}
int keyId = this.getInteger(xrp, XMLATTR_ID, -1);
if (keyId >= 0) {
softKey = mSkbTemplate.getDefaultKey(keyId);
} else {
softKey = getSoftKey(xrp, attrKey);
}
if (null == softKey) return null;
// Update the position for next key.
mKeyXPos = softKey.mRightF;
if ((int) mKeyXPos * mSkbWidth > mSkbWidth) {
return null;
}
// If the current xml event type becomes a starting tag,
// it indicates that we have parsed too much to get
// toggling states, and we started a new row. In this
// case, the row starting position information should
// be updated.
if (mXmlEventType == XmlResourceParser.START_TAG) {
attr = xrp.getName();
if (XMLTAG_ROW.compareTo(attr) == 0) {
mKeyYPos += attrRow.keyHeight;
if ((int) mKeyYPos * mSkbHeight > mSkbHeight) {
return null;
}
}
}
softKeyboard.addSoftKey(softKey);
}
} else if (mXmlEventType == XmlResourceParser.END_TAG) {
String attr = xrp.getName();
if (XMLTAG_ROW.compareTo(attr) == 0) {
mKeyYPos += attrRow.keyHeight;
if ((int) mKeyYPos * mSkbHeight > mSkbHeight) {
return null;
}
}
}
// Get the next tag.
if (!mNextEventFetched) mXmlEventType = xrp.next();
}
xrp.close();
softKeyboard.setSkbCoreSize(mSkbWidth, mSkbHeight);
return softKeyboard;
} catch (XmlPullParserException e) {
// Log.e(TAG, "Ill-formatted keybaord resource file");
} catch (IOException e) {
// Log.e(TAG, "Unable to read keyboard resource file");
}
return null;
}