Android夜間模式的幾種實現

1、直接修改widget顏色,這種方式實現起來最簡單,但須要每一個控件都去修改,太過複雜。例如: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修改顏色方法ide

    /**
     * 修改背景色
     * @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);
    }

2、經過修改Theme,更新應用主題。這種方法問題在於,須要重啓Activity才能完成界面渲染。函數

在Activity中調用setContentView以前進行Theme設置:ui

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

 

NightModeUitls設置Theme方法:this

    /** 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;
        }
    }

 

3、經過怎加一層遮光罩來實現。效果不是很理想。spa

經過WindowManager,將一個透明背景的TextView加到Activity主界面中。代碼以下:code

    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) {
        }
    }

4、最後來看一下Dialog須要怎麼實現夜間模式。orm

AlertDialog.Builder 有一個帶style id參數的構造函數,咱們就經過這個構造函數來實現Dialog主題的修改,從而達到夜間模式。blog

    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我採用以下方式:ip

    <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的主題修改。

Demo源碼

相關文章
相關標籤/搜索