├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── maning │ │ └── androidchangeskindemo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── maning │ │ │ └── androidchangeskindemo │ │ │ ├── activity │ │ │ ├── BaseActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── OtherActivity.java │ │ │ ├── SettingActivity.java │ │ │ ├── WebViewActivity.java │ │ │ └── other │ │ │ │ ├── ColorMatrixActivity.java │ │ │ │ └── ColorMatrixUtils.java │ │ │ ├── adapter │ │ │ └── SkinAdapter.java │ │ │ └── app │ │ │ └── MyApplication.java │ └── res │ │ ├── drawable-xhdpi │ │ ├── android.png │ │ ├── nanzhuang.png │ │ └── nanzhuang_night.png │ │ ├── drawable │ │ ├── btn_round.xml │ │ └── btn_round_night.xml │ │ ├── layout │ │ ├── activity_colormatrix.xml │ │ ├── activity_main.xml │ │ ├── activity_other.xml │ │ ├── activity_setting.xml │ │ ├── activity_web_view.xml │ │ └── list_item.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── maning │ └── androidchangeskindemo │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshots └── 001.gif ├── settings.gradle └── themelibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── maning │ └── themelibrary │ └── ExampleInstrumentedTest.java ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── maning │ │ └── themelibrary │ │ ├── SkinBroadcastReceiver.java │ │ └── SkinManager.java └── res │ ├── anim │ ├── mn_theme_activity_enter.xml │ └── mn_theme_activity_exit.xml │ └── values │ └── strings.xml └── test └── java └── com └── maning └── themelibrary └── ExampleUnitTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AndroidChangeSkinDemo 2 | 3 | ### Android夜间模式,通过Theme实现(attrs.xml+styles.xml+Activity.setTheme()) 4 | [![](https://jitpack.io/v/maning0303/MNChangeSkin.svg)](https://jitpack.io/#maning0303/MNChangeSkin) 5 | 6 | ## 效果展示: 7 | ![](https://github.com/maning0303/MNChangeSkin/raw/master/screenshots/001.gif) 8 | 9 | ## 如何添加 10 | ### Gradle添加: 11 | #### 1.在Project的build.gradle中添加仓库地址 12 | 13 | ``` gradle 14 | allprojects { 15 | repositories { 16 | ... 17 | maven { url "https://jitpack.io" } 18 | } 19 | } 20 | ``` 21 | 22 | #### 2.在Module目录下的build.gradle中添加依赖 23 | ``` gradle 24 | dependencies { 25 | compile 'com.github.maning0303:MNChangeSkin:V1.0.0' 26 | } 27 | ``` 28 | 29 | 30 | ## 实现步骤: 31 | 32 | ##### 1.自定义属性 33 | ```java 34 | 35 | ``` 36 | 37 | ##### 2.定义两种主题,一个白天,一个夜间 38 | ```java 39 | 40 | 43 | 44 | 47 | ``` 48 | 49 | ##### 3.布局中使用: 50 | ```java 51 | 52 | android:background="?app_background" 53 | 54 | ``` 55 | 56 | #### 代码设置: 57 | ```java 58 | 59 | 1.再Application的onCreate() 中初始化: 60 | //设置白天主题的和夜间主题 61 | SkinManager.setThemeID(R.style.DayTheme, R.style.NightTheme); 62 | 63 | 2.新建一个BaseActivity,所有Activity继承它: 64 | public class BaseActivity extends Activity { 65 | @Override 66 | protected void onCreate(Bundle savedInstanceState) { 67 | //设置主题 68 | SkinManager.onActivityCreateSetSkin(this); 69 | super.onCreate(savedInstanceState); 70 | } 71 | } 72 | 73 | 3.XML文件中设置不了的就获取当前主题,手动设置: 74 | int currentSkinType = SkinManager.getCurrentSkinType(this); 75 | if (SkinManager.THEME_DAY == currentSkinType) { 76 | //改变颜色... 77 | } else { 78 | //改变颜色... 79 | } 80 | 81 | 4.广播的作用---主要防止设置界面太深,而设置界面之前的页面改不了(更换主题必须重启Activity才能有效果),如果更改主题的按钮在首页面,就没有必要使用注册广播了。 82 | public void registerSkinReceiver() { 83 | skinBroadcastReceiver = new SkinBroadcastReceiver() { 84 | @Override 85 | public void onChangeSkin(int currentTheme) { 86 | Log.i("onChangeSkin", "广播来了" + currentTheme); 87 | //重启Activity 88 | recreate(); 89 | } 90 | }; 91 | SkinManager.registerSkinReceiver(OtherActivity.this, skinBroadcastReceiver); 92 | } 93 | 94 | public void unregisterSkinReceiver() { 95 | if (skinBroadcastReceiver != null) { 96 | SkinManager.unregisterSkinReceiver(this, skinBroadcastReceiver); 97 | } 98 | } 99 | 100 | 5.改变主题: 101 | //改变主题:自动根据当前主题改变白天和黑夜 102 | SkinManager.changeSkin(this); 103 | //改变主题:指定主题 104 | //SkinManager.changeSkin(this,R.style.DayTheme); 105 | //重启当前Activity 106 | startActivity(new Intent(this, SettingActivity.class)); 107 | //重要:做一个自定义动画,避免出现闪烁现象 108 | overridePendingTransition(com.maning.themelibrary.R.anim.mn_theme_activity_enter, com.maning.themelibrary.R.anim.mn_theme_activity_exit); 109 | finish(); 110 | 111 | 112 | 6.关于WebView设置夜间模式: 113 | webView.setWebViewClient(new WebViewClient() { 114 | ... 115 | 116 | @Override 117 | public void onPageFinished(WebView view, String url) { 118 | super.onPageFinished(view, url); 119 | //设置webView,这里是设置夜间模式的颜色 120 | String backgroudColor = "#232736"; 121 | String fontColor = "#626f9b"; 122 | String urlColor = "#9AACEC"; 123 | SkinManager.setColorWebView(webView, backgroudColor, fontColor, urlColor); 124 | } 125 | 126 | ... 127 | }); 128 | 129 | 130 | ``` 131 | 132 | #### 详情见Demo 133 | 134 | 135 | ### 上线项目使用: 136 | #### [GanKMM](https://github.com/maning0303/GankMM) 137 | 138 | ### ColorMatrix 实现各种模式: 139 | #### [AppDress](https://github.com/lenebf/AppDress) 140 | 141 | ## 推荐: 142 | Name | Describe | 143 | --- | --- | 144 | [GankMM](https://github.com/maning0303/GankMM) | (Material Design & MVP & Retrofit + OKHttp & RecyclerView ...)Gank.io Android客户端:每天一张美女图片,一个视频短片,若干Android,iOS等程序干货,周一到周五每天更新,数据全部由 干货集中营 提供。 | 145 | [MNUpdateAPK](https://github.com/maning0303/MNUpdateAPK) | Android APK 版本更新的下载和安装,适配7.0,简单方便。 | 146 | [MNImageBrowser](https://github.com/maning0303/MNImageBrowser) | 交互特效的图片浏览框架,微信向下滑动动态关闭 | 147 | [MNCalendar](https://github.com/maning0303/MNCalendar) | 简单的日历控件练习,水平方向日历支持手势滑动切换,跳转月份;垂直方向日历选取区间范围。 | 148 | [MClearEditText](https://github.com/maning0303/MClearEditText) | 带有删除功能的EditText | 149 | [MNCrashMonitor](https://github.com/maning0303/MNCrashMonitor) | Debug监听程序崩溃日志,展示崩溃日志列表,方便自己平时调试。 | 150 | [MNProgressHUD](https://github.com/maning0303/MNProgressHUD) | MNProgressHUD是对常用的自定义弹框封装,加载ProgressDialog,状态显示的StatusDialog和自定义Toast,支持背景颜色,圆角,边框和文字的自定义。 | 151 | [MNXUtilsDB](https://github.com/maning0303/MNXUtilsDB) | xUtils3 数据库模块单独抽取出来,方便使用。 | 152 | [MNVideoPlayer](https://github.com/maning0303/MNVideoPlayer) | SurfaceView + MediaPlayer 实现的视频播放器,支持横竖屏切换,手势快进快退、调节音量,亮度等。------代码简单,新手可以看一看。 | 153 | [MNZXingCode](https://github.com/maning0303/MNZXingCode) | 快速集成二维码扫描和生成二维码 | 154 | [MNChangeSkin](https://github.com/maning0303/MNChangeSkin) | Android夜间模式,通过Theme实现 | 155 | [SwitcherView](https://github.com/maning0303/SwitcherView) | 垂直滚动的广告栏文字展示。 | 156 | 157 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | buildToolsVersion "28.0.3" 6 | 7 | defaultConfig { 8 | applicationId "com.maning.androidchangeskindemo" 9 | minSdkVersion 16 10 | targetSdkVersion 28 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(include: ['*.jar'], dir: 'libs') 24 | implementation 'androidx.appcompat:appcompat:1.0.0' 25 | implementation 'com.kyleduo.switchbutton:library:1.3.4' 26 | implementation project(':themelibrary') 27 | implementation 'androidx.constraintlayout:constraintlayout:2.0.1' 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/maning/Desktop/Android/AndroidStudioSDK/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/maning/androidchangeskindemo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 31 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/activity/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.activity; 2 | 3 | import android.os.Bundle; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | 6 | import com.maning.themelibrary.SkinManager; 7 | 8 | /** 9 | * Created by maning on 16/3/28. 10 | */ 11 | public class BaseActivity extends AppCompatActivity { 12 | 13 | //当前Activity的主题 14 | public int skinBase; 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | //设置主题 19 | SkinManager.onActivityCreateSetSkin(this); 20 | super.onCreate(savedInstanceState); 21 | //获取当前的主题 22 | skinBase = SkinManager.getCurrentSkinType(this); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.ListView; 9 | 10 | import com.maning.androidchangeskindemo.R; 11 | import com.maning.androidchangeskindemo.activity.other.ColorMatrixActivity; 12 | import com.maning.androidchangeskindemo.adapter.SkinAdapter; 13 | import com.maning.themelibrary.SkinBroadcastReceiver; 14 | import com.maning.themelibrary.SkinManager; 15 | 16 | 17 | public class MainActivity extends BaseActivity implements View.OnClickListener { 18 | 19 | private static final String TAG = MainActivity.class.getSimpleName(); 20 | private ListView listView; 21 | private SkinBroadcastReceiver skinBroadcastReceiver; 22 | private Button mBtnColormatrix; 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | Log.i(TAG, "onCreate"); 28 | setContentView(R.layout.activity_main); 29 | initView(); 30 | initAdapter(); 31 | //注册夜间模式广播监听 32 | registerSkinReceiver(); 33 | } 34 | 35 | private void initAdapter() { 36 | SkinAdapter skinAdapter = new SkinAdapter(this); 37 | listView.setAdapter(skinAdapter); 38 | } 39 | 40 | private void initView() { 41 | listView = (ListView) findViewById(R.id.listView); 42 | Button btn_setting = (Button) findViewById(R.id.btn_setting); 43 | Button btn_change = (Button) findViewById(R.id.btn_change); 44 | Button btn_webview = (Button) findViewById(R.id.btn_webview); 45 | btn_webview.setOnClickListener(this); 46 | btn_setting.setOnClickListener(this); 47 | btn_change.setOnClickListener(this); 48 | mBtnColormatrix = (Button) findViewById(R.id.btn_colormatrix); 49 | mBtnColormatrix.setOnClickListener(this); 50 | } 51 | 52 | @Override 53 | public void onClick(View v) { 54 | switch (v.getId()) { 55 | case R.id.btn_webview: 56 | startActivity(new Intent(MainActivity.this, WebViewActivity.class)); 57 | break; 58 | case R.id.btn_setting: 59 | startActivity(new Intent(MainActivity.this, OtherActivity.class)); 60 | break; 61 | case R.id.btn_change: 62 | SkinManager.changeSkin(this); 63 | resetActivity(); 64 | break; 65 | case R.id.btn_colormatrix: 66 | startActivity(new Intent(this, ColorMatrixActivity.class)); 67 | break; 68 | } 69 | } 70 | 71 | //重启当前Activity 72 | private void resetActivity() { 73 | startActivity(new Intent(this, MainActivity.class)); 74 | overridePendingTransition(com.maning.themelibrary.R.anim.mn_theme_activity_enter, com.maning.themelibrary.R.anim.mn_theme_activity_exit); 75 | finish(); 76 | } 77 | 78 | @Override 79 | protected void onDestroy() { 80 | super.onDestroy(); 81 | unregisterSkinReceiver(); 82 | } 83 | 84 | public void registerSkinReceiver() { 85 | skinBroadcastReceiver = new SkinBroadcastReceiver() { 86 | @Override 87 | public void onChangeSkin(int currentTheme) { 88 | Log.i("onChangeSkin", "MainActivity广播来了" + currentTheme); 89 | recreate(); 90 | } 91 | }; 92 | SkinManager.registerSkinReceiver(this, skinBroadcastReceiver); 93 | } 94 | 95 | public void unregisterSkinReceiver() { 96 | if (skinBroadcastReceiver != null) { 97 | SkinManager.unregisterSkinReceiver(this, skinBroadcastReceiver); 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/activity/OtherActivity.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | 8 | import com.maning.androidchangeskindemo.R; 9 | import com.maning.themelibrary.SkinBroadcastReceiver; 10 | import com.maning.themelibrary.SkinManager; 11 | 12 | public class OtherActivity extends BaseActivity { 13 | 14 | 15 | private SkinBroadcastReceiver skinBroadcastReceiver; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_other); 21 | 22 | findViewById(R.id.rl_setting).setOnClickListener(new View.OnClickListener() { 23 | @Override 24 | public void onClick(View v) { 25 | startActivity(new Intent(OtherActivity.this, SettingActivity.class)); 26 | } 27 | }); 28 | 29 | registerSkinReceiver(); 30 | 31 | } 32 | 33 | public void registerSkinReceiver() { 34 | skinBroadcastReceiver = new SkinBroadcastReceiver() { 35 | @Override 36 | public void onChangeSkin(int currentTheme) { 37 | Log.i("onChangeSkin", "OtherActivity广播来了" + currentTheme); 38 | //重启Activity 39 | recreate(); 40 | } 41 | }; 42 | SkinManager.registerSkinReceiver(OtherActivity.this, skinBroadcastReceiver); 43 | } 44 | 45 | public void unregisterSkinReceiver() { 46 | if (skinBroadcastReceiver != null) { 47 | SkinManager.unregisterSkinReceiver(this, skinBroadcastReceiver); 48 | } 49 | } 50 | 51 | 52 | @Override 53 | protected void onDestroy() { 54 | super.onDestroy(); 55 | unregisterSkinReceiver(); 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/activity/SettingActivity.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.widget.CompoundButton; 7 | 8 | import com.kyleduo.switchbutton.SwitchButton; 9 | import com.maning.androidchangeskindemo.R; 10 | import com.maning.themelibrary.SkinManager; 11 | 12 | public class SettingActivity extends BaseActivity { 13 | 14 | private static final String TAG = "SettingActivity"; 15 | private SwitchButton btn_checked; 16 | private Context context; 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_setting); 22 | 23 | context = this; 24 | 25 | btn_checked = (SwitchButton) findViewById(R.id.btn_checked); 26 | 27 | int currentSkinType = SkinManager.getCurrentSkinType(SettingActivity.this); 28 | if (SkinManager.THEME_DAY == currentSkinType) { 29 | btn_checked.setCheckedImmediately(false); 30 | btn_checked.setBackColorRes(R.color.kswBackColor); 31 | btn_checked.setThumbColorRes(R.color.kswThumbColor); 32 | } else { 33 | btn_checked.setCheckedImmediately(true); 34 | btn_checked.setBackColorRes(R.color.kswBackColor_night); 35 | btn_checked.setThumbColorRes(R.color.kswThumbColor_night); 36 | } 37 | 38 | btn_checked.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 39 | @Override 40 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 41 | SkinManager.changeSkin(SettingActivity.this); 42 | resetActivity(); 43 | } 44 | }); 45 | 46 | } 47 | 48 | //重启当前Activity 49 | private void resetActivity() { 50 | startActivity(new Intent(this, SettingActivity.class)); 51 | overridePendingTransition(com.maning.themelibrary.R.anim.mn_theme_activity_enter, com.maning.themelibrary.R.anim.mn_theme_activity_exit); 52 | finish(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/activity/WebViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.activity; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.graphics.Bitmap; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.webkit.WebResourceError; 8 | import android.webkit.WebResourceRequest; 9 | import android.webkit.WebView; 10 | import android.webkit.WebViewClient; 11 | 12 | import com.maning.androidchangeskindemo.R; 13 | import com.maning.themelibrary.SkinManager; 14 | 15 | public class WebViewActivity extends BaseActivity { 16 | 17 | private WebView webView; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_web_view); 23 | 24 | webView = (WebView) findViewById(R.id.webView); 25 | 26 | initWebView(); 27 | 28 | } 29 | 30 | @SuppressLint("SetJavaScriptEnabled") 31 | private void initWebView() { 32 | //设置背景色 33 | webView.setBackgroundColor(0); 34 | //设置WebView属性,能够执行Javascript脚本 35 | webView.getSettings().setJavaScriptEnabled(true); 36 | 37 | ////////////////////////////// 38 | webView.loadUrl("https://www.baidu.com"); 39 | //设置了默认在本应用打开,不设置会用浏览器打开的 40 | webView.setWebViewClient(new WebViewClient() { 41 | @Override 42 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 43 | //返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器 44 | view.loadUrl(url); 45 | return true; 46 | } 47 | 48 | @Override 49 | public void onPageFinished(WebView view, String url) { 50 | super.onPageFinished(view, url); 51 | //设置webView 52 | String backgroudColor = "#232736"; 53 | String fontColor = "#626f9b"; 54 | String urlColor = "#9AACEC"; 55 | SkinManager.setColorWebView(webView, backgroudColor, fontColor, urlColor); 56 | } 57 | 58 | @Override 59 | public void onPageStarted(WebView view, String url, Bitmap favicon) { 60 | super.onPageStarted(view, url, favicon); 61 | webView.setVisibility(View.VISIBLE); 62 | } 63 | 64 | @Override 65 | public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { 66 | super.onReceivedError(view, request, error); 67 | } 68 | }); 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/activity/other/ColorMatrixActivity.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.activity.other; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | import android.widget.Button; 6 | import android.widget.SeekBar; 7 | 8 | import androidx.appcompat.app.AppCompatActivity; 9 | 10 | import com.maning.androidchangeskindemo.R; 11 | 12 | /** 13 | * 引用:https://github.com/lenebf/AppDress 14 | */ 15 | public class ColorMatrixActivity extends AppCompatActivity implements View.OnClickListener { 16 | 17 | /** 18 | * 护眼模式 19 | */ 20 | private Button mBtnEye; 21 | /** 22 | * 黑白模式 23 | */ 24 | private Button mBtnBlackWhite; 25 | /** 26 | * 正常模式 27 | */ 28 | private Button mBtnNormal; 29 | /** 30 | * 夜间模式 31 | */ 32 | private Button mBtnNight; 33 | private SeekBar mSeekBar; 34 | 35 | @Override 36 | protected void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | setContentView(R.layout.activity_colormatrix); 39 | initView(); 40 | } 41 | 42 | private void initView() { 43 | mBtnEye = (Button) findViewById(R.id.btn_eye); 44 | mBtnEye.setOnClickListener(this); 45 | mBtnBlackWhite = (Button) findViewById(R.id.btn_black_white); 46 | mBtnBlackWhite.setOnClickListener(this); 47 | mBtnNormal = (Button) findViewById(R.id.btn_normal); 48 | mBtnNormal.setOnClickListener(this); 49 | mBtnNight = (Button) findViewById(R.id.btn_night); 50 | mBtnNight.setOnClickListener(this); 51 | mSeekBar = (SeekBar) findViewById(R.id.seek_bar); 52 | mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 53 | @Override 54 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 55 | float progressF = (float) progress / 100; 56 | ColorMatrixUtils.initEyeshield(ColorMatrixActivity.this, progressF); 57 | } 58 | 59 | @Override 60 | public void onStartTrackingTouch(SeekBar seekBar) { 61 | 62 | } 63 | 64 | @Override 65 | public void onStopTrackingTouch(SeekBar seekBar) { 66 | 67 | } 68 | }); 69 | } 70 | 71 | @Override 72 | public void onClick(View v) { 73 | switch (v.getId()) { 74 | default: 75 | break; 76 | case R.id.btn_eye: 77 | mSeekBar.setProgress(70); 78 | ColorMatrixUtils.initEyeshield(this); 79 | break; 80 | case R.id.btn_black_white: 81 | mSeekBar.setProgress(100); 82 | ColorMatrixUtils.initBlackWhite(this); 83 | break; 84 | case R.id.btn_normal: 85 | mSeekBar.setProgress(100); 86 | ColorMatrixUtils.initNormal(this); 87 | break; 88 | case R.id.btn_night: 89 | mSeekBar.setProgress(100); 90 | ColorMatrixUtils.initNight(this); 91 | break; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/activity/other/ColorMatrixUtils.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.activity.other; 2 | 3 | import android.app.Activity; 4 | import android.graphics.ColorMatrix; 5 | import android.graphics.ColorMatrixColorFilter; 6 | import android.graphics.Paint; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.view.Window; 10 | import android.widget.ImageView; 11 | 12 | import androidx.annotation.NonNull; 13 | 14 | /** 15 | * @author : maning 16 | * @date : 2020-09-29 17 | * @desc : 18 | */ 19 | public class ColorMatrixUtils { 20 | 21 | public static void initNormal(Activity activity) { 22 | Window window = activity.getWindow(); 23 | if (window == null) { 24 | return; 25 | } 26 | View view = window.getDecorView(); 27 | view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 28 | } 29 | 30 | public static void initEyeshield(Activity activity) { 31 | initEyeshield(activity, 0.7f); 32 | } 33 | 34 | /** 35 | * @param activity 36 | * @param defaultEyeSrc 0f-1.0f 之间 37 | */ 38 | public static void initEyeshield(Activity activity, float defaultEyeSrc) { 39 | Window window = activity.getWindow(); 40 | if (window == null) { 41 | return; 42 | } 43 | View view = window.getDecorView(); 44 | Paint paint = new Paint(); 45 | // 我们把蓝色减弱为原来的0.7 46 | ColorMatrix cm = new ColorMatrix(new float[]{ 47 | 1, 0, 0, 0, 0, 48 | 0, 1, 0, 0, 0, 49 | 0, 0, defaultEyeSrc, 0, 0, 50 | 0, 0, 0, 1, 0 51 | }); 52 | paint.setColorFilter(new ColorMatrixColorFilter(cm)); 53 | view.setLayerType(View.LAYER_TYPE_HARDWARE, paint); 54 | } 55 | 56 | public static void initBlackWhite(Activity activity) { 57 | Window window = activity.getWindow(); 58 | if (window == null) { 59 | return; 60 | } 61 | View view = window.getDecorView(); 62 | Paint paint = new Paint(); 63 | ColorMatrix cm = new ColorMatrix(); 64 | // 关键起作用的代码,Saturation,翻译成中文就是饱和度的意思。 65 | // 官方文档说明:A value of 0 maps the color to gray-scale. 1 is identity. 66 | // 原来如此,666 67 | cm.setSaturation(0f); 68 | paint.setColorFilter(new ColorMatrixColorFilter(cm)); 69 | view.setLayerType(View.LAYER_TYPE_HARDWARE, paint); 70 | } 71 | 72 | 73 | public static void initNight(Activity activity) { 74 | Window window = activity.getWindow(); 75 | if (window == null) { 76 | return; 77 | } 78 | View view = window.getDecorView(); 79 | Paint rootPaint = new Paint(); 80 | ColorMatrix cm = new ColorMatrix(new float[]{ 81 | -1, 0, 0, 0, 255, 82 | 0, -1, 0, 0, 255, 83 | 0, 0, -1, 0, 255, 84 | 0, 0, 0, 1, 0 85 | }); 86 | rootPaint.setColorFilter(new ColorMatrixColorFilter(cm)); 87 | view.setLayerType(View.LAYER_TYPE_HARDWARE, rootPaint); 88 | //遍历子view 89 | if (view instanceof ViewGroup) { 90 | takeOffColor((ViewGroup) view); 91 | } 92 | 93 | } 94 | 95 | public static void takeOffColor(ViewGroup viewGroup) { 96 | // 遍历查找ImageView,对其设置逆矩阵 97 | int childCount = viewGroup.getChildCount(); 98 | for (int i = 0; i < childCount; i++) { 99 | final View childView = viewGroup.getChildAt(i); 100 | if (childView instanceof ViewGroup) { 101 | takeOffColor((ViewGroup) childView); 102 | } else if (childView instanceof ImageView) { 103 | revert(childView); 104 | } 105 | } 106 | } 107 | 108 | public static void revert(@NonNull View view) { 109 | Paint paint = new Paint(); 110 | ColorMatrix cm = new ColorMatrix(new float[]{ 111 | -1, 0, 0, 0, 255, 112 | 0, -1, 0, 0, 255, 113 | 0, 0, -1, 0, 255, 114 | 0, 0, 0, 1, 0 115 | }); 116 | paint.setColorFilter(new ColorMatrixColorFilter(cm)); 117 | view.setLayerType(View.LAYER_TYPE_HARDWARE, paint); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/adapter/SkinAdapter.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.ImageView; 9 | import android.widget.TextView; 10 | 11 | import com.maning.androidchangeskindemo.R; 12 | 13 | /** 14 | * Created by maning on 16/3/28. 15 | */ 16 | public class SkinAdapter extends BaseAdapter { 17 | 18 | private Context context; 19 | private LayoutInflater inflater; 20 | 21 | public SkinAdapter(Context context) { 22 | this.context = context; 23 | inflater = LayoutInflater.from(this.context); 24 | } 25 | 26 | 27 | @Override 28 | public int getCount() { 29 | return 10; 30 | } 31 | 32 | @Override 33 | public Object getItem(int position) { 34 | return null; 35 | } 36 | 37 | @Override 38 | public long getItemId(int position) { 39 | return 0; 40 | } 41 | 42 | @Override 43 | public View getView(int position, View convertView, ViewGroup parent) { 44 | ViewHolder viewHolder; 45 | if (convertView == null) { 46 | viewHolder = new ViewHolder(); 47 | convertView = inflater.inflate(R.layout.list_item, parent, false); 48 | viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView); 49 | viewHolder.textView = (TextView) convertView.findViewById(R.id.textView); 50 | convertView.setTag(viewHolder); 51 | } else { 52 | viewHolder = (ViewHolder) convertView.getTag(); 53 | } 54 | viewHolder.textView.setText("这是男装" + position); 55 | 56 | return convertView; 57 | } 58 | 59 | private static class ViewHolder { 60 | ImageView imageView; 61 | TextView textView; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/maning/androidchangeskindemo/app/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.maning.androidchangeskindemo.app; 2 | 3 | import android.app.Application; 4 | 5 | import com.maning.androidchangeskindemo.R; 6 | import com.maning.themelibrary.SkinManager; 7 | 8 | /** 9 | * Created by maning on 2017/6/5. 10 | */ 11 | 12 | public class MyApplication extends Application { 13 | 14 | @Override 15 | public void onCreate() { 16 | super.onCreate(); 17 | 18 | initTheme(); 19 | } 20 | 21 | private void initTheme() { 22 | SkinManager.setThemeID(R.style.DayTheme, R.style.NightTheme); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maning0303/MNChangeSkin/9345f49e737ae843ce9fca988b0cda170fa28fcf/app/src/main/res/drawable-xhdpi/android.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/nanzhuang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maning0303/MNChangeSkin/9345f49e737ae843ce9fca988b0cda170fa28fcf/app/src/main/res/drawable-xhdpi/nanzhuang.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/nanzhuang_night.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maning0303/MNChangeSkin/9345f49e737ae843ce9fca988b0cda170fa28fcf/app/src/main/res/drawable-xhdpi/nanzhuang_night.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_round_night.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_colormatrix.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | 16 | 17 | 24 | 25 |