有时候使用一些APP的时候发现有一个主题切换的功能,感觉挺好玩的,今天也尝试着做了一下,现在总结换肤经验
_/** _ * 换肤接口 */ 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里面定义想要的样式主题
<**style** **name=****"BlueTheme"** **parent=****"AppTheme"**> <**item** **name=****"colorPrimary"**>@color/colorBluePrimary</**item**> <**item** **name=****"colorPrimaryDark"**>@color/colorBluePrimaryDark</**item**> <**item** **name=****"colorAccent"**>@color/colorBluePrimaryDark</**item**> _ __ __ _</**style**> <**style** **name=****"RedTheme"** **parent=****"AppTheme"**> <**item** **name=****"colorPrimary"**>@color/colorRedPrimary</**item**> <**item** **name=****"colorPrimaryDark"**>@color/colorRedPrimaryDark</**item**> <**item** **name=****"colorAccent"**>@color/colorRedPrimaryDark</**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(); }
- @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); } }
}
来通知标题栏回调然后更新background