android夜间模式的几种实现

    /**
     * 相应交互,修改控件颜色
     * @param view
     */
    public void onMethod1Click(View view) {
        if (view.getId() == R.id.btn_method1) {
            int theme = NightModeUtils.getSwitchDayNightMode(this);
            NightModeUtils.setBackGroundColor(this, mRootView, theme);
            NightModeUtils.setTextColor(this, findViewById(R.id.text), theme);
            NightModeUtils.setDayNightMode(this, theme);
        }
    }
复制代码

NightModeUitls修改颜色方法

复制代码
    /**
     * 修改背景色
     * @param context
     * @param view
     * @param theme
     */
    public static void setBackGroundColor(Context context, View view, int theme) {
        int color = context.getResources().getColor(
                theme == THEME_SUN ? R.color.light_color : R.color.night_color);
        view.setBackgroundColor(color);
    }

    /**
     * 修改文字色
     * @param context
     * @param view
     * @param theme
     */
    public static void setTextColor(Context context, View view, int theme) {
        int color = context.getResources().getColor(
                theme == THEME_SUN ? R.color.night_color : R.color.light_color);
        TextView textView = (TextView)view;
        textView.setTextColor(color);
    }
复制代码

二、通过修改Theme,更新应用主题。这种方法问题在于,需要重启Activity才能完成界面渲染。

在Activity中调用setContentView之前进行Theme设置:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        NightModeUtils.onActivityCreateSetTheme(this);
        setContentView(R.layout.activity_main);
    }

 

NightModeUitls设置Theme方法:

复制代码
    /** Set the theme of the activity, according to the configuration. */
    public static void onActivityCreateSetTheme(Activity activity) {
        int theme = getDayNightMode(activity);
        switch (theme) {
            case THEME_SUN:
                activity.setTheme(R.style.AppSunTheme);
                break;
            case THEME_NIGHT:
                activity.setTheme(R.style.AppNightTheme);
                break;
            default:
                break;
        }
    }
复制代码

 

三、通过怎加一层遮光罩来实现。效果不是很理想。

通过WindowManager,将一个透明背景的TextView加到Activity主界面中。代码如下:

复制代码
    private void night() {
        if (mNightView == null) {
            mNightView = new TextView(this);
            mNightView.setBackgroundColor(0xaa000000);
        }

        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_APPLICATION,
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
        lp.gravity = Gravity.BOTTOM;
        lp.y = 10;

        try {
            mWindowManager.addView(mNightView, lp);
        } catch (Exception ex) {
        }
    }

    private void day() {
        try {
            mWindowManager.removeView(mNightView);
        } catch (Exception ex) {
        }
    }
此方法记得提取出来作为一个工具来用

不要在像Activity这样有生命周期的东东里乱写东西,不然莫名其妙的被销毁,然后新建,

但早已经是物是人非,最后就是状态异常、空指针各种Crash各种坑。

我们要实现的效果是:点击显示Button-addView,点击消除Button-removeView,

我想removeView可是想在哪就在哪,随心所欲,游离于Activity的生命周期之外~

直接上代码,将WindowManager抽离出来即可,一个小Demo:

首先添加相应权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />  public class Windowutils { private static WindowManager mWindowManager; private static View mNightView; public static void showWindow(Context context) {     mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);     mNightView = new View(context);     WindowManager.LayoutParams lp = new WindowManager.LayoutParams(                LayoutParams.MATCH_PARENT,                LayoutParams.MATCH_PARENT,                WindowManager.LayoutParams.TYPE_APPLICATION,                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,                PixelFormat.TRANSLUCENT);      mNightView.setBackgroundColor(0xaa000000);      mWindowManager.addView(mNightView, lp); } public static void removeWindow() {     // TODO Auto-generated method stub     if(mWindowManager==null||mNightView==null){                  return;     }     mWindowManager.removeViewImmediate(mNightView); } }
复制代码

四、最后来看一下Dialog需要怎么实现夜间模式。

AlertDialog.Builder 有一个带style id参数的构造函数,我们就通过这个构造函数来实现Dialog主题的修改,从而达到夜间模式。

复制代码
    public static AlertDialog.Builder createBuilder(Context context) {
        if (NightModeUtils.getDayNightMode(context) == NightModeUtils.THEME_SUN) {
            return new AlertDialog.Builder(context);
        } else {
            return new AlertDialog.Builder(context, R.style.NightDialog);
        }
    }
复制代码

我们通过如上方法来获取Builder,实现主题切换。其中R.style.NightDialog我采用如下方式:

    <style name="NightDialog" parent="android:Theme.Holo.Dialog">
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

在android honeycomb之前的版本Theme.Dialog.Alert与AlertDialog这两个style是public的,可以通过修改主题时,重新定义这两个style实现dialog主题的修改,但之后的版本已经将他们开放关闭了。所以,我通过上面的办法实现了dialog的主题修改。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值