I used XML to control the theme of an InputMethod
for Android. A theme in XML contains the color and the shape of keys.
XML file
<theme>
<color name="FIRST_LINE_LETTER_COLOR" value="#263238"></color>
<color name="SECOND_LINE_LETTER_COLOR" value="#263238"></color>
<color name="THIRD_LINE_LETTER_COLOR" value="#263238"></color>
<color name="PIN_KEY_COLOR" value="#263238"></color>
<color name="PIN_KEY_PRESSED_COLOR" value="#80CBC4"></color>
<shape name="PIN_KEY_SHAPE" value="circle"></shape>
</theme>
ThemeXmlParser.java
import android.content.Context;
import android.graphics.Color;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ThemeXmlParser {
private Context context;
private static Map<String, Integer> colorMap;
private static Map<String, String> configMap;
private ThemeXmlParser(Context ctx) {
context = ctx;
colorMap = new HashMap<String, Integer>();
configMap = new HashMap<String, String>();
}
public static ThemeXmlParser newInstance(Context ctx) {
return new ThemeXmlParser(ctx);
}
private String selectAssetsPath(String scheme) {
String path = "";
if (scheme.equals(XMLStr.Theme.google_dark)) {
path = "themes/google_dark_theme.xml";
} else {
//todo add other skins
}
return path;
}
public void parse(String scheme) {
String assetsPath = selectAssetsPath(scheme);
InputSource is = null;
try {
is = new InputSource(context.getAssets().open(assetsPath));
} catch (IOException e) {
e.printStackTrace();
}
if (is != null) {
doParse(is);
}
}
public static Map<String, Integer> colorMap() {
return colorMap;
}
public static Map<String, String> configMap() {
return configMap;
}
private void doParse(InputSource is) {
XMLReader xmlReader = createXMLReader();
ColorHandler colorHandler = new ColorHandler();
xmlReader.setContentHandler(colorHandler);
try {
xmlReader.parse(is);
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private XMLReader createXMLReader() {
XMLReader reader = null;
SAXParser saxParser = createSAXParser();
try {
reader = saxParser.getXMLReader();
} catch (SAXException e) {
e.printStackTrace();
}
return reader;
}
private SAXParser createSAXParser() {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = null;
try {
saxParser = factory.newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
return saxParser;
}
class ColorHandler extends DefaultHandler {
@Override
public void startElement(String uri, String localName, String qName,
Attributes attrs) throws SAXException {
String name = attrs.getValue(0);
String value = attrs.getValue(1);
try {
if (value.startsWith("#")) {
//color
int color = toColor(value);
colorMap.put(name, color);
} else {
//config
configMap.put(name, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param colorStr: #FFFFFF
* @return:Color.rgb(256, 256, 256)
*/
private int toColor(String colorStr) {
return Color.parseColor(colorStr);
}
}
}
I'd like to focus on:
- The best library for parsing XML
- The best code style that obeys software engineering
- The best way to handle these exceptions