有時候使用一些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);
}
}
}