android 5.0 切换主题,夜间模式

       背景:现在做的软件颜色是白色的,如果在晚上看就会觉的很刺眼,对眼睛不好。于是想要实现夜间模式,然后在网上找了一写demo,有了实现思路,来看看具体的实现过程吧..


我使用的工具是android studio1.4 ,gradle:1.5.0,为什么使用1.4呢,之前一直使用1.0的版本,最近想要研究material,  android studio 1.4可以直接创建material风格的项目,而且代码已经自动生成,非常方便,但是你之前用gradle是1.5.0以下的版本的话,运行程序会直接崩溃,如果你也遇到这样的问题,请看我的另一篇博客,http://blog.csdn.net/tuibiansoar/article/details/50778079

 先看下切换主题的效果图:

APEC蓝

      


脑残粉主题:

   


夜间模式主题:


   

首先我们要通过设置主题的方式进行切换皮肤,怎么去切换主题呢?

在androidManifest.xml中系统默认会设置主题,进入style文件中就可以看到主题

这里是在xml里直接设置的默认主题,我们要切换主题需要动态的去加载不同的主题,所以我们要用到activity中的setTheme()方法设置主题。我们在设置主题的时候不可能只设置一个toolbar的颜色就ok了,还需要设值一些其他的颜色,例如点击效果,或者字体颜色要和主题颜色相对应,如果主题颜色为黑色,字体也是黑色,这样就造成问题看不到的问题,所以我们要自定义一些属性供我们使用。首先我们要在attr.xml中自定义属性
 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="colorPrimaryLight" format="reference|color" />
    <attr name="colorTextLight" format="reference|color"/>
    <attr name="colorTextDark" format="reference|color"/>
    <attr name="colorBackground" format="reference|color"/>
    <attr name="colorNavItem" format="reference|color"/>
    <attr name="colorDivider" format="reference|color"/>
</resources>



有了这些属性就可以自定义一些主题了,新建一个theme.xml,里边定义不同风格的主题

</pre><pre class="html" name="code"><?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--中国红主题-->
    <style name="Red_theme" parent="BaseTheme">
        <item name="colorPrimary">@color/red_primary</item>
        <item name="colorPrimaryDark">@color/red_primary_dark</item>
        <item name="colorAccent">@color/red_primary_light</item>
        <item name="colorTextLight">@color/red_text_light</item>
        <item name="colorTextDark">@color/red_text_dark</item>
        <item name="colorBackground">@color/comment_backgroud</item>
        <item name="colorNavItem">@color/item_nav_red_seletor</item>
        <item name="colorDivider">@color/comment_divider</item>
    </style>

    <!--琥珀主题-->
    <style name="Amber_theme" parent="BaseTheme">
        <item name="colorPrimary">@color/amber_primary</item>
        <item name="colorPrimaryDark">@color/amber_primary_dark</item>
        <item name="colorAccent">@color/amber_primary_light</item>
        <item name="colorTextLight">@color/amber_text_light</item>
        <item name="colorTextDark">@color/amber_text_dark</item>
        <item name="colorBackground">@color/comment_backgroud</item>
        <item name="colorNavItem">@color/item_nav_amber_seletor</item>
        <item name="colorDivider">@color/comment_divider</item></style>

    <!--APEC蓝主题-->
    <style name="Indigo_theme" parent="BaseTheme">
        <item name="colorPrimary">@color/indigo_primary</item>
        <item name="colorPrimaryDark">@color/indigo_primary_dark</item>
        <item name="colorAccent">@color/indigo_primary_light</item>
        <item name="colorTextLight">@color/indigo_text_light</item>
        <item name="colorTextDark">@color/indigo_text_dark</item>
        <item name="colorBackground">@color/comment_backgroud</item>
        <item name="colorNavItem">@color/item_nav_indigo_seletor</item>
        <item name="colorDivider">@color/comment_divider</item></style>
    <!--脑残粉主题-->
    <style name="Pink_theme" parent="BaseTheme">
        <item name="colorPrimary">@color/pink_primary</item>
        <item name="colorPrimaryDark">@color/pink_primary_dark</item>
        <item name="colorAccent">@color/pink_primary_light</item>
        <item name="colorTextLight">@color/pink_text_light</item>
        <item name="colorTextDark">@color/pink_text_dark</item>
        <item name="colorBackground">@color/comment_backgroud</item>
        <item name="colorNavItem">@color/item_nav_pink_seletor</item>
        <item name="colorDivider">@color/comment_divider</item></style>
    <!--夜间主题-->
    <style name="Night_theme" parent="BaseTheme.Night">
        <item name="colorPrimary">@color/black_primary</item>
        <item name="colorPrimaryDark">@color/black_primary_dark</item>
        <item name="colorAccent">@color/black_primary_light</item>
        <item name="colorTextLight">@color/black_text_light</item>
        <item name="colorTextDark">@color/black_text_dark</item>
        <item name="colorBackground">@color/grey_800</item>
        <item name="colorNavItem">@color/item_nav_night_seletor</item>
        <item name="colorDivider">@color/comment_divider</item></style>
</resources>


下边我们就可以用来改变主题了,以下是java代码的实现

ThemeUtils.java

public class ThemeUtils {

    public static final String TAG = "ThemeUtils";
    private static final String THEME = "pre_theme";
    private static Activity mContext;
    public static void changeTheme(Activity activity) {
        mContext = activity;
        final ChoiceOnClickListener listener = new ChoiceOnClickListener();
        final int index = 0;
        new AlertDialog.Builder(activity)
                .setTitle(R.string.theme)
                .setSingleChoiceItems(new TAdapter(activity, R.layout.item_theme, R.id.check, Theme.getThemes()), index, listener)
                .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        setTheme(mContext, listener.getWhich());

                        mContext.startActivity(new Intent(mContext, MainActivity.class));
                        mContext.finish();
                    }
                })
                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .create()
                .show();
    }

    /**
     *
     * @param activity
     */
    public static void setTheme(Activity activity,int index) {
        setTheme(activity, Theme.getThemes().get(index));
    }

    /**
     *
     * @param activity
     * @param theme
     */
    public static void setTheme(Activity activity, Theme theme) {
        if (theme == null) {
            return;
        }
        activity.setTheme(theme.style);
    }


    /**
     *
     */
    private static class ChoiceOnClickListener implements DialogInterface.OnClickListener {

        private int which = 0;
        @Override
        public void onClick(DialogInterface dialogInterface, int which) {
            this.which = which;
        }

        public int getWhich() {
            return which;
        }
    }



    /**
     * Theme
     */
    public static class Theme {
        public String name;
        public String tag;
        public int color;
        public int style;

        private static List<Theme> THEME_MAP = new ArrayList<>();
        static {
            THEME_MAP.add(new Theme(getString(R.string.theme_name_indigo), getString(R.string.theme_tag_indigo), R.color.indigo_primary, R.style.Indigo_theme));
            THEME_MAP.add(new Theme(getString(R.string.theme_name_red), getString(R.string.theme_tag_red), R.color.red_primary, R.style.Red_theme));
            THEME_MAP.add(new Theme(getString(R.string.theme_name_amber), getString(R.string.theme_tag_amber), R.color.amber_primary, R.style.Amber_theme));
            THEME_MAP.add(new Theme(getString(R.string.theme_name_pink), getString(R.string.theme_tag_pink), R.color.pink_primary, R.style.Pink_theme));
            THEME_MAP.add(new Theme(getString(R.string.theme_name_night), getString(R.string.theme_tag_night), R.color.black_primary, R.style.Night_theme));
        }

        public Theme(String name, String tag, @ColorRes int color, int style) {
            this.name = name;
            this.tag = tag;
            this.color = color;
            this.style = style;
        }

        protected static List<Theme> getThemes() {
            return THEME_MAP;
        }

        @Override
        public String toString() {
            return name;
        }
    }


    private static class TAdapter extends ArrayAdapter<Theme> {

        private int mTextId;
        public TAdapter(Context context, int resource, int textViewResourceId, List<Theme> objects) {
            super(context, resource, textViewResourceId, objects);
            this.mTextId = textViewResourceId;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Theme theme = getItem(position);
            View view = super.getView(position, convertView, parent);
            CheckedTextView textView = (CheckedTextView) view.findViewById(mTextId);
//            MDTintHelper.setTint(textView, getContext().getResources().getColor(theme.color));
            textView.setTextColor(getContext().getResources().getColor(theme.color));
//            textView.setChecked(convertView.getiss);
//            textView.setChecked(true);
            return view;
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

    }

    private static String getString(int resid) {
        return mContext.getString(resid);
    }
 

点击跳转之后需要在MainActivity 的onCreate()方法中调用ThemeUtils.setTheme(activity)方法设置,为了方便建议写一个BaseActivity,在这里的onCreate调用, 然后继承BaseActivity。

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ThemeUtils.changeTheme(this);
    }
}


这样就进行切换皮肤和主题了,但是非夜间模式的主题你会发现切换后的主题是这个样子的,有没有发现有点怪,toolbar的字体和菜单颜色白色会不会更好看呢,但是这个要怎么去修改呢?在android 5.0里新的控件就已经支持设置theme了,是不是很神奇。

既然这样,那我们就给toolbar设置一个主题,代码如下:

    <style name="MyActionBar" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
        <item name="android:background">?attr/colorPrimary</item>
        <item name="android:actionModeBackground">?attr/colorPrimary</item>
        <item name="android:fitsSystemWindows">true</item>
        <item name="android:windowActionModeOverlay">true</item>
    </style>


   <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:theme="@style/MyActionBar"
            />

在toolbar上设置给theme就好了,在看下效果

这样是不是看着更爽呢!!


有的人在运行的demo中发现滑出的菜单点击某一菜单时,点击效果和主题的风格是相同的,这个怎么实现呢?


可以用这两个属性itemTextColor和ItemIconTint



关于夜间模式,需要把整体的主题设置成暗色调的,所以自定义的主题和其他主题有所不同。




以上就是切换主题的实现方式了。有问题欢迎大家纠正...

下载demo地址:http://download.csdn.net/detail/tuibiansoar/9462210



       切换主题其他相关资料:

       https://github.com/dersoncheng/MultipleTheme

      http://mp.weixin.qq.com/s?__biz=MzA4MjU5NTY0NA==&mid=401740657&idx=1&sn=8e6727fbe094ea42d5fd80b185a49395#rd

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值