天天看點

Android 應用換膚功能(白天黑夜主題切換)

有時候使用一些APP的時候發現有一個主題切換的功能,感覺挺好玩的,今天也嘗試着做了一下,現在總結換膚經驗

1.

/**
 * 換膚接口
 */
public interface ColorUiInterface {
    View getView();

    void setTheme(Resources.Theme themeId);
}      
2.自定義Reletivelayout控件實作換膚接口      
public class ColorRelativeLayout extends RelativeLayout implements ColorUiInterface {

    private int attr_background = -1;

    public ColorRelativeLayout(Context context) {
        super(context);
    }

    public ColorRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.attr_background = ViewAttributeUtil.getBackgroundAttibute(attrs);
    }

    public ColorRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.attr_background = ViewAttributeUtil.getBackgroundAttibute(attrs);
    }

    @Override
    public View getView() {
        return this;
    }

    @Override
    public void setTheme(Resources.Theme themeId) {
        if (attr_background != -1) {
            ViewAttributeUtil.applyBackgroundDrawable(this, themeId, attr_background);
        }
    }
}      
3.在arrs.xml      
<attr name="colorPrimaryCenter" format="color|reference" />
<attr name="colorTextIcon" format="color|reference" />
<attr name="colorPrimaryText" format="color|reference" />
<attr name="colorSecondText" format="color|reference" />
<attr name="colorBackground" format="color|reference" />
<attr name="colorDivider" format="color|reference" />
<attr name="colorBackgroundAccent" format="color|reference" />
<attr name="colorHint" format="color|reference" />      
4.在style裡面定義想要的樣式主題      
<!--blueTheme-->
<style name="BlueTheme" parent="AppTheme">
    <item name="colorPrimary">@color/colorBluePrimary</item>
    <item name="colorPrimaryDark">@color/colorBluePrimaryDark</item>
    <item name="colorAccent">@color/colorBluePrimaryDark</item>
    <!--<item name="md_title_color">@color/colorBluePrimary</item>-->
    <!--<item name="md_link_color">@color/colorBluePrimary</item>-->
    <!--<item name="md_positive_color">@color/colorBluePrimary</item>-->

</style>

<!--redTheme-->
<style name="RedTheme" parent="AppTheme">
    <item name="colorPrimary">@color/colorRedPrimary</item>
    <item name="colorPrimaryDark">@color/colorRedPrimaryDark</item>
    <item name="colorAccent">@color/colorRedPrimaryDark</item>
    <!--<item name="md_title_color">@color/colorRedPrimary</item>-->
    <!--<item name="md_link_color">@color/colorRedPrimary</item>-->
    <!--<item name="md_positive_color">@color/colorRedPrimary</item>-->

</style>      
5.在Activity中點選按鈕彈出對話框(此Activity有兩個要求 1.繼承       
AppCompatActivity 2.實作ColorChooserDialog.ColorCallback)      
public void onClick(String content) {
    new ColorChooserDialog.Builder(this, R.string.theme)
            .customColors(R.array.colors, null)
            .doneButton(R.string.done)
            .cancelButton(R.string.cancel)
            .allowUserColorInput(false)
            .allowUserColorInputAlpha(false)
            .show();
}      
6.       
@Override
public void onColorSelection(@NonNull ColorChooserDialog dialog, @ColorInt int selectedColor) {
    if (selectedColor == ThemeUtils.getThemeColor(this, R.attr.colorPrimary))
        return;
    EventBus.getDefault().post(new SkinChangeEvent());

    if (selectedColor == getResources().getColor(R.color.colorBluePrimary)) {
        setTheme(R.style.BlueTheme);
        PreUtils.setCurrentTheme(this, Theme.Blue);

    } else if (selectedColor == getResources().getColor(R.color.colorRedPrimary)) {
        setTheme(R.style.RedTheme);
        PreUtils.setCurrentTheme(this, Theme.Red);

    }       
}      
7.以上更改的是狀态欄的主題,修改标題欄樣式是這樣的      
<com.zcy.ghost.ghost.app.theme.ColorRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/title"
    android:layout_width="match_parent"
    android:layout_height="68dp"
    android:background="?attr/colorPrimary">

    <TextView
        android:id="@+id/title_name"
        style="@style/title_tv_style"
        android:layout_width="match_parent"
        android:layout_marginTop="20dp" />
</com.zcy.ghost.ghost.app.theme.ColorRelativeLayout>      
8.通過調用
ColorUiUtil.changeTheme(rootView, getTheme());      
public static void changeTheme(View rootView, Resources.Theme theme) {
    if (rootView instanceof ColorUiInterface) {
        ((ColorUiInterface) rootView).setTheme(theme);
        if (rootView instanceof ViewGroup) {
            int count = ((ViewGroup) rootView).getChildCount();
            for (int i = 0; i < count; i++) {
                changeTheme(((ViewGroup) rootView).getChildAt(i), theme);
            }
        }      
}

繼續閱讀