使用 setTheme 方法来实现日间/夜间模式切换的方案。这种方案的思路就是在用户选择夜间模式时,Activity 设置成夜间模式的主题,之后再让 Activity 调用 recreate() 方法重新创建一遍就行了。
1.在 colors.xml 中定义两组颜色,分别表示日间和夜间的主题色:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="nightColorPrimary">#3b3b3b</color>
<color name="nightColorPrimaryDark">#383838</color>
<color name="nightColorAccent">#a72b55</color>
</resources>
2.在 styles.xml 中定义两组主题,也就是日间主题和夜间主题:
<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:textColor">@android:color/black</item> <item name="mainStyle">@android:color/white</item> </style> <style name="NightAppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/nightColorPrimary</item> <item name="colorPrimaryDark">@color/nightColorPrimaryDark</item> <item name="colorAccent">@color/nightColorAccent</item> <item name="android:textColor">@android:color/white</item> <item name="mainStyle">@color/nightColorPrimaryDark</item> </style> </resources>
3.在valus文件夹下新建attrs,mainBackground 属性是我们自定义的属性,用来表示背景色:
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="mainStyle" format="color|reference"></attr> </resources>
4.创建布局 activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <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/mainStyle" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> <Button android:id="@+id/btn_theme" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="切换日/夜间模式" /> <TextView android:id="@+id/tv" android:layout_below="@id/btn_theme" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="通过setTheme()的方法" /> </RelativeLayout>
在 <RelativeLayout> 的 android:background 属性中,我们使用 "?attr/mainStyle" 来表示,意思就是 RelativeLayout 的背景色会去引用在主题中事先定义好的 mainStyle属性的值。这样就实现了日间/夜间模式切换的换色了。
4. 创建MainActivity :
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.Button; import com.bawei.draweract.R; public class MainActivity extends AppCompatActivity { // 默认是日间模式 private int theme = R.style.AppTheme; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 判断是否有主题存储 if(savedInstanceState != null){ theme = savedInstanceState.getInt("theme"); setTheme(theme); } setContentView(R.layout.activity_main); Button btn_theme = (Button) findViewById(R.id.btn_theme); btn_theme.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { theme = (theme == R.style.AppTheme) ? R.style.NightAppTheme : R.style.AppTheme; MainActivity.this.recreate(); } }); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("theme", theme); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); theme = savedInstanceState.getInt("theme"); } }
接下来就大功告成啦。