2019独角兽企业重金招聘Python工程师标准>>>
有时候使用一些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里面定义想要的样式主题
<style name="BlueTheme" parent="AppTheme"> <item name="colorPrimary">@color/colorBluePrimaryitem> <item name="colorPrimaryDark">@color/colorBluePrimaryDarkitem> <item name="colorAccent">@color/colorBluePrimaryDarkitem> style> <style name="RedTheme" parent="AppTheme"> <item name="colorPrimary">@color/colorRedPrimaryitem> <item name="colorPrimaryDark">@color/colorRedPrimaryDarkitem> <item name="colorAccent">@color/colorRedPrimaryDarkitem> 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); } }
}
来通知标题栏回调然后更新background