转载请注明出处 http://blog.csdn.net/qq_31715429/article/details/52138037
本文出自:猴菇先生的博客
公司有切换日、夜间模式的需求,在github上找到了MultipleTheme换肤框架,无需重启应用和当前页面,集成后顺利的实现了这个需求,还是比较方便的。
几点要注意的:
1.按照github上面的步骤集成,attrs里面的item的name应该和style里面的name相同,不然找不到该属性。注意是style文件,而不是styles文件。
2.在布局文件中修改相应属性的值为”?attr/xx”。需要注意的是,如果把这个写到drawable文件夹中,例如
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="2.5dp" />
<solid android:color="?attr/activity_bg" />
</shape>
在5.0版本以下会导致崩溃:
android.view.InflateException: Binary XML file line #2: Error inflating class <unknown>
Caused by: java.lang.reflect.InvocationTargetException
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/common_corners_bg.xml from drawable resource ID #0x7f02004c
Caused by: java.lang.UnsupportedOperationException: Can't convert to color: type=0x2
不知道是这个换肤框架的兼容性有问题,还是我进入的方式不对。。
3.在BaseActivity.java中根据SharedPreference拿到当前应该显示什么主题,并setTheme()
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//初始化主题
if (SharedPreferenceUtil.getTheme(this) == R.style.LightTheme) {
setTheme(R.style.LightTheme);//系统方法,需要appcompat包
} else {
setTheme(R.style.DarkTheme);
}
}
}
4.在更换主题的点击事件里,修改SharedPreference记录的主题状态,并且作者加入了渐变动画
if (UserInfo.getTheme(this) == R.style.LightTheme) {
setTheme(R.style.DarkTheme);
SharedPreferenceUtil.setTheme(this, R.style.DarkTheme);
} else {
setTheme(R.style.LightTheme);
SharedPreferenceUtil.setTheme(this, R.style.LightTheme);
}
final View rootView = getWindow().getDecorView();
rootView.setDrawingCacheEnabled(true);
rootView.buildDrawingCache(true);
final Bitmap localBitmap = Bitmap.createBitmap(rootView.getDrawingCache());
rootView.setDrawingCacheEnabled(false);
if (null != localBitmap && rootView instanceof ViewGroup) {
final View localView = new View(getApplicationContext());
localView.setBackgroundDrawable(new BitmapDrawable(getResources(), localBitmap));
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
((ViewGroup) rootView).addView(localView, params);
localView.animate().alpha(0).setDuration(1000).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
ColorUiUtil.changeTheme(rootView, getTheme());
}
@Override
public void onAnimationEnd(Animator animation) {
((ViewGroup) rootView).removeView(localView);
localBitmap.recycle();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
}).start();
}
5.针对切换主题模式时需要立即更新页面ui的页面,需要使用框架里的封装控件;不需要立即更新的只用在布局文件中修改相应属性的值为”?attr/xx”,仍然用android原生控件
<com.monkey.zhuishu.changeTheme.widget.ColorRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/activity_bg">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text = "换肤" />
</com.monkey.zhuishu.changeTheme.widget.ColorRelativeLayout>
6.如果你用的控件它的框架中并没有,那就照着作者写的另写一个吧。比如我用的design包下的TabLayout,那么就复制一份作者写的控件,修改为extends TabLayout
public class ColorTabLayout extends TabLayout implements ColorUiInterface {
private int attr_background = -1;
public ColorTabLayout(Context context) {
super(context);
}
public ColorTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.attr_background = ViewAttributeUtil.getBackgroundAttibute(attrs);
}
public ColorTabLayout(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);
}
}
}
然后该怎么用怎么用
<com.monkey.zhuishu.changeTheme.widget.ColorTabLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/base_title_height"
android:layout_below="@+id/titleBar"
android:background="?attr/activity_bg"
app:tabIndicatorColor="?attr/indicator_color"
app:tabSelectedTextColor="@color/tabSelectedText"
app:tabTextColor="@color/tabUnSelectedText">
</com.monkey.zhuishu.changeTheme.widget.ColorTabLayout>