今天要來寫關於Android裝置中日間/夜間主題切換的方法
Emmm在文章開始前我先說好...
這篇的重點不是要教你如何切換Android顏色配置主題ヾ(´¬`)ノ
這篇文章基本上是給工程師看的...所以如果你點進來了...也請不要急著走XD
我也會教你怎麼切黑暗主題啦(-‿◦)
Okay,還好留住人了(?)
咳咳回歸正題,大家有用iPhone的都知道iPhone有個所謂的深色(夜間)主題
號稱可以保護眼睛讓你在燈關掉睡覺前也能滑手機(・ωー)~☆
而深色主題長這樣
那麼我們的Google看到此景象我們當然也不能落人於後啊(┼д┼;)
因此在Android系統中咱們的Android 10就有更新深色主題了!
其設置如下
打開設定
↓
顯示
↓
深色模式
基本上就完成囉
還是不知道嗎?如下圖Gif操作
咦?你跟我說找不到?
那可能你的Android手機版本不是Android10喔....
好,非工程師的朋友們可以拉到最底下留言按Like了XD
接下來即將進入非人類的世界(咦?)
來上一下今天的範例吧
因為今天要設定的東西比較複雜,所以Github在此
->https://github.com/thumbb13555/DesignModeChange/tree/master
1. 設置資料夾
先講講原理
首先來看一下資料結構
把焦點移向res以下的資料夾
可以發現有些xml檔後面有標注(night)
這些有標注night的檔案就是在夜間模式會用到的資源
那麼現在就來創建它吧
首先開啟Project資料夾檢視模式
然後在res的資料夾下面新增drawable-night的資料夾跟values-night的資料夾
再來請按照圖片中的樣子在night的資料夾內新增colors.xml以及style.xml的資料夾
然後連內容兩個的內容除了顏色以外都要一模一樣喔~往下會給程式碼
首先是drawable的部分,drawable的部分雖然名字一樣,但實際上是兩張不一樣的icon
日間模式的是太陽
<vector android:height="150dp" android:tint="#FFD738" android:viewportHeight="24" android:viewportWidth="24" android:width="150dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@android:color/white" android:pathData="M6.76,4.84l-1.8,-1.79 -1.41,1.41 1.79,1.79 1.42,-1.41zM4,10.5L1,10.5v2h3v-2zM13,0.55h-2L11,3.5h2L13,0.55zM20.45,4.46l-1.41,-1.41 -1.79,1.79 1.41,1.41 1.79,-1.79zM17.24,18.16l1.79,1.8 1.41,-1.41 -1.8,-1.79 -1.4,1.4zM20,10.5v2h3v-2h-3zM12,5.5c-3.31,0 -6,2.69 -6,6s2.69,6 6,6 6,-2.69 6,-6 -2.69,-6 -6,-6zM11,22.45h2L13,19.5h-2v2.95zM3.55,18.54l1.41,1.41 1.79,-1.8 -1.41,-1.41 -1.79,1.8z"/> </vector>
夜間模式的是月亮
<vector android:height="150dp" android:tint="#C3C3C3" android:viewportHeight="24" android:viewportWidth="24" android:width="150dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="@android:color/white" android:pathData="M11.1,12.08C8.77,7.57 10.6,3.6 11.63,2.01C6.27,2.2 1.98,6.59 1.98,12c0,0.14 0.02,0.28 0.02,0.42C2.62,12.15 3.29,12 4,12c1.66,0 3.18,0.83 4.1,2.15C9.77,14.63 11,16.17 11,18c0,1.52 -0.87,2.83 -2.12,3.51c0.98,0.32 2.03,0.5 3.11,0.5c3.5,0 6.58,-1.8 8.37,-4.52C18,17.72 13.38,16.52 11.1,12.08z"/> <path android:fillColor="@android:color/white" android:pathData="M7,16l-0.18,0C6.4,14.84 5.3,14 4,14c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.62,0 2.49,0 3,0c1.1,0 2,-0.9 2,-2C9,16.9 8.1,16 7,16z"/> </vector>
當然,夜間模式要用的檔案就是放在-night的資料夾,稍後的顏色也是一樣
values的資料夾部分也是一樣
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#6200EE</color> <color name="colorPrimaryDark">#3700B3</color> <color name="colorAccent">#03DAC5</color> <color name="custom_color">#E8E8E8</color> <color name="word_color">#292929</color> </resources>
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="custom_color">#673AB7</color> <color name="word_color">#F8F8F8</color> </resources>
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.DayNight"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources>
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="AppTheme" parent="Theme.AppCompat.DayNight"> <!-- Customize your theme here. --> <item name="colorPrimary">#FF9800</item> <item name="colorPrimaryDark">#FF5722</item> <item name="colorAccent">#8BC34A</item> </style> </resources>
設置完後就可以切回Android資料夾檢視模式,就會看到以下樣式囉
然後當你在設置畫面的時候,你就會看到這樣的視窗
就表示設置成功了!
最後給你今天的介面
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Switch android:id="@+id/switch1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="夜間模式切換" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:ignore="UseSwitchCompatOrMaterialXml" /> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toTopOf="@+id/switch1" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_baseline_mode_24" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="無意義的存在" android:backgroundTint="@color/custom_color" android:textColor="@color/word_color" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/switch1" /> </androidx.constraintlayout.widget.ConstraintLayout>
2. 撰寫設定儲存模組
目前我們已經在介面中完成了日/夜設置
接下來就是要寫程式控制它,並儲存設定的狀態
儲存狀態的方法我們是使用SharedPreferences的儲存機制完成它
關於SharedPreferences我之前有寫過一篇文章,可以去看看ㄜ
->碼農日常-『Android studio』Android資料儲存-SharedPreferences的基本用法
那麼儲存的程式在這邊
public class SaveStatus extends Application { public static final String NIGHT_MODE = "NIGHT_MODE"; private boolean isNightMode = false; private static SaveStatus singleton = null; /**設置外部接口*/ public static SaveStatus getInstance() { if(singleton == null) { singleton = new SaveStatus(); } return singleton; } /**初始化*/ @Override public void onCreate() { super.onCreate(); singleton = this; SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this); this.isNightMode = mPrefs.getBoolean(NIGHT_MODE, false); } /**將現在的日夜間模式狀態顯示給Main傳出外部*/ public boolean isNightMode() { return isNightMode; } /**設置現在使用者所選擇的日夜間狀態*/ public void setIsNightModeEnabled(boolean isNightMode) { this.isNightMode = isNightMode; /**將現在目前的狀態存進SharedPreferences內*/ SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor editor = mPrefs.edit(); editor.putBoolean(NIGHT_MODE, isNightMode); editor.apply(); } }
然後請至AndroidManifest.xml內新增這行
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jetec.designmodechange"> <application android:name=".SaveStatus" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
3. 撰寫設定
直接上
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /**從SharedPreferences中垃取目前背景色彩的設定 * (備註:若沒有設定前,預設皆為日間模式,詳見 * this.isNightModeEnabled = mPrefs.getBoolean(NIGHT_MODE, false); * 這一行)*/ if (SaveStatus.getInstance().isNightMode()) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); } setContentView(R.layout.activity_main); @SuppressLint("UseSwitchCompatOrMaterialCode") Switch sw = findViewById(R.id.switch1); /**偵測目前的模式,如果是夜間模式的話switch設定為打開*/ if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES){ sw.setChecked(true); } sw.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { /**設定為夜間模式,並將設定寫入SharedPreferences*/ SaveStatus.getInstance().setIsNightModeEnabled(true); } else { /**設定為日間模式,並將設定寫入SharedPreferences*/ SaveStatus.getInstance().setIsNightModeEnabled(false); } /**將此頁面finish掉後重新打開*/ Intent intent = getIntent(); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); finish(); startActivity(intent); } }); } }
基本上,在模式切換的時候相當於是手動將頁面重啟
整體原理就像是螢幕旋轉是一樣的概念(只是它是自動,我們是手動...)
所以先看向前半部
if (SaveStatus.getInstance().isNightMode()) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); } setContentView(R.layout.activity_main);
這個部分就是從SharedPreferences中將前次的設定取出來
然後才再來初始化整個UI
最後再按下切換設定後,就把整個畫面finish掉在重啟
Intent intent = getIntent(); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); finish(); startActivity(intent);
當然,請記得要保存狀態呦!
SaveStatus.getInstance().setIsNightModeEnabled(true);
文章就到這邊..哎呀,這禮拜好忙,這篇文到星期日才給他寫完QQ
而且週六在寫的時候,也遇到了不夠了解的地方,故障排除了一下子才給他弄完,然後又要出門...
總之..
留言列表