├── SwitchButton ├── .idea │ ├── .name │ ├── copyright │ │ └── profiles_settings.xml │ ├── scopes │ │ └── scope_settings.xml │ ├── encodings.xml │ ├── vcs.xml │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── gradle.xml │ ├── compiler.xml │ └── misc.xml ├── demo │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ └── ios_thumb.png │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable-xxhdpi │ │ │ │ │ ├── icon_blog.png │ │ │ │ │ └── icon_github.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── styles.xml │ │ │ │ │ └── strings.xml │ │ │ │ ├── color │ │ │ │ │ ├── custom_back_color.xml │ │ │ │ │ └── custom_thumb_color.xml │ │ │ │ ├── values-v21 │ │ │ │ │ └── styles.xml │ │ │ │ ├── drawable │ │ │ │ │ ├── ios_off.xml │ │ │ │ │ ├── ios_back_drawable.xml │ │ │ │ │ ├── miui_back_drawable.xml │ │ │ │ │ ├── flyme_back_drawable.xml │ │ │ │ │ ├── miui_thumb_drawable.xml │ │ │ │ │ └── flyme_thumb_drawable.xml │ │ │ │ ├── values-w820dp │ │ │ │ │ └── dimens.xml │ │ │ │ ├── layout │ │ │ │ │ ├── activity_main.xml │ │ │ │ │ ├── activity_style_in_code.xml │ │ │ │ │ ├── activity_style.xml │ │ │ │ │ └── activity_use.xml │ │ │ │ └── menu │ │ │ │ │ └── menu_main.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── kyleduo │ │ │ │ │ └── switchbutton │ │ │ │ │ └── demo │ │ │ │ │ ├── StyleActivity.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── StyleInCodeActivity.java │ │ │ │ │ └── UseActivity.java │ │ │ └── AndroidManifest.xml │ │ └── androidTest │ │ │ └── java │ │ │ └── com │ │ │ └── kyleduo │ │ │ └── switchbutton │ │ │ └── switchbutton │ │ │ └── ApplicationTest.java │ ├── proguard-rules.pro │ ├── build.gradle │ └── demo.iml ├── library │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ ├── styles.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── dimens.xml │ │ │ │ │ └── attrs.xml │ │ │ │ ├── color │ │ │ │ │ └── ksw_md_back_color.xml │ │ │ │ └── drawable │ │ │ │ │ └── ksw_md_thumb.xml │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── kyleduo │ │ │ │ └── switchbutton │ │ │ │ ├── ColorUtils.java │ │ │ │ └── SwitchButton.java │ │ └── androidTest │ │ │ └── java │ │ │ └── com │ │ │ └── kyleduo │ │ │ └── switchbutton │ │ │ └── switchbutton │ │ │ └── ApplicationTest.java │ ├── proguard-rules.pro │ ├── build.gradle │ └── library.iml ├── settings.gradle ├── .gitignore ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── build.gradle ├── SwitchButton.iml ├── gradlew.bat └── gradlew ├── preview └── demo_131.jpg ├── demo └── switchbutton_demo_131.apk ├── .gitignore ├── README.md └── CHANGELOG.md /SwitchButton/.idea/.name: -------------------------------------------------------------------------------- 1 | SwitchButton -------------------------------------------------------------------------------- /SwitchButton/demo/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /SwitchButton/library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /SwitchButton/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':library', ':demo' 2 | -------------------------------------------------------------------------------- /SwitchButton/library/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /preview/demo_131.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/preview/demo_131.jpg -------------------------------------------------------------------------------- /SwitchButton/library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /demo/switchbutton_demo_131.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/demo/switchbutton_demo_131.apk -------------------------------------------------------------------------------- /SwitchButton/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | -------------------------------------------------------------------------------- /SwitchButton/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable-xhdpi/ios_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/SwitchButton/demo/src/main/res/drawable-xhdpi/ios_thumb.png -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/SwitchButton/demo/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/SwitchButton/demo/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/SwitchButton/demo/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable-xxhdpi/icon_blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/SwitchButton/demo/src/main/res/drawable-xxhdpi/icon_blog.png -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable-xxhdpi/icon_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/SwitchButton/demo/src/main/res/drawable-xxhdpi/icon_github.png -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/SwitchButton/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wutongke/SwitchButton/master/SwitchButton/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /SwitchButton/.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /SwitchButton/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SwitchButton/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /SwitchButton/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 10 15:27:10 PDT 2013 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-2.2.1-all.zip 7 | -------------------------------------------------------------------------------- /SwitchButton/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/color/custom_back_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable/ios_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /SwitchButton/library/src/main/res/color/ksw_md_back_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | .idea/ 3 | 4 | # Android Stuido profile 5 | *.iml 6 | 7 | # Mobile Tools for Java (J2ME) 8 | .mtj.tmp/ 9 | 10 | # Package Files # 11 | *.jar 12 | *.war 13 | *.ear 14 | 15 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 16 | hs_err_pid* 17 | 18 | # ignore gen 19 | bin/ 20 | gen/ 21 | .DS_Store 22 | 23 | SwitchButton/gradle.properties 24 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/androidTest/java/com/kyleduo/switchbutton/switchbutton/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.switchbutton.switchbutton; 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 | } -------------------------------------------------------------------------------- /SwitchButton/library/src/androidTest/java/com/kyleduo/switchbutton/switchbutton/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.switchbutton.switchbutton; 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 | } -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/color/custom_thumb_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwitchButton/library/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | -------------------------------------------------------------------------------- /SwitchButton/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SwitchButton/library/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #1E000000 4 | #33019285 5 | 6 | #33000000 7 | 8 | #ECECEC 9 | #019285 10 | #FFFFFF 11 | #aaaaaa 12 | 13 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable/ios_back_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /SwitchButton/library/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 42dp 4 | 11dp 5 | 11dp 6 | 11dp 7 | 10dp 8 | 9 | 20dp 10 | 21dp 11 | 2dp 12 | 13 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable/miui_back_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable/flyme_back_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /SwitchButton/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:1.1.2' 9 | classpath 'com.github.dcendents:android-maven-plugin:1.2' 10 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0' 11 | 12 | // NOTE: Do not place your application dependencies here; they belong 13 | // in the individual module build.gradle files 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | jcenter() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /SwitchButton/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /SwitchButton/demo/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/kyle/Documents/developer/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 | -------------------------------------------------------------------------------- /SwitchButton/demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "22.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.kyleduo.switchbutton.demo" 9 | minSdkVersion 11 10 | targetSdkVersion 21 11 | versionCode 14 12 | versionName "1.3.1" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled true 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:23.1.0' 25 | compile project(':library') 26 | } 27 | -------------------------------------------------------------------------------- /SwitchButton/library/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/kyle/Documents/developer/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 | -------------------------------------------------------------------------------- /SwitchButton/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /SwitchButton/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /SwitchButton/SwitchButton.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable/miui_thumb_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/drawable/flyme_thumb_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 16 | 17 | 23 | 24 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/layout/activity_style_in_code.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 18 | 24 | 25 | 30 | 31 | -------------------------------------------------------------------------------- /SwitchButton/library/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/java/com/kyleduo/switchbutton/demo/StyleActivity.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.switchbutton.demo; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.ActionBarActivity; 5 | import android.widget.CompoundButton; 6 | 7 | import com.kyleduo.switchbutton.SwitchButton; 8 | 9 | public class StyleActivity extends ActionBarActivity { 10 | 11 | private SwitchButton mFlymeSb, mMiuiSb, mCustomSb, mDefaultSb; 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_style); 17 | 18 | SwitchButton disableSb = (SwitchButton) findViewById(R.id.sb_disable_control); 19 | mFlymeSb = (SwitchButton) findViewById(R.id.sb_custom_flyme); 20 | mMiuiSb = (SwitchButton) findViewById(R.id.sb_custom_miui); 21 | mCustomSb = (SwitchButton) findViewById(R.id.sb_custom); 22 | mDefaultSb = (SwitchButton) findViewById(R.id.sb_default); 23 | 24 | disableSb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 25 | @Override 26 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 27 | mFlymeSb.setEnabled(isChecked); 28 | mMiuiSb.setEnabled(isChecked); 29 | mCustomSb.setEnabled(isChecked); 30 | mDefaultSb.setEnabled(isChecked); 31 | } 32 | }); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 27 | 28 | 32 | 36 | 37 | 41 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /SwitchButton/library/src/main/java/com/kyleduo/switchbutton/ColorUtils.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.switchbutton; 2 | 3 | import android.content.res.ColorStateList; 4 | 5 | /** 6 | * Generate thumb and background color state list use tintColor 7 | * Created by kyle on 15/11/4. 8 | */ 9 | public class ColorUtils { 10 | private static final int ENABLE_ATTR = android.R.attr.state_enabled; 11 | private static final int CHECKED_ATTR = android.R.attr.state_checked; 12 | private static final int PRESSED_ATTR = android.R.attr.state_pressed; 13 | 14 | public static ColorStateList generateThumbColorWithTintColor(final int tintColor) { 15 | int[][] states = new int[][]{ 16 | {-ENABLE_ATTR, CHECKED_ATTR}, 17 | {-ENABLE_ATTR}, 18 | {PRESSED_ATTR, -CHECKED_ATTR}, 19 | {PRESSED_ATTR, CHECKED_ATTR}, 20 | {CHECKED_ATTR}, 21 | {-CHECKED_ATTR} 22 | }; 23 | 24 | int[] colors = new int[] { 25 | tintColor - 0xAA000000, 26 | 0xFFBABABA, 27 | tintColor - 0x99000000, 28 | tintColor - 0x99000000, 29 | tintColor | 0xFF000000, 30 | 0xFFEEEEEE 31 | }; 32 | return new ColorStateList(states, colors); 33 | } 34 | 35 | public static ColorStateList generateBackColorWithTintColor(final int tintColor) { 36 | int[][] states = new int[][]{ 37 | {-ENABLE_ATTR, CHECKED_ATTR}, 38 | {-ENABLE_ATTR}, 39 | {CHECKED_ATTR, PRESSED_ATTR}, 40 | {-CHECKED_ATTR, PRESSED_ATTR}, 41 | {CHECKED_ATTR}, 42 | {-CHECKED_ATTR} 43 | }; 44 | 45 | int[] colors = new int[] { 46 | tintColor - 0xE1000000, 47 | 0x10000000, 48 | tintColor - 0xD0000000, 49 | 0x20000000, 50 | tintColor - 0xD0000000, 51 | 0x20000000 52 | }; 53 | return new ColorStateList(states, colors); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | SwitchButton Demo 3 | 4 | Hello world! 5 | Settings 6 | 7 | version 1.3.1\nby kyleduo 8 | Apache License 2.0 9 | 10 | 11 | Default Style 12 | Default Style without background fade effect. 13 | Custom by tint color 14 | Custom Style 15 | Flyme5 Style 16 | MIUI7 Style 17 | Material Design & iOS Style 18 | Disable state 19 | Toggle the others\' enable state 20 | enable/disable other SwitchButtons 21 | 22 | 23 | work with listener 24 | work with delay 25 | You did it! 26 | work with stuff takes long 27 | Click "Start" button to kick it off. 28 | Click "Start" button to kick it off. 29 | 2 ways to TOGGLE 30 | 2 ways to SET_CHECKED 31 | toggle(); 32 | toggleImmediately(); 33 | setChecked(boolean); 34 | setCheckedImmediately(boolean); 35 | Start 36 | 37 | 38 | 39 | 40 | view in github 41 | my blog 42 | 43 | 44 | 45 | @string/title_activity_style 46 | @string/title_activity_style_in_code 47 | @string/title_activity_use 48 | @string/copyright 49 | @string/license 50 | 51 | 52 | Style in xml 53 | Easy to use 54 | Style in code 55 | 56 | -------------------------------------------------------------------------------- /SwitchButton/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Android 39 | 40 | 41 | Android Lint 42 | 43 | 44 | Gradle 45 | 46 | 47 | Java language level migration aids 48 | 49 | 50 | Probable bugsGradle 51 | 52 | 53 | 54 | 55 | Abstraction issues 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /SwitchButton/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/java/com/kyleduo/switchbutton/demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.switchbutton.demo; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.Menu; 8 | import android.view.MenuItem; 9 | import android.view.View; 10 | import android.widget.AdapterView; 11 | import android.widget.ListView; 12 | 13 | 14 | public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_main); 20 | ListView listView = (ListView) findViewById(R.id.list); 21 | listView.setOnItemClickListener(this); 22 | } 23 | 24 | 25 | @Override 26 | public boolean onCreateOptionsMenu(Menu menu) { 27 | getMenuInflater().inflate(R.menu.menu_main, menu); 28 | return true; 29 | } 30 | 31 | @Override 32 | public boolean onOptionsItemSelected(MenuItem item) { 33 | Intent intent = new Intent(Intent.ACTION_VIEW); 34 | int id = item.getItemId(); 35 | switch (id) { 36 | case R.id.action_github: 37 | intent.setData(Uri.parse("https://github.com/kyleduo/SwitchButton")); 38 | startActivity(intent); 39 | return true; 40 | case R.id.action_blog: 41 | intent.setData(Uri.parse("http://kyleduo.com")); 42 | startActivity(intent); 43 | return true; 44 | default: 45 | break; 46 | } 47 | return super.onOptionsItemSelected(item); 48 | } 49 | 50 | private void jumpToStyle() { 51 | startActivity(new Intent(this, StyleActivity.class)); 52 | } 53 | 54 | private void jumpToStyleInCode() { 55 | startActivity(new Intent(this, StyleInCodeActivity.class)); 56 | } 57 | 58 | private void jumpToUse() { 59 | startActivity(new Intent(this, UseActivity.class)); 60 | } 61 | 62 | private void gotoWeibo() { 63 | Intent intent = new Intent(Intent.ACTION_VIEW); 64 | intent.setData(Uri.parse("http://weibo.com/u/1762403573")); 65 | startActivity(intent); 66 | } 67 | 68 | private void gotoLicense() { 69 | Intent intent = new Intent(Intent.ACTION_VIEW); 70 | intent.setData(Uri.parse("http://www.apache.org/licenses/LICENSE-2.0")); 71 | startActivity(intent); 72 | } 73 | 74 | 75 | @Override 76 | public void onItemClick(AdapterView parent, View view, int position, long id) { 77 | switch (position) { 78 | case 0: 79 | jumpToStyle(); 80 | break; 81 | case 1: 82 | jumpToStyleInCode(); 83 | break; 84 | case 2: 85 | jumpToUse(); 86 | break; 87 | case 3: 88 | gotoWeibo(); 89 | break; 90 | case 4: 91 | gotoLicense(); 92 | break; 93 | 94 | default: 95 | break; 96 | } 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /SwitchButton/library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | apply plugin: 'com.jfrog.bintray' 4 | 5 | version = "1.3.1" 6 | 7 | def siteUrl = 'https://github.com/kyleduo/SwitchButton' 8 | def gitUrl = 'https://github.com/kyleduo/SwitchButton.git' 9 | group = "com.kyleduo.switchbutton" 10 | 11 | android { 12 | compileSdkVersion 23 13 | buildToolsVersion "22.0.1" 14 | resourcePrefix "SwitchButton__" 15 | 16 | defaultConfig { 17 | minSdkVersion 11 18 | targetSdkVersion 23 19 | versionCode 14 20 | versionName "1.3.1" 21 | } 22 | buildTypes { 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | } 29 | 30 | install { 31 | repositories.mavenInstaller { 32 | pom { 33 | //noinspection GroovyAssignabilityCheck 34 | project { 35 | packaging 'aar' 36 | 37 | // Add your description here 38 | name 'SwitchButton' 39 | url siteUrl 40 | 41 | // Set your license 42 | licenses { 43 | license { 44 | name 'The Apache Software License, Version 2.0' 45 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 46 | } 47 | } 48 | developers { 49 | developer { 50 | id 'kyleduo' 51 | name 'kyleduo' 52 | email 'kyleduo@gmail.com' 53 | } 54 | } 55 | scm { 56 | connection gitUrl 57 | developerConnection gitUrl 58 | url siteUrl 59 | 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | dependencies { 67 | compile fileTree(dir: 'libs', include: ['*.jar']) 68 | compile 'com.android.support:appcompat-v7:23.1.0' 69 | } 70 | 71 | task sourcesJar(type: Jar) { 72 | from android.sourceSets.main.java.srcDirs 73 | classifier = 'sources' 74 | } 75 | 76 | task javadoc(type: Javadoc) { 77 | source = android.sourceSets.main.java.srcDirs 78 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 79 | } 80 | 81 | task javadocJar(type: Jar, dependsOn: javadoc) { 82 | classifier = 'javadoc' 83 | from javadoc.destinationDir 84 | } 85 | 86 | artifacts { 87 | archives javadocJar 88 | archives sourcesJar 89 | } 90 | 91 | Properties properties = new Properties() 92 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 93 | bintray { 94 | user = properties.getProperty("bintray.user") 95 | key = properties.getProperty("bintray.apikey") 96 | configurations = ['archives'] 97 | pkg { 98 | repo = "maven" 99 | name = "SwitchButton" // project name in jcenter 100 | websiteUrl = siteUrl 101 | vcsUrl = gitUrl 102 | licenses = ["Apache-2.0"] 103 | publish = true 104 | } 105 | } -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/java/com/kyleduo/switchbutton/demo/StyleInCodeActivity.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.switchbutton.demo; 2 | 3 | import android.graphics.PointF; 4 | import android.graphics.RectF; 5 | import android.os.Bundle; 6 | import android.support.v7.app.ActionBarActivity; 7 | import android.view.View; 8 | import android.widget.AdapterView; 9 | import android.widget.ArrayAdapter; 10 | import android.widget.ListView; 11 | 12 | import com.kyleduo.switchbutton.SwitchButton; 13 | 14 | public class StyleInCodeActivity extends ActionBarActivity implements AdapterView.OnItemClickListener { 15 | 16 | private SwitchButton mChangeSb; 17 | private boolean mThumbMarginFlag, mThumbSizeFlag, mThumbRadiusFlag, mBackRadiusFlag, mBackMeasureRatioFlag, mAnimationDurationFlag; 18 | private String[] opts = new String[]{ 19 | "setThumbColorRes/setThumbColor", 20 | "setThumbDrawableRes/setThumbDrawable", 21 | "setBackColorRes/setBackColor", 22 | "setBackDrawableRes/setBackDrawable", 23 | "setTintColor", 24 | "setThumbMargin", 25 | "setThumbSize", 26 | "setThumbRadius (color-mode only)", 27 | "setBackRadius (color-mode only)", 28 | "setFadeBack", 29 | "setBackMeasureRatio", 30 | "setAnimationDuration", 31 | "setDrawDebugRect", 32 | }; 33 | 34 | @Override 35 | protected void onCreate(Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | setContentView(R.layout.activity_style_in_code); 38 | 39 | mChangeSb = (SwitchButton) findViewById(R.id.sb_code); 40 | ListView optLv = (ListView) findViewById(R.id.opt_lv); 41 | 42 | optLv.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1, opts)); 43 | optLv.setOnItemClickListener(this); 44 | } 45 | 46 | @Override 47 | public void onItemClick(AdapterView parent, View view, int position, long id) { 48 | switch (position) { 49 | case 0: 50 | mChangeSb.setThumbColorRes(R.color.custom_thumb_color); 51 | break; 52 | case 1: 53 | mChangeSb.setThumbDrawableRes(R.drawable.miui_thumb_drawable); 54 | break; 55 | case 2: 56 | mChangeSb.setBackColorRes(R.color.custom_back_color); 57 | break; 58 | case 3: 59 | mChangeSb.setBackDrawableRes(R.drawable.miui_back_drawable); 60 | break; 61 | case 4: 62 | mChangeSb.setTintColor(0x9F6C66); 63 | break; 64 | case 5: { 65 | float margin = 10 * getResources().getDisplayMetrics().density; 66 | float defaultMargin = SwitchButton.DEFAULT_THUMB_MARGIN_DP * getResources().getDisplayMetrics().density; 67 | mChangeSb.setThumbMargin(mThumbMarginFlag ? new RectF(defaultMargin, defaultMargin, defaultMargin, defaultMargin) : new RectF(margin, margin, margin, margin)); 68 | mThumbMarginFlag = !mThumbMarginFlag; 69 | } 70 | break; 71 | case 6: { 72 | float size = 30 * getResources().getDisplayMetrics().density; 73 | mChangeSb.setThumbSize(mThumbSizeFlag ? null : new PointF(size, size)); 74 | mThumbSizeFlag = !mThumbSizeFlag; 75 | } 76 | break; 77 | case 7: { 78 | float r = 2 * getResources().getDisplayMetrics().density; 79 | mChangeSb.setThumbRadius(mThumbRadiusFlag ? Math.min(mChangeSb.getThumbSizeF().x, mChangeSb.getThumbSizeF().y) / 2f : r); 80 | mThumbRadiusFlag = !mThumbRadiusFlag; 81 | } 82 | break; 83 | case 8: { 84 | float r = 2 * getResources().getDisplayMetrics().density; 85 | mChangeSb.setBackRadius(mBackRadiusFlag ? Math.min(mChangeSb.getBackSizeF().x, mChangeSb.getBackSizeF().y) / 2f : r); 86 | mBackRadiusFlag = !mBackRadiusFlag; 87 | } 88 | break; 89 | case 9: 90 | mChangeSb.setFadeBack(!mChangeSb.isFadeBack()); 91 | break; 92 | case 10: 93 | mChangeSb.setBackMeasureRatio(mBackMeasureRatioFlag ? SwitchButton.DEFAULT_BACK_MEASURE_RATIO : 2.4f); 94 | mBackMeasureRatioFlag = !mBackMeasureRatioFlag; 95 | break; 96 | case 11: 97 | mChangeSb.setAnimationDuration(mAnimationDurationFlag ? SwitchButton.DEFAULT_ANIMATION_DURATION : 1000); 98 | mAnimationDurationFlag = !mAnimationDurationFlag; 99 | break; 100 | case 12: 101 | mChangeSb.setDrawDebugRect(!mChangeSb.isDrawDebugRect()); 102 | break; 103 | default: 104 | break; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SwitchButton 2 | ============ 3 | 4 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-SwitchButton-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/1119) 5 | 6 | **To get a quick preview, you can find the Demo in [Google Play](https://play.google.com/store/apps/details?id=com.kyleduo.switchbutton.demo) or [My Blog](http://kyleduo.com/project/switchbutton/switchbutton_demo_131.apk).** 7 | 8 | This project provides you a convenient way to use and customise a SwitchButton widget in Android. With just resources changed and attrs set, you can create a lifelike SwitchButton of Android 5.0+, iOS, MIUI, or Flyme and so on. 9 | 10 | Now we get the biggest movement since SwitchButton published. v1.3.0 comes with totally reconsitution and more convenient API. A wholly new demo can give you a tour in it. 11 | 12 | *** 13 | Change Log 14 | --- 15 | [Change Log 1.3.1](https://github.com/kyleduo/SwitchButton/blob/master/CHANGELOG.md) 16 | 17 | Using SwitchButton in your application 18 | --- 19 | ~~ADT~~ 20 | 21 | ~~Clone the project and use the -adt part as library~~ 22 | No more support 23 | 24 | __Gradle__ 25 | 26 | Add dependencies in build.gradle of your module 27 | 28 | dependencies { 29 | compile 'com.kyleduo.switchbutton:library:1.3.1' 30 | } 31 | *** 32 | Demo 33 | --- 34 | I create a new demo apk to show you how to style the cute widget and use it. There's some screenshots of the new demo. 35 | 36 | ![demo_preview](https://raw.githubusercontent.com/kyleduo/SwitchButton/master/preview/demo_131.jpg) 37 | 38 | *** 39 | Usage 40 | --- 41 | 42 | In 1.3.0, I updated the usage of __SwitchButton__ library. To make it more Android way to use, I've combined the thumb and back style each to StateListColor/StateListDrawable. So you are free to create styles in different states. 43 | 44 | In __xml__ layout file, you can configure the face of switch button using these attrs. 45 | 46 | * __kswThumbDrawable__: drawable for thumb 47 | * __kswThumbColor__: color for thumb 48 | * __kswThumbMargin__: margin from thumb to back, can be negative. maybe cover by single direction margins 49 | * __kswThumbMarginTop__: same to __kswThumbMargin__, just top 50 | * __kswThumbMarginBottom__: same to __kswThumbMargin__, just bottom 51 | * __kswThumbMarginLeft__: same to __kswThumbMargin__, just left 52 | * __kswThumbMarginRight__: same to __kswThumbMargin__, just right 53 | * __kswThumbWidth__: width of thumb 54 | * __kswThumbHeight__: height of thumb 55 | * __kswThumbRadius__: radius of thumb rect, only work with __kswThumbColor__ 56 | * __kswBackRadius__: radius of background rect, only work with __kswBackColor__ 57 | * __kswBackDrawable__: drawable for background 58 | * __kswBackColor__: color for background 59 | * __kswFadeBack__: fade background color/drawable when drag or animate between on/off status or not 60 | * __kswBackMeasureRatio__: decide width of background from thumb's, this is the ratio 61 | * __kswAnimationDuration__: duration of animation between 2 status 62 | * __kswTintColor__: change SwitchButton's style just by __one__ property, all relevant color will be generate automatically. 63 | 64 | You can alse change the configuration of SwitchButton ___in code___. You can find the api from Demo apk. There's a glance. 65 | 66 | ``` 67 | private String[] opts = new String[]{ 68 | "setThumbColorRes/setThumbColor", 69 | "setThumbDrawableRes/setThumbDrawable", 70 | "setBackColorRes/setBackColor", 71 | "setBackDrawableRes/setBackDrawable", 72 | "setTintColor", 73 | "setThumbMargin", 74 | "setThumbSize", 75 | "setThumbRadius (color-mode only)", 76 | "setBackRadius (color-mode only)", 77 | "setFadeBack", 78 | "setBackMeasureRatio", 79 | "setAnimationDuration", 80 | "setDrawDebugRect", 81 | }; 82 | ``` 83 | 84 | License 85 | --- 86 | 87 | Licensed under the Apache License, Version 2.0 (the "License"); 88 | you may not use this file except in compliance with the License. 89 | You may obtain a copy of the License at 90 | 91 | http://www.apache.org/licenses/LICENSE-2.0 92 | 93 | Unless required by applicable law or agreed to in writing, software 94 | distributed under the License is distributed on an "AS IS" BASIS, 95 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 96 | See the License for the specific language governing permissions and 97 | limitations under the License. -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/java/com/kyleduo/switchbutton/demo/UseActivity.java: -------------------------------------------------------------------------------- 1 | package com.kyleduo.switchbutton.demo; 2 | 3 | import android.animation.Animator; 4 | import android.animation.ObjectAnimator; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.CompoundButton; 10 | import android.widget.ProgressBar; 11 | import android.widget.TextView; 12 | 13 | import com.kyleduo.switchbutton.SwitchButton; 14 | 15 | public class UseActivity extends AppCompatActivity implements View.OnClickListener { 16 | 17 | private SwitchButton mListenerSb, mLongSb, mToggleSb, mCheckedSb, mDelaySb; 18 | private ProgressBar mPb; 19 | private Button mStartBt, mToggleAniBt, mToggleNotAniBt, mCheckedAniBt, mCheckNotAniBt; 20 | private TextView mListenerFinish; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_use); 26 | 27 | findView(); 28 | 29 | // work with listener 30 | mListenerSb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 31 | 32 | @Override 33 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 34 | mListenerFinish.setVisibility(isChecked ? View.VISIBLE : View.INVISIBLE); 35 | } 36 | }); 37 | 38 | // work with delay 39 | mDelaySb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 40 | @Override 41 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 42 | mDelaySb.setEnabled(false); 43 | mDelaySb.postDelayed(new Runnable() { 44 | @Override 45 | public void run() { 46 | mDelaySb.setEnabled(true); 47 | } 48 | }, 1500); 49 | } 50 | }); 51 | 52 | // work with stuff takes long 53 | mStartBt.setOnClickListener(new View.OnClickListener() { 54 | 55 | @Override 56 | public void onClick(View v) { 57 | ObjectAnimator animator = ObjectAnimator.ofInt(mPb, "progress", 0, 1000); 58 | animator.setDuration(1000); 59 | animator.addListener(new Animator.AnimatorListener() { 60 | @Override 61 | public void onAnimationStart(Animator animation) { 62 | mStartBt.setEnabled(false); 63 | mLongSb.setChecked(false); 64 | } 65 | 66 | @Override 67 | public void onAnimationEnd(Animator animation) { 68 | mStartBt.setEnabled(true); 69 | mLongSb.setChecked(true); 70 | } 71 | 72 | @Override 73 | public void onAnimationCancel(Animator animation) { 74 | mStartBt.setEnabled(true); 75 | } 76 | 77 | @Override 78 | public void onAnimationRepeat(Animator animation) { 79 | 80 | } 81 | }); 82 | animator.start(); 83 | } 84 | }); 85 | 86 | // toggle 87 | mToggleAniBt.setOnClickListener(this); 88 | mToggleNotAniBt.setOnClickListener(this); 89 | 90 | // checked 91 | mCheckedAniBt.setOnClickListener(this); 92 | mCheckNotAniBt.setOnClickListener(this); 93 | } 94 | 95 | private void findView() { 96 | mListenerSb = (SwitchButton) findViewById(R.id.sb_use_listener); 97 | mLongSb = (SwitchButton) findViewById(R.id.sb_use_long); 98 | mToggleSb = (SwitchButton) findViewById(R.id.sb_use_toggle); 99 | mCheckedSb = (SwitchButton) findViewById(R.id.sb_use_checked); 100 | mDelaySb = (SwitchButton) findViewById(R.id.sb_use_delay); 101 | 102 | mPb = (ProgressBar) findViewById(R.id.pb); 103 | mPb.setProgress(0); 104 | mPb.setMax(1000); 105 | 106 | mStartBt = (Button) findViewById(R.id.long_start); 107 | mToggleAniBt = (Button) findViewById(R.id.toggle_ani); 108 | mToggleNotAniBt = (Button) findViewById(R.id.toggle_not_ani); 109 | mCheckedAniBt = (Button) findViewById(R.id.checked_ani); 110 | mCheckNotAniBt = (Button) findViewById(R.id.checked_not_ani); 111 | 112 | mListenerFinish = (TextView) findViewById(R.id.listener_finish); 113 | mListenerFinish.setVisibility(mListenerSb.isChecked() ? View.VISIBLE : View.INVISIBLE); 114 | } 115 | 116 | @Override 117 | public void onClick(View v) { 118 | int id = v.getId(); 119 | switch (id) { 120 | case R.id.toggle_ani: 121 | mToggleSb.toggle(); 122 | break; 123 | case R.id.toggle_not_ani: 124 | mToggleSb.toggleImmediately(); 125 | break; 126 | case R.id.checked_ani: 127 | mCheckedSb.setChecked(!mCheckedSb.isChecked()); 128 | break; 129 | case R.id.checked_not_ani: 130 | mCheckedSb.setCheckedImmediately(!mCheckedSb.isChecked()); 131 | break; 132 | 133 | default: 134 | break; 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ============ 3 | 4 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-SwitchButton-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/1119) 5 | 6 | **To get a quick preview, you can find the Demo in [Google Play](https://play.google.com/store/apps/details?id=com.kyleduo.switchbutton.demo) or [My Blog](http://kyleduo.com/project/switchbutton/switchbutton_demo_131.apk).** 7 | 8 | This project provides you a convenient way to use and customise a SwitchButton widget in Android. With just resources changed and attrs set, you can create a lifelike SwitchButton of Android 5.0+, iOS, MIUI, or Flyme and so on. 9 | 10 | Now we get the biggest movement since SwitchButton published. v1.3.0 comes with totally reconsitution and more convenient API. A wholly new demo can give you a tour in it. 11 | 12 | *** 13 | update 1.3.1 (Latest) 14 | --- 15 | * Remove shadow of MD style to support under 5.0. 16 | 17 | *** 18 | update 1.3.0 19 | --- 20 | * Reconstructe the whole library. 21 | * More convenient customization way by __tintColor__. 22 | * New design demo. All APIs in ONE. 23 | * Fix issue [#23](https://github.com/kyleduo/SwitchButton/issues/23) [#25](https://github.com/kyleduo/SwitchButton/issues/25) [#26](https://github.com/kyleduo/SwitchButton/issues/26) 24 | * Just exciting!!! 25 | 26 | *** 27 | 28 | update 1.2.10 29 | --- 30 | * Fix issue [#22](https://github.com/kyleduo/SwitchButton/issues/22) by change the attributes' name to prevent conflict; 31 | 32 | *** 33 | 34 | 35 | update 1.2.9 36 | --- 37 | * Fix issue [#19](https://github.com/kyleduo/SwitchButton/issues/19). 38 | 39 | *** 40 | 41 | update 1.2.8 42 | --- 43 | * Fix stretch bug while using higher API. 44 | * Add Gradle support. 45 | * Built in Android Studio. 46 | 47 | *** 48 | 49 | update 1.2.7 50 | --- 51 | * Fix rendering bug on some devices. 52 | * Fix states bug. 53 | 54 | *** 55 | 56 | update 1.2.6 57 | --- 58 | * With calling the method ___setChecked(boolean, false);___, you can change the status without invoking the listener. 59 | 60 | *** 61 | 62 | update 1.2.5 63 | --- 64 | * Fix shrink bug in Android 5.0 (the problem is same like it is in Android 4.4, which has been fixed in 1.2.4). 65 | * More available to setup Material Design style SwitchButton using ___@style/MD___ in xml layout. 66 | * Fix Demo Project bug 67 | 68 | *** 69 | 70 | update 1.2.4 71 | --- 72 | * fix shrink bug(that will cause the content out of bounds not disapper, on Android 4.4) 73 | * upload .pad resource, whitch I forgot to upload before.(My fault.) 74 | 75 | *** 76 | 77 | update 1.2.3 78 | --- 79 | * bug fix 80 | * upgrade demo apk 81 | * more clear way to use 82 | 83 | Since the animation ran on sub thread, "toggle" and "setChecked" methods may mot execute as you wish what cause the checked status change immediately. 84 | 85 | This problem may be solved, but I declared 2 methods to deal with the situation whether you want it happen immediately. 86 | 87 | If you want to set the checked status immediately, just call ___setChecked(boolean checked);___ method like CheckBox. And ___slideToChecked(boolean checked);___ method for slow one with slide animation. 88 | 89 | When toggle, call ___toggle();___ with change the status immediately and ___toggle(false);___ for slow one. 90 | 91 | 92 | ![easy_to_use](https://raw.githubusercontent.com/kyleduo/SwitchButton/master/preview/easy_to_use_128.png) 93 | 94 | *** 95 | update 1.2 96 | --- 97 | (11/08/2014) 98 | 99 | * Add StateList support for all resources and enable/disable, pressed has been tested in Demo. 100 | * New Style with __Material Design__, preview below. 101 | * Add "shrink" feature. This makes you can draw your image resources out size the view bounds, in the other word, shrink the size of view and make the experience stay the same. 102 | 103 | New Style with Material Design: 104 | 105 | ![materialdesign_style](https://raw.githubusercontent.com/kyleduo/SwitchButton/master/preview/switchbutton_md.jpg) 106 | 107 | To use shrink feature, you can easily add these attributes in your xml file. It is recommended that set these values positive. 108 | 109 | * __insetLeft__: left size for shrinking 110 | * __insetRight__: right size for shrinking 111 | * __insetTop__: top size for shrinking 112 | * __insetBottom__: bottom size for shrinking 113 | 114 | *** 115 | 116 | update 1.1 117 | --- 118 | (10/08/2014) 119 | 120 | * Fix lots of bugs. 121 | * Change the __default style__ 122 | * Add iOS7 style, you can just use like how the demo did 123 | * Update demo, it becomes more convenient, effective and beautiful 124 | * Add new attribute: measureFactor, you can custom the factor between width and height now. It is convenient to config the rest space of background. Learn more in the demo. 125 | * Update the logic of thumbMargin, it can work well with negative margins now (iOS style just using this trick). 126 | 127 | new default style and demo apk looks like this: 128 | 129 | ![default_style](https://raw.githubusercontent.com/kyleduo/SwitchButton/master/preview/default_style.png) 130 | 131 | ![demo_preview](https://raw.githubusercontent.com/kyleduo/SwitchButton/master/preview/easy_to_style_128.png) 132 | 133 | *** 134 | 135 | Update 1.0 136 | --- 137 | Add an attr of radius, now you can change the radius when configure the button's face! -------------------------------------------------------------------------------- /SwitchButton/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/layout/activity_style.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 18 | 23 | 24 | 29 | 30 | 36 | 37 | 42 | 43 | 44 | 45 | 50 | 51 | 56 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | 78 | 79 | 91 | 92 | 104 | 105 | 106 | 107 | 108 | 113 | 114 | 118 | 119 | 126 | 127 | 134 | 135 | 142 | 143 | 144 | 149 | 150 | 155 | 156 | 161 | 162 | 175 | 176 | 177 | 182 | 183 | 187 | 188 | 194 | 195 | 202 | 203 | 204 | 209 | 210 | 217 | 218 | -------------------------------------------------------------------------------- /SwitchButton/demo/src/main/res/layout/activity_use.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | 22 | 23 | 28 | 29 | 34 | 35 | 42 | 43 | 44 | 50 | 51 | 56 | 57 | 63 | 64 | 70 | 71 | 76 | 77 | 83 | 84 |