在這裏咱們所說的並不是自定義屬性,關於自定義屬性,請參考以前的文章,講的很細,今天所說的是自定義「屬性名」。java
先講一下,爲何咱們須要自定義咱們的屬性名,加入你再開發一個應用,該應用你設置好幾種主題,每個主題對應與整個程序的不少中屬性,假如在一種主題當中有內容背景色(屬性爲:background),並且還有字體背景色(一樣爲:background),若是我須要更換主題的時候,以上所說的顏色的改變就會略有麻煩,若是此時,我給以上顏色的取值取了名字。好比第一個顏色我能夠設置爲"contentBackgrounp",第二個顏色就能夠設置爲"fontBackgrounp",這樣的話呢,我就能夠區分這兩種 顏色,更換主題時,只需調用setTheme()方法就能夠了,其餘的什麼都不須要改變。android
上面說的有些不太懂,沒有辦法,語言水平就到這了,下面我用代碼去實現這些。app
首先,我須要定義以上兩種屬性:theme_atrrs.xml
ide
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="contentBackgrounp" format="reference"></attr> <attr name="fontBackgrounp" format="reference"></attr> </resources>
NOTICE:以上屬性的格式必定要爲reference格式,由於雖然咱們設置了以上屬性,可是咱們不關心它是什麼,咱們關心的是它指向哪裏,也就說這個屬性實際上就表明着它所指向的值。(這個意思下面我再細說)佈局
下面,我就要對以上屬性,在我所使用的主題中進行賦值theme.xml字體
<?xml version="1.0" encoding="utf-8"?> <resources> <!--夜間模式下的主題--> <style name="AppBaseTheme_Dark" parent="@style/Theme.AppCompat.Light"> <item name="contentBackgrounp">@color/dark_content</item> <item name="fontBackgrounp">@color/dark_font</item> </style> <!--日間模式下的主題--> <style name="AppBaseTheme_Light" parent="@style/Theme.AppCompat.Light"> <item name="contentBackgrounp">@color/day_content</item> <item name="fontBackgrounp">@color/day_font</item> </style> </resources>
下面,咱們就要AndroidMainfest.xml文件中初始化咱們的主題,此處假如咱們默認爲日間模式this
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppBaseTheme_Light" > <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>
也就是說設置以下語句,若是不設置以下語句,程序會報錯
設計
android:theme="@style/AppBaseTheme_Light"
而後,咱們就能夠在咱們的佈局中去使用咱們定義好的屬性:code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="?attr/contentBackgrounp"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:background="?attr/fontBackgrounp"/> </RelativeLayout>
由於,咱們在使用過程當中這兩個組件的background都是一個指向的值,它的真正值是咱們在theme.xml中設置的,因此,若是要改變主題,其餘的什麼都不須要改變,若是要設置爲夜間模式,只需調用方法setTheme(R.style.AppBasetheme_Dark)便可。orm
因爲setTheme方法的調用必須在調用執行方法setContentView()以前:使用,在使用時有兩種處理方法;
第一種,也是最簡單的方法:
setTheme(R.style.AppTheme_Light); this.onCreate(new Bundle());
只需以上兩句就能夠達到更換主題的方法。
第二種方法,雖然代碼長度略長,可是是比較好的設計方法:
在SharedPreferences中配置一個鍵,存儲主題模式,使用過程以下:
boolean isNight = false; SharedPreferences sp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sp = PreferenceManager.getDefaultSharedPreferences(this); setTheme((isNight = sp.getBoolean("isNight", false)) ? R.style.AppTheme_Dark : R.style.AppTheme_Light); setContentView(R.layout.activity_main);
點擊按鈕:
@Override public void onClick(View v) { int resId = v.getId(); switch (resId) { case R.id.day: if(isNight) { SharedPreferences.Editor editor = sp.edit(); editor.putBoolean("isNight",false); recreate(); } break; case R.id.dark: if(!isNight) { SharedPreferences.Editor editor = sp.edit(); editor.putBoolean("isNight", true); recreate(); } break; }
關於方法recreate:
Cause this Activity to be recreated with a new instance. This results in essentially the same flow as when the Activity is created due to a configuration change -- the current instance will go through its lifecycle to onDestroy() and a new instance then created after it.
意思是說:調用該方法,會使得該Activity重建一個新的實例,當前的實例會調用生命週期的onDestroy方法,而且在調用onDestroy方法以後用從新建立一個新的實例