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

转载请注明出处 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>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值