注:急速开发的人,可以直接看第三种实现方式
注:遇到放回activity闪屏的问题可以
1:修改theme,重启activity(Google自家在内的很多应用都是采用此种方式实现夜间模式的)
优点:正儿八经的夜间模式,配色看着舒服
缺点:规模较大的应用,需要随theme变化的属性会很多,都需要逐一定义,有点麻烦,另外一个缺点是要使得新theme生效,一般需要restartActivity来切换UI,会导致切换主题时界面闪烁
核心思路:自定义一个颜色属性名 A,A在日间和夜间模式下都有具体的颜色代码,页面布局文件只管引用A,至于是日间还是夜间,由后台主题决定。
附上一二中方法的图
(原图) (第一种实现)(第二种实现)
好,下面来讲讲具体的实现步骤,本环节使用的开发环境是Eclipse demo地址http://www.oschina.net/code/snippet_2702417_55892
1 首先
attrs.xml(声明属性的类型,布局xml中用) reference可以使用系统的资源ID,比如R.color.gray; color可以直接使用#ffffff颜色代码
<attr name="colorValue" format="color" /> <attr name="floatValue" format="float" /> <attr name="integerValue" format="integer" /> <attr name="booleanValue" format="boolean" /> <attr name="dimensionValue" format="dimension" /> <attr name="stringValue" format="string" /> <attr name="referenceValue" format="color|reference" /> <attr name="imageValue" format="reference"/> <attr name="curVisibility"> <!-- 相当于View的Visiblity --> <enum name="show" value="0" /> <!-- Not displayed, but taken into account during layout (space is left for it).相当于View的unVisiblity --> <enum name="inshow" value="1" /> <!-- Completely hidden, as if the view had not been added.相当于View的GONE --> <enum name="hide" value="2" /> </attr>
colors.xml(调色板,集中管理颜色hex)遵循优秀格式规范,即调色板模式,避免使用btn1,btn2,fontTitle,fontText之类的颜色名。
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="title">#101115</color> <color name="night_title">#FFFFFF</color> </resources>
string.xml
- <string name="app_name">dayandNight</string>
- <string name="hello_world">Hello world!</string>
- <string name="action_settings">白模式</string>
- <string name="night_action_settings">夜模式</string>
styles.xml(日间、夜间主题)
<resources> <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> </style> <style name="DayTheme" parent="AppTheme"> <item name="colorValue">@color/title</item> <item name="floatValue">0.35</item> <item name="integerValue">33</item> <item name="booleanValue">true</item> <item name="dimensionValue">16dp</item> <!-- 如果string类型不是填的引用而是直接放一个字符串,在布局文件中使用正常,但代码里获取的就有问题 --> <item name="stringValue">@string/action_settings</item> <item name="referenceValue">@drawable/bg</item> <item name="imageValue">@drawable/day</item> <item name="curVisibility">show</item> </style> <style name="NightTheme" parent="AppTheme"> <item name="colorValue">@color/night_title</item> <item name="floatValue">1.44</item> <item name="integerValue">55</item> <item name="booleanValue">false</item> <item name="dimensionValue">18sp</item> <item name="stringValue">@string/night_action_settings</item> <item name="referenceValue">@drawable/night_bg</item> <item name="imageValue">@drawable/night</item> <item name="curVisibility">hide</item> </style> </resources>
2activity的使用
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if(MyApp.isLightMode()){
- this.setTheme(R.style.NightTheme);
- }else{
- this.setTheme(R.style.DayTheme);
- }
- setContentView(R.layout.activity_one);
- }
- public void onClick(View view){
- MyApp.setIslightMode(!MyApp.isLightMode());
- recreate();
- }
xml的布局:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="?attr/referenceValue"
- android:orientation="vertical"
- android:gravity="center" >
- <TextView
- android:id="@+id/setting_Color"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="TextView"
- android:textColor="?attr/colorValue" />
- <CheckBox
- android:id="@+id/setting_show_answer_switch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:checked="?attr/booleanValue" />
- <TextView
- android:id="@+id/setting_Title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="pszwzy"
- android:textColor="?attr/colorValue"
- android:textSize="?attr/dimensionValue" />
- <TextView
- android:id="@+id/setting_Text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="?attr/stringValue" />
- <ImageView
- android:id="@+id/setting_Image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="?attr/imageValue" />
- <View
- android:id="@+id/setting_line"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:visibility="?attr/curVisibility" />
- <Button
- android:onClick="onClick"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="模式切换"
- android:textColor="?attr/colorValue"
- />
- </LinearLayout>
(1)在BaseActivity中创建下面的方法
- public static void updateTheme(Activity activity,isNight)
- {
- MyApp.setNightMode(isNight);
- activity.recreate();
- }