步骤:
1.在attr.xml下定义style变量
2.在style.xml下编写不同的主题,不同主题引用attr.xml中定义好的变量设置不同的属性
3.在布局文件中控件相应属性引用attr.xml下定义style变量
4.在activity中响应事件中切换主题,例如切换成其中一个主题R.style.AppTheme;设置一个可以持久化的变量标识切换成哪一个主题
5.调用MainActivity.this.recreate();
5.在onCreate方法中根据标识主题的变量设置相应的主题MainActivity.this.setTheme(R.style.AppTheme);
效果图
下面直接上代码
attr.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="colorValue" format="color" /> <attr name="background2" format="color" /> <attr name="textSize" format="dimension" /> </resources>
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorValue">#FF00FF00</item> <item name="background2">@color/background_floating_material_dark</item> <item name="textSize">10sp</item> </style> <style name="mytheme" parent="AppTheme"> <item name="android:windowNoTitle">true</item> <item name="colorValue">@color/background_floating_material_dark</item> <item name="background2">@color/background_floating_material_light</item> <item name="textSize">50sp</item> <!--<item name="windowActionBar">false</item>--> </style> <style name="mytext" parent="@android:style/TextAppearance.Medium"> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textSize">?attr/textSize</item> <item name="android:textColor">?attr/colorValue</item> </style> <!--<style name="mytext.textsize">--> <!--<item name="android:textSize">50sp</item>--> <!--<item name="android:textColor">@color/background_floating_material_dark</item>--> <!--</style>--> </resources>
<resources> <string name="app_name">TestStyleTheme</string> <string name="hello_world">Hello world!</string> <string name="action_settings">Settings</string> </resources>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="?attr/background2" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/tv" style="@style/mytext" android:text="@string/hello_world" /> <Button android:id="@+id/btn" android:layout_below="@id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="切换主题"/> </RelativeLayout>
import android.annotation.TargetApi; import android.app.Activity; import android.os.Build; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button btn; private static String b ="false"; PropertiesManager p; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); p = PropertiesManager.getPropertiesManager(MainActivity.this,null); b = p.get("theme"); if(b==null){ b = "false"; } if(b.equals("false")) { MainActivity.this.setTheme(R.style.AppTheme); }else{ MainActivity.this.setTheme(R.style.mytheme); } setContentView(R.layout.activity_main); btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public void onClick(View v) { if(b.equals("false")) { b = "true"; }else{ b = "false"; } p.set("theme",b); MainActivity.this.recreate(); } }); } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="test.teststyletheme" > <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
import android.content.Context; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; public class PropertiesManager { public static PropertiesManager pm; Context mContext; public String configPath; public static PropertiesManager getPropertiesManager(Context context, String configPath) { if (pm == null) { pm = new PropertiesManager(); pm.mContext = context; pm.configPath = configPath; } return pm; } private final static String APP_CONFIG = "config"; private Properties get() { FileInputStream fis = null; Properties props = new Properties(); try { // 读取files目录下的config // fis = activity.openFileInput(APP_CONFIG); // 读取app_config目录下的config File dirConf = mContext.getDir(APP_CONFIG, Context.MODE_PRIVATE); if (configPath != null) { fis = new FileInputStream(configPath + File.separator + APP_CONFIG); } else { fis = new FileInputStream(dirConf.getPath() + File.separator + APP_CONFIG); } props.load(fis); } catch (Exception e) { } finally { try { fis.close(); } catch (Exception e) { } } return props; } private void setProps(Properties p) { FileOutputStream fos = null; try { // 把config建在files目录下 // fos = activity.openFileOutput(APP_CONFIG, Context.MODE_PRIVATE); // 把config建在(自定义)app_config的目录下 File conf = null; if(configPath!=null){ conf = new File(new File(configPath), APP_CONFIG); }else{ File dirConf = mContext.getDir(APP_CONFIG, Context.MODE_PRIVATE); conf = new File(dirConf, APP_CONFIG); } fos = new FileOutputStream(conf); p.store(fos, null); fos.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { fos.close(); } catch (Exception e) { } } } private void set(Properties ps) { Properties props = get(); props.putAll(ps); setProps(props); } public String get(String key) { Properties props = get(); return (props != null) ? props.getProperty(key) : null; } public void set(String key, String value) { Properties props = get(); props.setProperty(key, value); setProps(props); } public void remove(String... key) { Properties props = get(); for (String k : key) props.remove(k); setProps(props); } }