43.使用MultipleTheme换肤框架实现日、夜间模式的切换

来源:互联网 发布:cpu锁帧软件 编辑:程序博客网 时间:2024/05/21 11:09

转载请注明出处 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.InvocationTargetExceptionCaused by: android.content.res.Resources$NotFoundException: File res/drawable/common_corners_bg.xml from drawable resource ID #0x7f02004cCaused 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>
1 0
原创粉丝点击