Android主題更換簡單實踐

#前言
  很多優秀的APP都支持多種主題,最常見的是白天和夜間模式。因此本篇博客是作者實踐更換主題的記錄,寫出來與大家分享。
  實現更換主圖這一功能有很多種方式,最簡單的方式,就是定義多套主題。至於style文件當中,也適合新手學習與實踐(大神勿噴)。言歸正傳,進入主題。
#定義需要在各種主題下切換的屬性
  這部分內容放在values下的attrs.xml文件中,這裏我簡單定義了幾個如下:

<resources>

    <attr name="rootViewBg" format="reference|color"/>
    <attr name="titleBg" format="color"/>
    <attr name="buttonBg" format="color"/>
    <attr name="textColor" format="reference|color"/>
    <attr name="buttonTextColor" format="color"/>

</resources>

#定義多種主題
  既然是主題,自然是放在style.xml文件當中,這裏以我的style文件爲例,大家參考下,重點看註釋裏的日間模式和夜間模式:

<resources>

    <!-- 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>
    </style>

    <style name="FullscreenTheme" parent="AppTheme">
        <item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowBackground">@null</item>
        <item name="metaButtonBarStyle">?android:attr/buttonBarStyle</item>
        <item name="metaButtonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
    </style>

    <style name="FullscreenActionBarStyle" parent="Widget.AppCompat.ActionBar">
        <item name="android:background">@color/black_overlay</item>
    </style>
    <!--日間模式-->
    <style name="Theme_Day" parent="AppTheme">
        <item name="rootViewBg">@color/white</item>
        <item name="textColor">@color/black_overlay</item>
        <item name="buttonBg">#383838</item>
        <item name="buttonTextColor">#008888</item>
    </style>
    <!--夜間模式-->
    <style name="Theme_Night" parent="AppTheme">
        <item name="rootViewBg">@color/black_overlay</item>
        <item name="textColor">@color/white</item>
        <item name="buttonBg">#000090</item>
        <item name="buttonTextColor">#008811</item>
    </style>
</resources>

#將屬性應用到佈局文件當中
  佈局文件比較簡單,就是將我們自己定義的一些屬性,應用到我們需要在不同主題下需要變更的View屬性,注意代碼當中註釋的地方,比較簡單,不做太多的講解。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/rootViewBg">
    <!--注意這裏哦-->

    <Button
        android:id="@+id/bt"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="修改主題" />

    <view.CircleProgress
        android:id="@+id/circle_progress_welcome"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_centerInParent="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="40dp"
        android:text="@string/wasu_phone_tv"
        android:textSize="30sp"
        android:textStyle="bold"
        android:typeface="serif"
        android:textColor="?attr/textColor"/>
        <!--注意這裏哦-->


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:text="@string/verion_info"
        android:textColor="@color/white" />

</RelativeLayout>

#AndroidManifest.xml文件中,應用默認的自定義主題
  先看我的AndroidManifest.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wasu.winton.phonetv">

    <application
        android:name=".BaseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name="activity.WelcomeActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:theme="@style/Theme_Night">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="activity.LoginActivity"
                />
        <activity android:name="activity.IndexActivity"/>
    </application>

</manifest>

注意一下我的第一個Activity中android:theme的值爲我自定義的主題,爲什麼呢?因爲只有自定義主題中,才包含了我自定義的屬性呀,如果使用android:theme:@style/AppTheme會報運行時異常的,因爲很多網上的例子,都沒說這一點,我這裏浪費了好幾個小時。
  報出的異常:android.view.InflateException

android.view.InflateException: Binary XML file line #1: Error inflating class android.widget.RelativeLayout

#Activity中切換主題
  主要就是這兩個方法,這兩個方法都是放在Activity的onCreate()方法中。通過將使用哪種主題寫入SharePerfence文件,保證重新創建Activity可以生效。

 public void initView() {
        if(PerferenceUtil.getSp().getBoolean("dark",false)){
            //配置文件中讀取
            setTheme(R.style.Theme_Day);
        }else {
            setTheme(R.style.Theme_Night);
        }
        setContentView(R.layout.activity_welcome);
        circleProgress =(CircleProgress)findViewById(R.id.circle_progress_welcome);
        circleProgress.startAnim();
        bt = (Button)findViewById(R.id.bt);

    }

    @Override
    public void initListener() {
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean theme = PerferenceUtil.getSp().getBoolean("dark", false);
                PerferenceUtil.getEditor().putBoolean("dark",!theme).commit();//更換配置文件中主題
                WelcomeActivity.this.recreate();//重新創建Activity
                }
        });
    }

#效果
  這種方式就是會出現閃現,怎麼改善,後序研究。
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章