Android 实现两种黑白天模式切换

本文介绍了两种在Android中实现黑白天模式切换的方法。第一种方法涉及依赖、布局、属性设置以及MainActivity的代码实现。第二种方法则无需依赖,重点在于布局、属性设置和ThemeManager的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


第一种


一、依赖

compile 'com.android.support:appcompat-v7:26.1.0'

二、布局

<TextView
    android:id="@+id/yejian"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="夜间模式" />

三、属性设置

res下新建文件夹 values-night  ,  values-night下新建 colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3b3b3b</color>
    <color name="colorPrimaryDark">#383838</color>
    <color name="colorAccent">#a72b55</color>
    <color name="textColor">#FFFFFF</color>
    <color name="backgroundColor">#3b3b3b</color>
</resources>

原values下colors

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="textColor">#FF000000</color>
    <color name="backgroundColor">#FFFFFF</color>
</resources>
 

四、代码    MainActivity

import android.content.res.Configuration;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatDelegate;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView yejian;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 默认设置为日间模式
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        setContentView(R.layout.activity_main);
        yejian = (TextView) findViewById(R.id.yejian);
        yejian.setOnClickListener(new View.OnClickListener() {
            private int qiehuan;
            @Override
            public void onClick(View view) {
                int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
                getDelegate().setLocalNightMode(currentNightMode == Configuration.UI_MODE_NIGHT_NO ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
                recreate();
            }
        });
    }
}
 


第二种


一、布局(不需要依赖)

<Button
    android:text="夜间模式"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn_theme"/>
<TextView
    android:text="用接口回调方法"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tv" />

二、属性设置

values 下 colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimary_night">#3b3b3b</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorPrimaryDark_night">#383838</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorAccent_night">#a72b55</color>
    <color name="textColor">#FF000000</color>
    <color name="textColor_night">#FFFFFF</color>
    <color name="backgroundColor">#FFFFFF</color>
    <color name="backgroundColor_night">#3b3b3b</color>
</resources>
 

三、代码   ThemeManager

import android.content.Context;
import android.content.res.Resources;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class ThemeManager {
    // 默认是日间模式
    private static ThemeMode mThemeMode = ThemeMode.DAY;
    // 主题模式监听器
    private static List<OnThemeChangeListener> mThemeChangeListenerList = new LinkedList<>();
    // 夜间资源的缓存,key : 资源类型, 值<key:资源名称, value:int值>
    private static HashMap<String, HashMap<String, Integer>> sCachedNightResrouces = new HashMap<>();
    // 夜间模式资源的后缀,比如日件模式资源名为:R.color.activity_bg, 那么夜间模式就为 :R.color.activity_bg_night
    private static final String RESOURCE_SUFFIX = "_night";
    /**
     * 主题模式,分为日间模式和夜间模式
     */
    public enum ThemeMode {
        DAY, NIGHT
    }
    /**
     * 设置主题模式
     *@param themeMode
     */
    public static void setThemeMode(ThemeMode themeMode) {
        if (mThemeMode != themeMode) {
            mThemeMode = themeMode;
            if (mThemeChangeListenerList.size() > 0) {
                for (OnThemeChangeListener listener : mThemeChangeListenerList) {
                    listener.onThemeChanged();
                }
            }
        }
    }
    /**
     * 根据传入的日间模式的resId得到相应主题的resId,注意:必须是日间模式的resId
     * @param dayResId 日间模式的resId
     * @return 相应主题的resId,若为日间模式,则得到dayResId;反之夜间模式得到nightResId
     */
    public static int getCurrentThemeRes(Context context, int dayResId) {
        if (getThemeMode() == ThemeMode.DAY) {
            return dayResId;
        }
        // 资源名
        String entryName = context.getResources().getResourceEntryName(dayResId);
        // 资源类型
        String typeName = context.getResources().getResourceTypeName(dayResId);
        HashMap<String, Integer> cachedRes = sCachedNightResrouces.get(typeName);
        // 先从缓存中去取,如果有直接返回该id
        if (cachedRes == null) {
            cachedRes = new HashMap<>();
        }
        Integer resId = cachedRes.get(entryName + RESOURCE_SUFFIX);
        if (resId != null && resId != 0) {
            return resId;
        } else {
            //如果缓存中没有再根据资源id去动态获取
            try {
                // 通过资源名,资源类型,包名得到资源int值
                int nightResId = context.getResources().getIdentifier(entryName + RESOURCE_SUFFIX, typeName, context.getPackageName());
                // 放入缓存中
                cachedRes.put(entryName + RESOURCE_SUFFIX, nightResId);
                sCachedNightResrouces.put(typeName, cachedRes);
                return nightResId;
            } catch (Resources.NotFoundException e) {
                e.printStackTrace();
            }
        }
        return 0;
    }
    /**
     * 注册ThemeChangeListener
     * @param listener
     */
    public static void registerThemeChangeListener(OnThemeChangeListener listener) {
        if (!mThemeChangeListenerList.contains(listener)) {
            mThemeChangeListenerList.add(listener);
        }
    }
    /**
     * 反注册ThemeChangeListener
     * @param listener
     */
    public static void unregisterThemeChangeListener(OnThemeChangeListener listener) {
        if (mThemeChangeListenerList.contains(listener)) {
            mThemeChangeListenerList.remove(listener);
        }
    }
    /**
     * 得到主题模式
     * @return
     */
    public static ThemeMode getThemeMode() {
        return mThemeMode;
    }
    /**
     * 主题模式切换监听器
     */
    public interface OnThemeChangeListener {
        /**
         * 主题切换时回调
         */
        void onThemeChanged();
    }
}
 

MainActivity

import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements ThemeManager.OnThemeChangeListener {

    private TextView tv;
    private Button btn_theme;
    private LinearLayout relativeLayout;
    private ActionBar supportActionBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ThemeManager.registerThemeChangeListener(this);
        supportActionBar = getSupportActionBar();
        btn_theme = (Button) findViewById(R.id.btn_theme);
        relativeLayout = (LinearLayout) findViewById(R.id.relativeLayout);
        tv = (TextView) findViewById(R.id.tv);
        btn_theme.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ThemeManager.setThemeMode(ThemeManager.getThemeMode() == ThemeManager.ThemeMode.DAY
                        ? ThemeManager.ThemeMode.NIGHT : ThemeManager.ThemeMode.DAY);
                if (ThemeManager.getThemeMode()== ThemeManager.ThemeMode.NIGHT){
                    btn_theme.setText("日间模式");
                }else{
                    btn_theme.setText("夜间模式");
                }
            }
        });
    }

    public void initTheme() {
        tv.setTextColor(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.textColor)));
        btn_theme.setTextColor(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.textColor)));
        relativeLayout.setBackgroundColor(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.backgroundColor)));
        // 设置标题栏颜色
        if(supportActionBar != null){
            supportActionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.colorPrimary))));
        }
        // 设置状态栏颜色
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            window.setStatusBarColor(getResources().getColor(ThemeManager.getCurrentThemeRes(MainActivity.this, R.color.colorPrimary)));
        }
    }
    @Override
    public void onThemeChanged() {
        initTheme();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ThemeManager.unregisterThemeChangeListener(this);
    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值