├── .gitignore ├── MyApplication.iml ├── README.md ├── app ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── yw │ │ └── skin │ │ └── ywskin │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── daysmatter.db │ │ ├── holiday.json │ │ ├── redskin.skin │ │ ├── skins │ │ │ ├── colorskin.skin │ │ │ └── redskin.skin │ │ └── solarterm.db │ ├── java │ │ └── com │ │ │ └── yw │ │ │ └── skin │ │ │ └── ywskin │ │ │ ├── App.java │ │ │ ├── MainActivity.java │ │ │ ├── utils │ │ │ ├── CustomViewSkinUtils.java │ │ │ └── SpUtils.java │ │ │ └── wiget │ │ │ └── CustomCircleView.java │ └── res │ │ ├── drawable │ │ ├── layer_all_rl_bg.xml │ │ ├── layer_rl_bg.xml │ │ ├── skin_tv_circle_bg.xml │ │ ├── tv_color_bg.xml │ │ ├── tv_red_bg.xml │ │ └── tv_reset_bg.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── attri.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── yw │ └── skin │ └── ywskin │ └── ExampleUnitTest.java ├── build.gradle ├── colorskin ├── build.gradle ├── colorskin.iml ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── yw │ │ └── skin │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── yw │ │ │ └── skin │ │ │ └── CustomGetResourcesUtils.java │ └── res │ │ ├── drawable │ │ ├── layer_all_rl_bg.xml │ │ └── layer_rl_bg.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── eventbg.jpg │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── yw │ └── skin │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── redskin ├── build.gradle ├── proguard-rules.pro ├── redskin.iml └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── yw │ │ └── skin │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── yw │ │ │ └── skin │ │ │ └── CustomGetResourcesUtils.java │ └── res │ │ ├── drawable │ │ └── layer_rl_bg.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── yw │ └── skin │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | 3 | .idea/ 4 | build/ 5 | */build/ 6 | gradlew 7 | gradlew.bat 8 | local.properties 9 | .gitignore -------------------------------------------------------------------------------- /MyApplication.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | ##### 上篇文章介绍了Android-skin-support的缺陷([Android-skin-support的缺陷](http://www.jianshu.com/p/cfb7fef0ff46)),那么这篇文章就来介绍一下如何解决这个缺陷。我们这里就通过一个自定义的换肤框架和Android-skin-support一起配合使用就可以满足各种常规和非常规的换肤需求。CustomSkinChange是一款Android自定义的换肤框架,功能强大,可以配合Android-skin-support一起使用,它通过反射换肤的skin包(其实就是APK包)获取其中的资源动态的设置需要换肤的app。它配置有点麻烦,但是功能强大,它不仅可以完成Android-skin-support的功能,比如换控件的背景颜色、透明度、图片,它还可以完成Android-skin-support不能完成的功能,比如坐标、自定义属性、字体内容、控件的宽高等,它几乎可以通过获取包括皮肤包在Android项目资源文件下的任何资源进行换肤。 3 | [Android-skin-support的github地址](https://github.com/ximsfei/Android-skin-support.git) 4 | #### 这款框架还可以: 5 | - 尤其对于某些自定义的控件的自定义属性也可以切换皮肤包中的资源,比如圆的颜色以及圆的半径都都可以根据换肤包切换。 6 | 7 | ![image.png](http://upload-images.jianshu.io/upload_images/9374751-d75bf3a2a599347a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 8 | 9 | 10 | - 字体的颜色、字体的内容、字体的坐标都难以通过换肤包切换 11 | 12 | ![image.png](http://upload-images.jianshu.io/upload_images/9374751-f87706062a3a57f7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 13 | 14 | 15 | - 控件的宽高、坐标位置也能根据皮肤包中的资源进行切换 16 | 17 | ![image.png](http://upload-images.jianshu.io/upload_images/9374751-e38c756fd04e8326.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 18 | 19 | ##### 由于它需要通过反射来获取皮肤包中的资源进行动态换肤,所以需要换肤包提供反射的方法,配置也就会比Android-skin-support 20 | ##### 麻烦,但是它可以完成Android-skin-support不能完成的需求,所以可以用Android-skin-support完成大部分可以完成 21 | ##### 的换肤需求,然后通过CustomSkinChange去解决那些非常规的需求。 22 | # 正文 23 | #### 先看看换肤的动画效果 24 | ![2017-12-20_20_30_05.gif](http://upload-images.jianshu.io/upload_images/9374751-867d686b493d5286.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 25 | #### 1.点击按钮切换皮肤包,并对换肤名称进行持久化 26 | ``` 27 | @Event(value = {R.id.skin_reset_tv, R.id.skin_red_tv, R.id.skin_color_tv}) 28 | private void onClick(View view) { 29 | 30 | switch (view.getId()) { 31 | case R.id.skin_reset_tv://默认的蓝色皮肤 32 | Log.i( "skin_reset", "###重置" ); 33 | saveZhutiName( CustomViewSkinUtils.RESET_SKIN ); 34 | setSkinResource(); 35 | skinReFresh(); 36 | break; 37 | case R.id.skin_red_tv://红色皮肤 38 | Log.i( "skin_reset", "###红色" ); 39 | saveZhutiName( CustomViewSkinUtils.RED_SKIN ); 40 | CustomViewSkinUtils.copySkinApk( this, CustomViewSkinUtils.RED_SKIN ); 41 | setSkinResource(); 42 | skinReFresh(); 43 | break; 44 | case R.id.skin_color_tv://多彩的图片皮肤 45 | saveZhutiName( CustomViewSkinUtils.COLOR_SKIN ); 46 | CustomViewSkinUtils.copySkinApk( this, CustomViewSkinUtils.COLOR_SKIN ); 47 | setSkinResource(); 48 | skinReFresh(); 49 | break; 50 | } 51 | } 52 | ``` 53 | 利用sp对换肤的名称进行持久化 54 | ``` 55 | SpUtils.getInstance( this ).saveSkinName( highZhuTiName.substring( 0, len ) ); 56 | ``` 57 | #### 2.因为Android-skin-support的换肤包都是放在assets/skins的文件夹下面的,CustomSkinChange是配合Android-skin-support使用,那么它的换肤包也是从assets/skins文件夹下面取,取同样的换肤包存入sd卡中(如果只想利用CustomSkinChange换肤,不用Android-skin-support框架,那么就可以把换肤包放在sd卡中)。 58 | ``` 59 | /** 60 | * 因为Android-skin-support的皮肤包是放在assets中的,所以我们这里也从assets中获取皮肤包 61 | * 并保存在sdk中(这里只是为了兼容Android-skin-support ,其实可以直接把皮肤包放在sdk中的) 62 | * @param context 63 | * @param skinName 皮肤包的名称(不包括后缀名) 64 | */ 65 | public static void copySkinApk(Context context, String skinName) { 66 | try { 67 | File dex = new File( Environment.getExternalStorageDirectory().toString() + File.separator + skinName + ".apk" ); 68 | InputStream input = context.getAssets().open( "skins/" + skinName + ".skin" ); 69 | dex.createNewFile(); 70 | FileOutputStream fo = new FileOutputStream( dex ); 71 | int a = 0; 72 | byte bf[] = new byte[1024]; 73 | while ((a = input.read( bf )) != -1) { 74 | fo.write( bf, 0, a ); 75 | fo.flush(); 76 | } 77 | fo.close(); 78 | input.close(); 79 | } catch (IOException e) { 80 | e.printStackTrace(); 81 | } 82 | } 83 | ``` 84 | #### 3.在调用setSkinResource()获取换肤的资源 85 | ``` 86 | //设置换肤资源 87 | public void setSkinResource() { 88 | mSkinClzz = CustomViewSkinUtils.customViewChangeSkin( this ); 89 | mSkinResources = CustomViewSkinUtils.addOtherResourcesToMain( this ); 90 | } 91 | ``` 92 | ``` 93 | /** 94 | * 从sdk中获取皮肤包,然后通过DexClassLoader获取皮肤包中的设置色值、尺寸的类的Class 95 | * @param context 96 | * @return 97 | */ 98 | public static Class customViewChangeSkin(Context context) { 99 | String skinName = SpUtils.getInstance( context ).getSkinName(); 100 | Log.i("skin_reset", "###"+skinName); 101 | if (!DEFAULT_SKIN.equals( skinName )) { 102 | try { 103 | File dex_in = new File( Environment.getExternalStorageDirectory().toString() + File.separator + skinName + ".apk" ); 104 | String optimizedDirectory = context.getCacheDir() + File.separator; 105 | Log.i("skin_reset", dex_in.getAbsolutePath()+"###"+optimizedDirectory+" "+dex_in.getName()); 106 | ClassLoader classLoader = new DexClassLoader( dex_in.getAbsolutePath(), optimizedDirectory, null, context.getClassLoader() ); 107 | Class clazz = classLoader.loadClass( "com.yw.skin.CustomGetResourcesUtils" ); 108 | return clazz; 109 | } catch (ClassNotFoundException e) { 110 | e.printStackTrace(); 111 | } 112 | } 113 | return null; 114 | } 115 | ``` 116 | ``` 117 | /** 118 | * 通过addAssetPath将皮肤包中的资源增加到本apk自己的path里面以后 就可以重新构建出resource对象了 119 | * 利用这个Resource就可以通过反射获取皮肤包中的资源了 120 | * @param context 121 | * @return 122 | */ 123 | public static Resources addOtherResourcesToMain(Context context) { 124 | String skinName = SpUtils.getInstance( context ).getSkinName(); 125 | if (!DEFAULT_SKIN.equals( skinName )) { 126 | File dex_in = new File( Environment.getExternalStorageDirectory().toString() + File.separator + skinName + ".apk" ); 127 | AssetManager assetManager = null; 128 | try { 129 | assetManager = AssetManager.class.newInstance(); 130 | //反射调用addAssetPath这个方法 就可以 131 | Method addAssetPath = assetManager.getClass().getMethod( "addAssetPath", String.class ); 132 | addAssetPath.invoke( assetManager, dex_in.getAbsolutePath() ); 133 | } catch (InstantiationException e) { 134 | e.printStackTrace(); 135 | } catch (IllegalAccessException e) { 136 | e.printStackTrace(); 137 | } catch (NoSuchMethodException e) { 138 | e.printStackTrace(); 139 | } catch (InvocationTargetException e) { 140 | e.printStackTrace(); 141 | } 142 | //把themeapk里的资源 通过addAssetPath 这个方法增加到本apk自己的path里面以后 就可以重新构建出resource对象了 143 | return new Resources( assetManager, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration() ); 144 | } 145 | return null; 146 | } 147 | ``` 148 | #### 4.调用skinReFresh()进行换肤 149 | ``` 150 | //开始换肤 151 | public void skinReFresh() { 152 | mSkinTextViewName = CustomViewSkinUtils.getCustomViewSkin( this, "skin_text_name", mSkinClzz, mSkinResources, mSkinTextViewNameCp ); 153 | mSkin_tv.setText( mSkinTextViewName ); 154 | 155 | mSkinTextViewMargin = CustomViewSkinUtils.getCustomViewSkin( this, "skin_text_magin", mSkinClzz, mSkinResources, mSkinTextViewMarginCp ); 156 | RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mSkin_tv.getLayoutParams(); 157 | layoutParams.leftMargin = (int) mSkinTextViewMargin; 158 | mSkin_tv.setLayoutParams( layoutParams ); 159 | 160 | mSkinTextViewColor = CustomViewSkinUtils.getCustomViewSkin( this, "skin_text_color", mSkinClzz, mSkinResources, mSkinTextViewColorCp ); 161 | mSkin_tv.setTextColor( mSkinTextViewColor ); 162 | 163 | mSkinRlbg = CustomViewSkinUtils.getCustomViewSkin( this, "skin_bg_drawable", mSkinClzz, mSkinResources, mSkinRlbgCp ); 164 | mSkin_content_ll.setBackground( mSkinRlbg ); 165 | 166 | mSkinAllRlbg = CustomViewSkinUtils.getCustomViewSkin( this, "skin_bg_mipmap", mSkinClzz, mSkinResources, mSkinAllRlbgCp ); 167 | mSkin_all_rl.setBackground( mSkinAllRlbg ); 168 | 169 | mSkin_cricle.setSkinRefresh( mSkinClzz, mSkinResources ); 170 | } 171 | ``` 172 | #### 5.调用CustomViewSkinUtils.getCustomViewSkin()获取换肤包总的资源 173 | 如果换肤包不存在或者换肤包的内容没有此资源的反射方法,那么就返回默认皮肤的资源。 174 | ``` 175 | public static T getCustomViewSkin(Context context, String name, Class clazz, Resources resources, T normalParam) { 176 | String skinName = SpUtils.getInstance( context ).getSkinName(); 177 | if ((clazz != null && resources != null) && !DEFAULT_SKIN.equals( skinName )) { 178 | try { 179 | Method method = clazz.getMethod( name, Resources.class ); 180 | T newSkinName = (T) method.invoke( null, resources ); 181 | return newSkinName; 182 | } catch (Exception e) { 183 | e.printStackTrace(); 184 | } 185 | } 186 | return normalParam; 187 | } 188 | ``` 189 | #### 6.对于自定义控件的自定义属性的处理 190 | radius和solid_color是自定义圆的半径和颜色 191 | ``` 192 | 201 | ``` 202 | 获取自定义属性,并且再用一个变量存储这个默认皮肤(本app)的资源 203 | ``` 204 | private void init(Context context, AttributeSet attrs) { 205 | mContext = context; 206 | TypedArray array = getContext().obtainStyledAttributes( attrs, R.styleable.Circle ); 207 | Circle_solid_color = array.getColor( R.styleable.Circle_solid_color, Color.BLUE ); 208 | Circle_radius = array.getInteger( R.styleable.Circle_radius, 50 ); //半径 209 | Circle_radiusCp = Circle_radius;//默认皮肤的资源 210 | Circle_solid_colorCp = Circle_solid_color;//默认皮肤的资源 211 | array.recycle(); 212 | mPaint.setDither( true ); //防抖 213 | mPaint.setAntiAlias( true ); //抗锯齿 214 | mPaint.setStrokeWidth( 50 ); //设置画笔的线宽 215 | mPaint.setColor( Circle_solid_color ); 216 | 217 | } 218 | ``` 219 | 开始换肤,如果相关的皮肤包不存在或者资源的反射方法也不存在,那么就返回默认(本app)的资源 220 | ``` 221 | public void setSkinRefresh(Class clz, Resources res) { 222 | Circle_solid_color = CustomViewSkinUtils.getCustomViewSkinColor( mContext, "Circle_solid_color", clz, res, Circle_solid_colorCp ); 223 | Circle_radius = CustomViewSkinUtils.getCustomViewSkinSize( mContext, "Circle_radius", clz, res, Circle_radiusCp ); 224 | mPaint.setColor( Circle_solid_color ); 225 | this.invalidate();//调用此方法进行刷新布局 226 | } 227 | ``` 228 | 调用invalidate()就会重新执行一次ondraw()方法,利用获取的新资源重新画圆 229 | ``` 230 | @Override 231 | protected void onDraw(Canvas canvas) { 232 | super.onDraw( canvas ); 233 | int sizeX = getWidth() / 2; 234 | int sizeY = getHeight() / 2; 235 | canvas.drawCircle( sizeX, sizeY, Circle_radius, mPaint ); 236 | canvas.save(); 237 | } 238 | ``` 239 | ##### 这是github的源码[CustomSkinChange的demon](https://github.com/k55k55k55/CustomSkinChange) 240 | 241 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.0" 6 | defaultConfig { 7 | applicationId "com.yw.skin.ywskin" 8 | minSdkVersion 19 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | 25 | compile 'com.android.support:support-v4:25.3.1' 26 | compile 'com.android.support:appcompat-v7:25.3.1' 27 | 28 | testCompile 'junit:junit:4.12' 29 | compile 'org.xutils:xutils:3.3.36' 30 | } 31 | -------------------------------------------------------------------------------- /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 F:\newsdk\newsdk/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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/yw/skin/ywskin/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin.ywskin; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals( "com.yw.skin.ywskin", appContext.getPackageName() ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/assets/daysmatter.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/assets/daysmatter.db -------------------------------------------------------------------------------- /app/src/main/assets/holiday.json: -------------------------------------------------------------------------------- 1 | { 2 | "201612":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0], 3 | "20171":[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,1,1,1,1,1,1,1,0,2,0,0,0,0,0,0,0], 4 | "20172":[1,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 5 | "20173":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,0,0,0,0], 6 | "20174":[0,0,0,0,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0], 7 | "20175":[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0], 8 | "20176":[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 9 | "20177":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 10 | "20178":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 11 | "20179":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1], 12 | "201710":[1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 13 | "201711":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 14 | "201712":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0] 15 | } -------------------------------------------------------------------------------- /app/src/main/assets/redskin.skin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/assets/redskin.skin -------------------------------------------------------------------------------- /app/src/main/assets/skins/colorskin.skin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/assets/skins/colorskin.skin -------------------------------------------------------------------------------- /app/src/main/assets/skins/redskin.skin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/assets/skins/redskin.skin -------------------------------------------------------------------------------- /app/src/main/assets/solarterm.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/assets/solarterm.db -------------------------------------------------------------------------------- /app/src/main/java/com/yw/skin/ywskin/App.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin.ywskin; 2 | 3 | import android.app.ActivityManager; 4 | import android.app.Application; 5 | import android.content.Context; 6 | 7 | import org.xutils.x; 8 | 9 | /** 10 | * 自定义 Application 11 | *

12 | * Created by afon on 2017/1/24. 13 | */ 14 | 15 | public class App extends Application { 16 | private static Context mContext; 17 | 18 | 19 | 20 | 21 | @Override 22 | public void onCreate() { 23 | super.onCreate(); 24 | 25 | x.Ext.init(this); 26 | mContext = getApplicationContext(); 27 | 28 | 29 | } 30 | 31 | public static Context getAppContext() { 32 | return mContext; 33 | } 34 | 35 | 36 | 37 | 38 | private String getCurProcessName(Context context) { 39 | int pid = android.os.Process.myPid(); 40 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 41 | for (ActivityManager.RunningAppProcessInfo appProcess : activityManager.getRunningAppProcesses()) { 42 | if (appProcess.pid == pid) { 43 | return appProcess.processName; 44 | } 45 | } 46 | return ""; 47 | } 48 | 49 | public static Context getCurrentContext() { 50 | return mContext; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/yw/skin/ywskin/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin.ywskin; 2 | 3 | import android.content.res.Resources; 4 | import android.graphics.drawable.Drawable; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.util.Log; 8 | import android.view.View; 9 | import android.widget.LinearLayout; 10 | import android.widget.RelativeLayout; 11 | import android.widget.TextView; 12 | 13 | import com.yw.skin.ywskin.utils.CustomViewSkinUtils; 14 | import com.yw.skin.ywskin.utils.SpUtils; 15 | import com.yw.skin.ywskin.wiget.CustomCircleView; 16 | 17 | import org.xutils.view.annotation.ContentView; 18 | import org.xutils.view.annotation.Event; 19 | import org.xutils.view.annotation.ViewInject; 20 | import org.xutils.x; 21 | 22 | import static com.yw.skin.ywskin.R.id.skin_all_rl; 23 | 24 | @ContentView(R.layout.activity_main) 25 | public class MainActivity extends AppCompatActivity { 26 | 27 | @ViewInject(R.id.skin_reset_tv) 28 | TextView mSkin_reset_tv; 29 | @ViewInject(R.id.skin_red_tv) 30 | TextView mSkin_red_tv; 31 | @ViewInject(R.id.skin_color_tv) 32 | TextView mSkin_color_tv; 33 | @ViewInject(R.id.skin_click_ll) 34 | LinearLayout mSkin_click_ll; 35 | @ViewInject(R.id.skin_tv) 36 | TextView mSkin_tv; 37 | @ViewInject(R.id.skin_cricle) 38 | CustomCircleView mSkin_cricle; 39 | @ViewInject(R.id.skin_content_ll) 40 | RelativeLayout mSkin_content_ll; 41 | @ViewInject(skin_all_rl) 42 | RelativeLayout mSkin_all_rl; 43 | 44 | private Class mSkinClzz; 45 | private Resources mSkinResources; 46 | private String mSkinTextViewName; 47 | private String mSkinTextViewNameCp; 48 | private float mSkinTextViewMargin; 49 | private float mSkinTextViewMarginCp; 50 | private int mSkinTextViewColor; 51 | private int mSkinTextViewColorCp; 52 | private Drawable mSkinRlbg; 53 | private Drawable mSkinRlbgCp; 54 | private Drawable mSkinAllRlbg; 55 | private Drawable mSkinAllRlbgCp; 56 | 57 | @Override 58 | protected void onCreate(Bundle savedInstanceState) { 59 | super.onCreate( savedInstanceState ); 60 | x.view().inject( this ); 61 | init(); 62 | } 63 | 64 | private void init() { 65 | mSkinTextViewName = getResources().getString( R.string.skin_color_name ); 66 | mSkinTextViewNameCp = mSkinTextViewName; 67 | mSkinTextViewMargin = getResources().getDimension( R.dimen.text_view_margin_left ); 68 | mSkinTextViewMarginCp = mSkinTextViewMargin; 69 | mSkinTextViewColor = getResources().getColor( R.color.reset_blist1_color ); 70 | mSkinTextViewColorCp = mSkinTextViewColor; 71 | mSkinRlbg = getResources().getDrawable( R.drawable.layer_rl_bg ); 72 | mSkinRlbgCp = mSkinRlbg; 73 | mSkinAllRlbg = getResources().getDrawable( R.drawable.layer_all_rl_bg ); 74 | mSkinAllRlbgCp = mSkinAllRlbg; 75 | } 76 | 77 | @Event(value = {R.id.skin_reset_tv, R.id.skin_red_tv, R.id.skin_color_tv}) 78 | private void onClick(View view) { 79 | 80 | switch (view.getId()) { 81 | case R.id.skin_reset_tv://默认的蓝色皮肤 82 | Log.i( "skin_reset", "###重置" ); 83 | saveZhutiName( CustomViewSkinUtils.RESET_SKIN ); 84 | setSkinResource(); 85 | skinReFresh(); 86 | break; 87 | case R.id.skin_red_tv://红色皮肤 88 | Log.i( "skin_reset", "###红色" ); 89 | saveZhutiName( CustomViewSkinUtils.RED_SKIN ); 90 | CustomViewSkinUtils.copySkinApk( this, CustomViewSkinUtils.RED_SKIN ); 91 | setSkinResource(); 92 | skinReFresh(); 93 | break; 94 | case R.id.skin_color_tv://多彩的图片皮肤 95 | saveZhutiName( CustomViewSkinUtils.COLOR_SKIN ); 96 | CustomViewSkinUtils.copySkinApk( this, CustomViewSkinUtils.COLOR_SKIN ); 97 | setSkinResource(); 98 | skinReFresh(); 99 | break; 100 | } 101 | } 102 | 103 | //保存主题名称 104 | private void saveZhutiName(String highZhuTiName) { 105 | int len = highZhuTiName.contains( "." ) == true ? highZhuTiName.indexOf( "." ) : highZhuTiName.length(); 106 | SpUtils.getInstance( this ).saveSkinName( highZhuTiName.substring( 0, len ) ); 107 | } 108 | 109 | //设置换肤资源 110 | public void setSkinResource() { 111 | mSkinClzz = CustomViewSkinUtils.customViewChangeSkin( this ); 112 | mSkinResources = CustomViewSkinUtils.addOtherResourcesToMain( this ); 113 | } 114 | 115 | //开始换肤 116 | public void skinReFresh() { 117 | mSkinTextViewName = CustomViewSkinUtils.getCustomViewSkin( this, "skin_text_name", mSkinClzz, mSkinResources, mSkinTextViewNameCp ); 118 | mSkin_tv.setText( mSkinTextViewName ); 119 | 120 | mSkinTextViewMargin = CustomViewSkinUtils.getCustomViewSkin( this, "skin_text_magin", mSkinClzz, mSkinResources, mSkinTextViewMarginCp ); 121 | RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mSkin_tv.getLayoutParams(); 122 | layoutParams.leftMargin = (int) mSkinTextViewMargin; 123 | mSkin_tv.setLayoutParams( layoutParams ); 124 | 125 | mSkinTextViewColor = CustomViewSkinUtils.getCustomViewSkin( this, "skin_text_color", mSkinClzz, mSkinResources, mSkinTextViewColorCp ); 126 | mSkin_tv.setTextColor( mSkinTextViewColor ); 127 | 128 | mSkinRlbg = CustomViewSkinUtils.getCustomViewSkin( this, "skin_bg_drawable", mSkinClzz, mSkinResources, mSkinRlbgCp ); 129 | mSkin_content_ll.setBackground( mSkinRlbg ); 130 | 131 | mSkinAllRlbg = CustomViewSkinUtils.getCustomViewSkin( this, "skin_bg_mipmap", mSkinClzz, mSkinResources, mSkinAllRlbgCp ); 132 | mSkin_all_rl.setBackground( mSkinAllRlbg ); 133 | 134 | mSkin_cricle.setSkinRefresh( mSkinClzz, mSkinResources ); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /app/src/main/java/com/yw/skin/ywskin/utils/CustomViewSkinUtils.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin.ywskin.utils; 2 | 3 | import android.content.Context; 4 | import android.content.res.AssetManager; 5 | import android.content.res.Resources; 6 | import android.os.Environment; 7 | import android.util.Log; 8 | 9 | import java.io.File; 10 | import java.io.FileInputStream; 11 | import java.io.FileOutputStream; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.lang.reflect.InvocationTargetException; 15 | import java.lang.reflect.Method; 16 | 17 | import dalvik.system.DexClassLoader; 18 | 19 | /** 20 | * 专为自定义换肤的方案工具类 21 | * 22 | * @author yw 23 | * @time 2017/9/13 14:14 24 | * @desc ${TODD} 25 | */ 26 | 27 | public class CustomViewSkinUtils { 28 | public static final String DEFAULT_SKIN = "default"; 29 | public static final String RESET_SKIN = DEFAULT_SKIN; 30 | public static final String RED_SKIN = "redskin"; 31 | public static final String COLOR_SKIN = "colorskin"; 32 | 33 | /** 34 | * 从sdk中获取皮肤包,然后通过DexClassLoader获取皮肤包中的设置色值、尺寸的类的Class 35 | * @param context 36 | * @return 37 | */ 38 | public static Class customViewChangeSkin(Context context) { 39 | String skinName = SpUtils.getInstance( context ).getSkinName(); 40 | Log.i("skin_reset", "###"+skinName); 41 | if (!DEFAULT_SKIN.equals( skinName )) { 42 | try { 43 | File dex_in = new File( Environment.getExternalStorageDirectory().toString() + File.separator + skinName + ".apk" ); 44 | String optimizedDirectory = context.getCacheDir() + File.separator; 45 | Log.i("skin_reset", dex_in.getAbsolutePath()+"###"+optimizedDirectory+" "+dex_in.getName()); 46 | ClassLoader classLoader = new DexClassLoader( dex_in.getAbsolutePath(), optimizedDirectory, null, context.getClassLoader() ); 47 | Class clazz = classLoader.loadClass( "com.yw.skin.CustomGetResourcesUtils" ); 48 | return clazz; 49 | } catch (ClassNotFoundException e) { 50 | e.printStackTrace(); 51 | } 52 | } 53 | return null; 54 | } 55 | 56 | /** 57 | * 因为Android-skin-support的皮肤包是放在assets中的,所以我们这里也从assets中获取皮肤包 58 | * 并保存在sdk中(这里只是为了兼容Android-skin-support ,其实可以直接把皮肤包放在sdk中的) 59 | * @param context 60 | * @param skinName 皮肤包的名称(不包括后缀名) 61 | */ 62 | public static void copySkinApk(Context context, String skinName) { 63 | try { 64 | File dex = new File( Environment.getExternalStorageDirectory().toString() + File.separator + skinName + ".apk" ); 65 | InputStream input = context.getAssets().open( "skins/" + skinName + ".skin" ); 66 | dex.createNewFile(); 67 | FileOutputStream fo = new FileOutputStream( dex ); 68 | int a = 0; 69 | byte bf[] = new byte[1024]; 70 | while ((a = input.read( bf )) != -1) { 71 | fo.write( bf, 0, a ); 72 | fo.flush(); 73 | } 74 | fo.close(); 75 | input.close(); 76 | } catch (IOException e) { 77 | e.printStackTrace(); 78 | } 79 | } 80 | 81 | 82 | public static void copyNetSkinApk(Context context, String skinName,String path) { 83 | try { 84 | File dex = new File( Environment.getExternalStorageDirectory().toString() + File.separator + skinName + ".apk" ); 85 | // InputStream input = context.getAssets().open( "skins/" + skinName + ".skin" ); 86 | dex.createNewFile(); 87 | FileInputStream inputStream = new FileInputStream(path);//读入原文件 88 | FileOutputStream fo = new FileOutputStream( dex ); 89 | int a = 0; 90 | byte bf[] = new byte[1024]; 91 | while ((a = inputStream.read( bf )) != -1) { 92 | fo.write( bf, 0, a ); 93 | fo.flush(); 94 | } 95 | fo.close(); 96 | inputStream.close(); 97 | } catch (IOException e) { 98 | e.printStackTrace(); 99 | } 100 | } 101 | 102 | public static T getCustomViewSkin(Context context, String name, Class clazz, Resources resources, T normalParam) { 103 | String skinName = SpUtils.getInstance( context ).getSkinName(); 104 | if ((clazz != null && resources != null) && !DEFAULT_SKIN.equals( skinName )) { 105 | try { 106 | Method method = clazz.getMethod( name, Resources.class ); 107 | T newSkinName = (T) method.invoke( null, resources ); 108 | return newSkinName; 109 | } catch (Exception e) { 110 | e.printStackTrace(); 111 | } 112 | } 113 | return normalParam; 114 | } 115 | 116 | public static String getCustomViewSkinString(Context context, String name, Class clazz, Resources resources, String normalString) { 117 | String skinName = SpUtils.getInstance( context ).getSkinName(); 118 | if ((clazz != null && resources != null) && !DEFAULT_SKIN.equals( skinName )) { 119 | try { 120 | Method method = clazz.getMethod( name, Resources.class ); 121 | String newSkinName = (String) method.invoke( null, resources ); 122 | return newSkinName; 123 | } catch (Exception e) { 124 | e.printStackTrace(); 125 | } 126 | } 127 | return normalString; 128 | } 129 | 130 | public static int getCustomViewSkinColor(Context context, String name, Class clazz, Resources resources, int normalDayColor) { 131 | String skinName = SpUtils.getInstance( context ).getSkinName(); 132 | if ((clazz != null && resources != null) && !DEFAULT_SKIN.equals( skinName )) { 133 | try { 134 | Method method = clazz.getMethod( name, Resources.class ); 135 | int SkinColor = (int) method.invoke( null, resources ); 136 | return SkinColor; 137 | } catch (Exception e) { 138 | e.printStackTrace(); 139 | } 140 | } 141 | return normalDayColor; 142 | } 143 | 144 | public static float getCustomViewSkinSize(Context context, String name, Class clazz, Resources resources, float normalSize) { 145 | String skinName = SpUtils.getInstance( context ).getSkinName(); 146 | if ((clazz != null && resources != null) && !"default".equals( skinName )) { 147 | try { 148 | Method method = clazz.getMethod( name, Resources.class ); 149 | float SkinSize = (float) method.invoke( null, resources ); 150 | return SkinSize; 151 | } catch (Exception e) { 152 | e.printStackTrace(); 153 | } 154 | } 155 | return normalSize; 156 | } 157 | 158 | /** 159 | * 通过addAssetPath将皮肤包中的资源增加到本apk自己的path里面以后 就可以重新构建出resource对象了 160 | * 利用这个Resource就可以通过反射获取皮肤包中的资源了 161 | * @param context 162 | * @return 163 | */ 164 | public static Resources addOtherResourcesToMain(Context context) { 165 | String skinName = SpUtils.getInstance( context ).getSkinName(); 166 | if (!DEFAULT_SKIN.equals( skinName )) { 167 | File dex_in = new File( Environment.getExternalStorageDirectory().toString() + File.separator + skinName + ".apk" ); 168 | AssetManager assetManager = null; 169 | try { 170 | assetManager = AssetManager.class.newInstance(); 171 | //反射调用addAssetPath这个方法 就可以 172 | Method addAssetPath = assetManager.getClass().getMethod( "addAssetPath", String.class ); 173 | addAssetPath.invoke( assetManager, dex_in.getAbsolutePath() ); 174 | } catch (InstantiationException e) { 175 | e.printStackTrace(); 176 | } catch (IllegalAccessException e) { 177 | e.printStackTrace(); 178 | } catch (NoSuchMethodException e) { 179 | e.printStackTrace(); 180 | } catch (InvocationTargetException e) { 181 | e.printStackTrace(); 182 | } 183 | //把themeapk里的资源 通过addAssetPath 这个方法增加到本apk自己的path里面以后 就可以重新构建出resource对象了 184 | return new Resources( assetManager, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration() ); 185 | } 186 | return null; 187 | } 188 | 189 | } 190 | -------------------------------------------------------------------------------- /app/src/main/java/com/yw/skin/ywskin/utils/SpUtils.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin.ywskin.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | /** 7 | * SP保存数据 8 | */ 9 | 10 | public class SpUtils { 11 | 12 | private static final String SETTING = "setting"; 13 | 14 | private static final String SKIN_NAME = "skin_name"; 15 | 16 | private static SharedPreferences mSp; 17 | private static SpUtils spUtils; 18 | private static SharedPreferences.Editor mEdit; 19 | 20 | 21 | private SpUtils(Context context) { 22 | mSp = context.getSharedPreferences( SETTING, Context.MODE_PRIVATE ); 23 | } 24 | 25 | public static SpUtils getInstance(Context context) { 26 | if (spUtils == null) { 27 | spUtils = new SpUtils( context.getApplicationContext() ); 28 | } 29 | mEdit = mSp.edit(); 30 | return spUtils; 31 | } 32 | 33 | 34 | /** 35 | * 保存皮肤名称 36 | */ 37 | public void saveSkinName(String skinName) { 38 | mEdit.putString( SKIN_NAME, skinName ); 39 | mEdit.commit(); 40 | } 41 | 42 | /** 43 | * 获取皮肤名称 44 | */ 45 | public String getSkinName() { 46 | return mSp.getString( SKIN_NAME, "default" ); 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/yw/skin/ywskin/wiget/CustomCircleView.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin.ywskin.wiget; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.content.res.TypedArray; 6 | import android.graphics.Canvas; 7 | import android.graphics.Color; 8 | import android.graphics.Paint; 9 | import android.support.annotation.Nullable; 10 | import android.util.AttributeSet; 11 | 12 | import com.yw.skin.ywskin.R; 13 | import com.yw.skin.ywskin.utils.CustomViewSkinUtils; 14 | 15 | /** 16 | * @author yw 17 | * @time 2017/12/13 11:58 18 | * @desc ${TODD} 19 | */ 20 | 21 | public class CustomCircleView extends android.support.v7.widget.AppCompatTextView { 22 | private Paint mPaint = new Paint(); 23 | private float Circle_radius; 24 | private float Circle_radiusCp; 25 | private Context mContext; 26 | private int Circle_solid_color; 27 | private int Circle_solid_colorCp; 28 | 29 | public CustomCircleView(Context context) { 30 | super( context ); 31 | 32 | } 33 | 34 | public CustomCircleView(Context context, @Nullable AttributeSet attrs) { 35 | super( context, attrs ); 36 | init( context, attrs ); 37 | } 38 | 39 | public CustomCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 40 | super( context, attrs, defStyleAttr ); 41 | init( context, attrs ); 42 | } 43 | 44 | private void init(Context context, AttributeSet attrs) { 45 | mContext = context; 46 | TypedArray array = getContext().obtainStyledAttributes( attrs, R.styleable.Circle ); 47 | Circle_solid_color = array.getColor( R.styleable.Circle_solid_color, Color.BLUE ); 48 | Circle_radius = array.getInteger( R.styleable.Circle_radius, 50 ); //半径 49 | Circle_radiusCp = Circle_radius; 50 | Circle_solid_colorCp = Circle_solid_color; 51 | array.recycle(); 52 | mPaint.setDither( true ); //防抖 53 | mPaint.setAntiAlias( true ); //抗锯齿 54 | mPaint.setStrokeWidth( 50 ); //设置画笔的线宽 55 | mPaint.setColor( Circle_solid_color ); 56 | 57 | } 58 | 59 | @Override 60 | protected void onDraw(Canvas canvas) { 61 | super.onDraw( canvas ); 62 | int sizeX = getWidth() / 2; 63 | int sizeY = getHeight() / 2; 64 | canvas.drawCircle( sizeX, sizeY, Circle_radius, mPaint ); 65 | canvas.save(); 66 | } 67 | 68 | public void setSkinRefresh(Class clz, Resources res) { 69 | Circle_solid_color = CustomViewSkinUtils.getCustomViewSkinColor( mContext, "Circle_solid_color", clz, res, Circle_solid_colorCp ); 70 | Circle_radius = CustomViewSkinUtils.getCustomViewSkinSize( mContext, "Circle_radius", clz, res, Circle_radiusCp ); 71 | mPaint.setColor( Circle_solid_color ); 72 | this.invalidate(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layer_all_rl_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layer_rl_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/skin_tv_circle_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tv_color_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tv_red_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tv_reset_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 16 | 17 | 24 | 25 | 39 | 55 | 70 | 71 | 72 | 73 | 82 | 83 | 92 | 93 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/attri.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | #ffffff 8 | #38b7ea 9 | #f3f3f3 10 | #333333 11 | #7d7d7d 12 | #dddddd 13 | #fbfbfb 14 | #cccccc 15 | #777777 16 | #fbba2f 17 | #fd4311 18 | #eeeeee 19 | #888888 20 | #999999 21 | #16b0f8 22 | #605334 23 | #206885 24 | #8a9fb8 25 | #ea8d1f 26 | #98e2ff 27 | #ff8888 28 | #fee295 29 | #aa5b68 30 | #905714 31 | #eba595 32 | #cb5c5c 33 | #fce215 34 | #77dddddd 35 | #88ffffff 36 | #16b0f8 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0dp 5 | 50dp 6 | 200dp 7 | 200dp 8 | 20dp 9 | 140dp 10 | 100 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ywskin 3 | 蓝色 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/yw/skin/ywskin/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin.ywskin; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals( 4, 2 + 2 ); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.3.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /colorskin/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.0" 6 | 7 | defaultConfig { 8 | applicationId "com.yw.skin" 9 | minSdkVersion 15 10 | targetSdkVersion 25 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /colorskin/colorskin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /colorskin/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 F:\newsdk\newsdk/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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /colorskin/src/androidTest/java/com/yw/skin/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals( "com.yw.skin", appContext.getPackageName() ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /colorskin/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /colorskin/src/main/java/com/yw/skin/CustomGetResourcesUtils.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin; 2 | 3 | import android.content.res.Resources; 4 | import android.graphics.drawable.Drawable; 5 | 6 | /** 7 | * @author yw 8 | * @time 2017/9/13 14:57 9 | * @desc ${TODD} 10 | */ 11 | 12 | public class CustomGetResourcesUtils { 13 | //CustomCircleView中的圆的颜色 14 | public static int Circle_solid_color(Resources resources) { 15 | return resources.getColor( R.color.reset_blist1_color ); 16 | } 17 | //CustomCircleView中的圆的大小 18 | public static float Circle_radius(Resources resources) { 19 | return resources.getInteger( R.integer.skin_tv_circle_radues ); 20 | } 21 | //矩形框的drawable 22 | public static Drawable skin_bg_drawable(Resources resources) { 23 | return resources.getDrawable( R.drawable.layer_rl_bg ); 24 | } 25 | //最外层的背景图片 26 | public static Drawable skin_bg_mipmap(Resources resources) { 27 | return resources.getDrawable( R.drawable.layer_all_rl_bg ); 28 | } 29 | //获取文字的颜色 30 | public static int skin_text_color(Resources resources) { 31 | return resources.getColor( R.color.reset_blist1_color ); 32 | } 33 | //获取文字的位置 34 | public static float skin_text_magin(Resources resources) { 35 | return resources.getDimension( R.dimen.text_margin ); 36 | } 37 | 38 | //获取文字 39 | public static String skin_text_name(Resources resources) { 40 | return resources.getString( R.string.skin_color_name ); 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /colorskin/src/main/res/drawable/layer_all_rl_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /colorskin/src/main/res/drawable/layer_rl_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-xhdpi/eventbg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-xhdpi/eventbg.jpg -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /colorskin/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/colorskin/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /colorskin/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #3F51B5 5 | #303F9F 6 | #FF4081 7 | #fce215 8 | 9 | -------------------------------------------------------------------------------- /colorskin/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 200dp 6 | 7 | 20dp 8 | 9 | 150 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /colorskin/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | redskin 3 | 多彩的图片背景 4 | 5 | -------------------------------------------------------------------------------- /colorskin/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /colorskin/src/test/java/com/yw/skin/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals( 4, 2 + 2 ); 16 | } 17 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Dec 13 02:22:59 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip 7 | -------------------------------------------------------------------------------- /redskin/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.0" 6 | 7 | defaultConfig { 8 | applicationId "com.yw.skin" 9 | minSdkVersion 19 10 | targetSdkVersion 25 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /redskin/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 F:\newsdk\newsdk/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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /redskin/redskin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /redskin/src/androidTest/java/com/yw/skin/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals( "com.yw.skin", appContext.getPackageName() ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /redskin/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /redskin/src/main/java/com/yw/skin/CustomGetResourcesUtils.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin; 2 | 3 | import android.content.res.Resources; 4 | import android.graphics.drawable.Drawable; 5 | 6 | /** 7 | * @author yw 8 | * @time 2017/9/13 14:57 9 | * @desc ${TODD} 10 | */ 11 | 12 | public class CustomGetResourcesUtils { 13 | //CustomCircleView中的圆的颜色 14 | public static int Circle_solid_color(Resources resources) { 15 | return resources.getColor( R.color.reset_blist1_color ); 16 | } 17 | //CustomCircleView中的圆的大小 18 | public static float Circle_radius(Resources resources) { 19 | return resources.getInteger( R.integer.skin_tv_circle_radues ); 20 | } 21 | //矩形框的drawable 22 | public static Drawable skin_bg_drawable(Resources resources) { 23 | return resources.getDrawable( R.drawable.layer_rl_bg ); 24 | } 25 | /* //最外层的背景图片 26 | public static Drawable skin_bg_mipmap(Resources resources) { 27 | return resources.getDrawable( R.mipmap.rl_noad_blist21_nor_ft ); 28 | }*/ 29 | //获取文字的颜色 30 | public static int skin_text_color(Resources resources) { 31 | return resources.getColor( R.color.reset_blist1_color ); 32 | } 33 | //获取文字的位置 34 | public static float skin_text_magin(Resources resources) { 35 | return resources.getDimension( R.dimen.text_margin ); 36 | } 37 | 38 | //获取文字 39 | public static String skin_text_name(Resources resources) { 40 | return resources.getString( R.string.skin_color_name ); 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /redskin/src/main/res/drawable/layer_rl_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /redskin/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/k55k55k55/CustomSkinChange/bf762872e35895f0842c4c5d827608ff2fdefa28/redskin/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /redskin/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #3F51B5 5 | #303F9F 6 | #FF4081 7 | #fd7897 8 | 9 | -------------------------------------------------------------------------------- /redskin/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 50dp 6 | 7 | 20dp 8 | 9 | 200 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /redskin/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | redskin 3 | 红色 4 | 5 | -------------------------------------------------------------------------------- /redskin/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /redskin/src/test/java/com/yw/skin/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.yw.skin; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals( 4, 2 + 2 ); 16 | } 17 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':redskin', ':colorskin' 2 | --------------------------------------------------------------------------------