Android Style\Theme动态切换

若转载请注明出处!

本文的主题思想是:
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;
	}
}

你可能感兴趣的:(android,style,theme)