Android Style\Theme动态切换
程序员文章站
2022-04-20 16:37:55
...
若转载请注明出处!
本文的主题思想是:
1》设置activity的theme,这个好设置,可参考 http://blog.csdn.net/wsscy2004/article/details/7562909
2》设置xml里面组件的style,我的实现是通过:获取组件,然后遍历他们去设置style(其中style的内容查找比较麻烦,我是通过反射R.class和解析style.xml做到的,有些地方需要人为手动设置)
这是上面用到的StyleBean
###反射R.class、解析style.xml,把R和style中的信息整理到类中,解析xml用的是sax,在解析style.xml的时候,注意把对应的方法、方法的参数类型记录下来,因为后面要通过反射来操作,eg:
这是上面用到的RChildBean
本文的主题思想是:
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; } }
上一篇: AlertDialog5种默认Theme对应的样式
下一篇: 女性睡眠姿势不对也会导致不孕,你信吗?
推荐阅读