若转载请注明出处!
本文的主题思想是:
1》设置activity的theme,这个好设置,可参考 http://blog.csdn.net/wsscy2004/article/details/7562909
2》设置xml里面组件的style,我的实现是通过:获取组件,然后遍历他们去设置style(其中style的内容查找比较麻烦,我是通过反射R.class和解析style.xml做到的,有些地方需要人为手动设置)
public static void onActivityCreateSetStyle(ViewGroup viewGroup) {
Log.d(tag, "onActivityCreateSetStyle");
if (mButtonStyle != 0) {
List<Button> list = getWidgetButton(viewGroup);
Log.d(tag, "onActivityCreateSetStyle button num == " + list.size());
if (list != null && !list.isEmpty()) {
String styleName = mApp.styles.get(mButtonStyle);// 得到样式name
Log.d(tag, "onActivityCreateSetStyle styleName == " + styleName);
StyleBean style = null;
for (StyleBean item : mApp.styledata) {
if (styleName.equals(item.getName())) {
style = item;// 得到样式的具体内容
}
}
List<String> methodNames = style.getMethodNames();
List<Class> paramTypes = style.getTypeClasses();
List<Object> values = style.getValues();
for (Button button : list) {
Log.d(tag, "method num == " + methodNames.size());
for (int i = 0; i < methodNames.size(); i++) {
Log.d(tag, "Button setMethod : " + methodNames.get(i));
Method method = getClassMethod(Button.class,
methodNames.get(i),
new Class[] { paramTypes.get(i) });
try {
if ("setTextColor".equals(methodNames.get(i))) {
method.invoke(
button,
context.getResources().getColor(
Integer.parseInt(values.get(i)
.toString())));
} else if ("setTextSize".equals(methodNames.get(i))) {
method.invoke(button, Float.parseFloat(values
.get(i).toString()));
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
这是上面用到的StyleBean
import java.util.List;
/**
* Style element bean
*
* @author Administrator
*
*/
@SuppressWarnings("rawtypes")
public class StyleBean {
private String name;
/**
* the method name associated with the attribute
*/
private List<String> methodNames;
/**
* the class associated with the attribute
*/
private List<Class> typeClasses;
/**
* the value associated with the attribute
*/
private List<Object> values;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getMethodNames() {
return methodNames;
}
public void setMethodNames(List<String> methodNames) {
this.methodNames = methodNames;
}
public List<Class> getTypeClasses() {
return typeClasses;
}
public void setTypeClasses(List<Class> typeClasses) {
this.typeClasses = typeClasses;
}
public List<Object> getValues() {
return values;
}
public void setValues(List<Object> values) {
this.values = values;
}
}
###反射R.class、解析style.xml,把R和style中的信息整理到类中,解析xml用的是sax,在解析style.xml的时候,注意把对应的方法、方法的参数类型记录下来,因为后面要通过反射来操作,eg:
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
buffer.delete(0, buffer.length());
itemName.delete(0, itemName.length());
if (localName.equals("style")) {
style = new StyleBean();
style.setName(attributes.getValue("name"));
Log.d(tag, "style name == " + style.getName());
methodNames = new ArrayList<String>();
typeClasses = new ArrayList<Class>();
values = new ArrayList<Object>();
} else if (localName.equals("item")) {
itemName.append(attributes.getValue("name"));
Log.d(tag, "item name == " + attributes.getValue("name") + " "
+ itemName.toString());
Log.d(tag, "" + itemName.toString().equals("android:textColor"));
if (itemName.toString().equals("android:textColor")) {
methodNames.add("setTextColor");// 手动设置
typeClasses.add(int.class);
} else if (itemName.toString().equals("android:textSize")) {
methodNames.add("setTextSize");// 手动设置
typeClasses.add(float.class);
}
}
}
//.....只贴关键的部分其他的方法就省略了
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
if (localName.equals("item")) {
String value = buffer.toString();
if (itemName.toString().equals("android:textColor")) {
if (value.contains("@color/")) {
RChildBean bean = getRChildBean("color");
if (bean != null) {
int color = getRValue(bean, value.substring(
value.lastIndexOf("/") + 1, value.length()));
Log.d(tag, "color == " + color);
if (color != -1) {
values.add(color);
}
}
bean = null;
}
} else if (itemName.toString().equals("android:textSize")) {
Log.d(tag, "size == " + value.substring(0, value.indexOf("sp")));
values.add(value.substring(0, value.indexOf("sp")));
}
} else if (localName.equals("style")) {
style.setMethodNames(methodNames);
style.setTypeClasses(typeClasses);
style.setValues(values);
styles.add(style);
}
}
private RChildBean getRChildBean(String name) {
for (RChildBean item : app.rchildlist) {
if (name.equals(item.getName())) {
return item;
}
}
return null;
}
private int getRValue(RChildBean child, String name) {
if (child.getItems().containsKey(name)) {
return child.getItems().get(name);
}
return -1;
}
这是上面用到的RChildBean
import java.util.Map;
/**
* R child class bean
*
* @author Administrator
*/
public class RChildBean {
/**
* R child name
*/
private String name;
/**
* R child items
*/
private Map<String, Integer> items;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, Integer> getItems() {
return items;
}
public void setItems(Map<String, Integer> items) {
this.items = items;
}
}