步骤:
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>
styles.xml
<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>
strings.xml
<resources>
<string name="app_name">TestStyleTheme</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
</resources>
activity_main.xml
<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>
MainActivity.java
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>
PropertiesManager.java 用户保存切换主题状态
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);
}
}