├── 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 |
4 |
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 |
4 |
5 |
6 |
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 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SwitchButton/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SwitchButton/SwitchButton.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
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 |
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 |
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 | [](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 | 
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 | [](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 | 
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 | 
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 | 
130 |
131 | 
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 |
89 |
90 |
95 |
96 |
104 |
105 |
112 |
113 |
114 |
120 |
121 |
126 |
127 |
131 |
132 |
140 |
141 |
146 |
147 |
154 |
155 |
162 |
163 |
164 |
165 |
171 |
172 |
177 |
178 |
182 |
183 |
191 |
192 |
197 |
198 |
205 |
206 |
213 |
214 |
215 |
216 |
217 |
--------------------------------------------------------------------------------
/SwitchButton/demo/demo.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
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 |
--------------------------------------------------------------------------------
/SwitchButton/library/src/main/res/drawable/ksw_md_thumb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
-
8 |
9 |
12 |
13 |
14 |
15 | -
21 |
22 |
23 |
24 |
25 | -
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | -
40 |
41 |
-
42 |
43 |
46 |
47 |
48 |
49 | -
55 |
56 |
57 |
58 |
59 | -
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | -
74 |
75 |
-
76 |
77 |
80 |
81 |
82 |
83 | -
89 |
90 |
91 |
92 |
93 | -
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | -
108 |
109 |
-
110 |
111 |
114 |
115 |
116 |
117 | -
123 |
124 |
125 |
126 |
127 | -
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | -
142 |
143 |
-
144 |
145 |
148 |
149 |
150 |
151 | -
157 |
158 |
159 |
160 |
161 | -
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | -
176 |
177 |
-
178 |
179 |
182 |
183 |
184 |
185 | -
191 |
192 |
193 |
194 |
195 | -
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
--------------------------------------------------------------------------------
/SwitchButton/library/library.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
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 |
--------------------------------------------------------------------------------
/SwitchButton/library/src/main/java/com/kyleduo/switchbutton/SwitchButton.java:
--------------------------------------------------------------------------------
1 | package com.kyleduo.switchbutton;
2 |
3 | import android.animation.ObjectAnimator;
4 | import android.content.Context;
5 | import android.content.res.ColorStateList;
6 | import android.content.res.Resources;
7 | import android.content.res.TypedArray;
8 | import android.graphics.Canvas;
9 | import android.graphics.Color;
10 | import android.graphics.Paint;
11 | import android.graphics.PointF;
12 | import android.graphics.RectF;
13 | import android.graphics.drawable.Drawable;
14 | import android.graphics.drawable.StateListDrawable;
15 | import android.support.v4.content.ContextCompat;
16 | import android.util.AttributeSet;
17 | import android.view.MotionEvent;
18 | import android.view.SoundEffectConstants;
19 | import android.view.ViewConfiguration;
20 | import android.view.ViewParent;
21 | import android.view.animation.AccelerateDecelerateInterpolator;
22 | import android.widget.CompoundButton;
23 |
24 |
25 | /**
26 | * SwitchButton
27 | *
28 | * @author kyleduo
29 | * @version 1.2.10
30 | * @since 2014-09-24
31 | */
32 |
33 | public class SwitchButton extends CompoundButton {
34 | public static final float DEFAULT_BACK_MEASURE_RATIO = 1.8f;
35 | public static final int DEFAULT_THUMB_SIZE_DP = 20;
36 | public static final int DEFAULT_THUMB_MARGIN_DP = 2;
37 | public static final int DEFAULT_ANIMATION_DURATION = 250;
38 | public static final int DEFAULT_TINT_COLOR = 0x327FC2;
39 |
40 | private static int[] CHECKED_PRESSED_STATE = new int[]{android.R.attr.state_checked, android.R.attr.state_enabled, android.R.attr.state_pressed};
41 | private static int[] UNCHECKED_PRESSED_STATE = new int[]{-android.R.attr.state_checked, android.R.attr.state_enabled, android.R.attr.state_pressed};
42 |
43 | private Drawable mThumbDrawable, mBackDrawable;
44 | private ColorStateList mBackColor, mThumbColor;
45 | private float mThumbRadius, mBackRadius;
46 | private RectF mThumbMargin;
47 | private float mBackMeasureRatio;
48 | private long mAnimationDuration;
49 | // fade back drawable or color when dragging or animating
50 | private boolean mFadeBack;
51 | private int mTintColor;
52 | private PointF mThumbSizeF;
53 |
54 | private int mCurrThumbColor, mCurrBackColor, mNextBackColor;
55 | private Drawable mCurrentBackDrawable, mNextBackDrawable;
56 | private RectF mThumbRectF, mBackRectF, mSafeRectF;
57 | private Paint mPaint;
58 | // whether using Drawable for thumb or back
59 | private boolean mIsThumbUseDrawable, mIsBackUseDrawable;
60 | private boolean mDrawDebugRect = false;
61 | private ObjectAnimator mProcessAnimator;
62 | // animation control
63 | private float mProcess;
64 | // temp position of thumb when dragging or animating
65 | private RectF mPresentThumbRectF;
66 | private float mStartX, mStartY, mLastX;
67 | private int mTouchSlop;
68 | private int mClickTimeout;
69 | private Paint mRectPaint;
70 |
71 | public SwitchButton(Context context, AttributeSet attrs, int defStyle) {
72 | super(context, attrs, defStyle);
73 | init(attrs);
74 | }
75 |
76 | public SwitchButton(Context context, AttributeSet attrs) {
77 | super(context, attrs);
78 | init(attrs);
79 | }
80 |
81 | public SwitchButton(Context context) {
82 | super(context);
83 | init(null);
84 | }
85 |
86 | private void init(AttributeSet attrs) {
87 | mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
88 | mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();
89 |
90 | mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
91 | mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
92 | mRectPaint.setStyle(Paint.Style.STROKE);
93 | mRectPaint.setStrokeWidth(getResources().getDisplayMetrics().density);
94 |
95 | mThumbRectF = new RectF();
96 | mBackRectF = new RectF();
97 | mSafeRectF = new RectF();
98 | mThumbSizeF = new PointF();
99 | mThumbMargin = new RectF();
100 |
101 | mProcessAnimator = ObjectAnimator.ofFloat(this, "process", 0, 0).setDuration(DEFAULT_ANIMATION_DURATION);
102 | mProcessAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
103 |
104 | mPresentThumbRectF = new RectF();
105 |
106 | Resources res = getResources();
107 | float density = res.getDisplayMetrics().density;
108 |
109 | Drawable thumbDrawable = null;
110 | ColorStateList thumbColor = null;
111 | float margin = density * DEFAULT_THUMB_MARGIN_DP;
112 | float marginLeft = 0;
113 | float marginRight = 0;
114 | float marginTop = 0;
115 | float marginBottom = 0;
116 | float thumbWidth = density * DEFAULT_THUMB_SIZE_DP;
117 | float thumbHeight = density * DEFAULT_THUMB_SIZE_DP;
118 | float thumbRadius = density * DEFAULT_THUMB_SIZE_DP / 2;
119 | float backRadius = thumbRadius;
120 | Drawable backDrawable = null;
121 | ColorStateList backColor = null;
122 | float backMeasureRatio = DEFAULT_BACK_MEASURE_RATIO;
123 | int animationDuration = DEFAULT_ANIMATION_DURATION;
124 | boolean fadeBack = true;
125 | int tintColor = Integer.MIN_VALUE;
126 |
127 | TypedArray ta = attrs == null ? null : getContext().obtainStyledAttributes(attrs, R.styleable.SwitchButton);
128 | if (ta != null) {
129 | thumbDrawable = ta.getDrawable(R.styleable.SwitchButton_kswThumbDrawable);
130 | thumbColor = ta.getColorStateList(R.styleable.SwitchButton_kswThumbColor);
131 | margin = ta.getDimension(R.styleable.SwitchButton_kswThumbMargin, margin);
132 | marginLeft = ta.getDimension(R.styleable.SwitchButton_kswThumbMarginLeft, margin);
133 | marginRight = ta.getDimension(R.styleable.SwitchButton_kswThumbMarginRight, margin);
134 | marginTop = ta.getDimension(R.styleable.SwitchButton_kswThumbMarginTop, margin);
135 | marginBottom = ta.getDimension(R.styleable.SwitchButton_kswThumbMarginBottom, margin);
136 | thumbWidth = ta.getDimension(R.styleable.SwitchButton_kswThumbWidth, thumbWidth);
137 | thumbHeight = ta.getDimension(R.styleable.SwitchButton_kswThumbHeight, thumbHeight);
138 | thumbRadius = ta.getDimension(R.styleable.SwitchButton_kswThumbRadius, Math.min(thumbWidth, thumbHeight) / 2.f);
139 | backRadius = ta.getDimension(R.styleable.SwitchButton_kswBackRadius, thumbRadius + density * 2f);
140 | backDrawable = ta.getDrawable(R.styleable.SwitchButton_kswBackDrawable);
141 | backColor = ta.getColorStateList(R.styleable.SwitchButton_kswBackColor);
142 | backMeasureRatio = ta.getFloat(R.styleable.SwitchButton_kswBackMeasureRatio, backMeasureRatio);
143 | animationDuration = ta.getInteger(R.styleable.SwitchButton_kswAnimationDuration, animationDuration);
144 | fadeBack = ta.getBoolean(R.styleable.SwitchButton_kswFadeBack, true);
145 | tintColor = ta.getColor(R.styleable.SwitchButton_kswTintColor, tintColor);
146 | ta.recycle();
147 | }
148 |
149 | // thumb drawable and color
150 | mThumbDrawable = thumbDrawable;
151 | mThumbColor = thumbColor;
152 | mIsThumbUseDrawable = mThumbDrawable != null;
153 | mTintColor = tintColor;
154 | if (mTintColor == Integer.MIN_VALUE) {
155 | mTintColor = DEFAULT_TINT_COLOR;
156 | }
157 | if (!mIsThumbUseDrawable && mThumbColor == null) {
158 | mThumbColor = ColorUtils.generateThumbColorWithTintColor(mTintColor);
159 | mCurrThumbColor = mThumbColor.getDefaultColor();
160 | }
161 | mThumbSizeF.set(thumbWidth, thumbHeight);
162 |
163 | // back drawable and color
164 | mBackDrawable = backDrawable;
165 | mBackColor = backColor;
166 | mIsBackUseDrawable = mBackDrawable != null;
167 | if (!mIsBackUseDrawable && mBackColor == null) {
168 | mBackColor = ColorUtils.generateBackColorWithTintColor(mTintColor);
169 | mCurrBackColor = mBackColor.getDefaultColor();
170 | mNextBackColor = mBackColor.getColorForState(CHECKED_PRESSED_STATE, mCurrBackColor);
171 | }
172 |
173 | // margin
174 | mThumbMargin.set(marginLeft, marginTop, marginRight, marginBottom);
175 |
176 | // size & measure params must larger than 1
177 | mBackMeasureRatio = mThumbMargin.width() >= 0 ? Math.max(backMeasureRatio, 1) : backMeasureRatio;
178 |
179 | mThumbRadius = thumbRadius;
180 | mBackRadius = backRadius;
181 | mAnimationDuration = animationDuration;
182 | mFadeBack = fadeBack;
183 |
184 | mProcessAnimator.setDuration(mAnimationDuration);
185 |
186 | setFocusable(true);
187 | setClickable(true);
188 |
189 | // sync checked status
190 | if (isChecked()) {
191 | setProcess(1);
192 | }
193 | }
194 |
195 | @Override
196 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
197 | setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
198 | }
199 |
200 | private int measureWidth(int widthMeasureSpec) {
201 | int widthSize = MeasureSpec.getSize(widthMeasureSpec);
202 | int widthMode = MeasureSpec.getMode(widthMeasureSpec);
203 | int measuredWidth;
204 |
205 | int minWidth = (int) (mThumbSizeF.x * mBackMeasureRatio);
206 | if (mIsBackUseDrawable) {
207 | minWidth = Math.max(minWidth, mBackDrawable.getMinimumWidth());
208 | }
209 | minWidth = Math.max(minWidth, (int) (minWidth + mThumbMargin.left + mThumbMargin.right));
210 | minWidth = Math.max(minWidth, minWidth + getPaddingLeft() + getPaddingRight());
211 | minWidth = Math.max(minWidth, getSuggestedMinimumWidth());
212 |
213 | if (widthMode == MeasureSpec.EXACTLY) {
214 | measuredWidth = Math.max(minWidth, widthSize);
215 | } else {
216 | measuredWidth = minWidth;
217 | if (widthMode == MeasureSpec.AT_MOST) {
218 | measuredWidth = Math.min(measuredWidth, widthSize);
219 | }
220 | }
221 |
222 | return measuredWidth;
223 | }
224 |
225 | private int measureHeight(int heightMeasureSpec) {
226 | int heightMode = MeasureSpec.getMode(heightMeasureSpec);
227 | int heightSize = MeasureSpec.getSize(heightMeasureSpec);
228 | int measuredHeight;
229 |
230 | int minHeight = (int) Math.max(mThumbSizeF.y, mThumbSizeF.y + mThumbMargin.top + mThumbMargin.right);
231 | minHeight = Math.max(minHeight, getSuggestedMinimumHeight());
232 | minHeight = Math.max(minHeight, minHeight + getPaddingTop() + getPaddingBottom());
233 |
234 | if (heightMode == MeasureSpec.EXACTLY) {
235 | measuredHeight = Math.max(minHeight, heightSize);
236 | } else {
237 | measuredHeight = minHeight;
238 | if (heightMode == MeasureSpec.AT_MOST) {
239 | measuredHeight = Math.min(measuredHeight, heightSize);
240 | }
241 | }
242 |
243 | return measuredHeight;
244 | }
245 |
246 | @Override
247 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
248 | super.onSizeChanged(w, h, oldw, oldh);
249 | if (w != oldw || h != oldh) {
250 | setup();
251 | }
252 | }
253 |
254 | /**
255 | * set up the rect of back and thumb
256 | */
257 | private void setup() {
258 | float thumbTop = getPaddingTop() + Math.max(0, mThumbMargin.top);
259 | float thumbLeft = getPaddingLeft() + Math.max(0, mThumbMargin.left);
260 |
261 | if (mIsThumbUseDrawable) {
262 | mThumbSizeF.x = Math.max(mThumbSizeF.x, mThumbDrawable.getMinimumWidth());
263 | mThumbSizeF.y = Math.max(mThumbSizeF.y, mThumbDrawable.getMinimumHeight());
264 | }
265 |
266 | mThumbRectF.set(thumbLeft, thumbTop, thumbLeft + mThumbSizeF.x, thumbTop + mThumbSizeF.y);
267 |
268 | float backLeft = mThumbRectF.left - mThumbMargin.left;
269 | mBackRectF.set(backLeft, mThumbRectF.top - mThumbMargin.top, backLeft + mThumbMargin.left + mThumbSizeF.x * mBackMeasureRatio + mThumbMargin.right, mThumbRectF.bottom + mThumbMargin.bottom);
270 |
271 | mSafeRectF.set(mThumbRectF.left, 0, mBackRectF.right - mThumbMargin.right - mThumbRectF.width(), 0);
272 |
273 | float minBackRadius = Math.min(mBackRectF.width(), mBackRectF.height()) / 2.f;
274 | mBackRadius = Math.min(minBackRadius, mBackRadius);
275 |
276 | if (mBackDrawable != null) {
277 | mBackDrawable.setBounds((int) mBackRectF.left, (int) mBackRectF.top, (int) mBackRectF.right, (int) mBackRectF.bottom);
278 | }
279 | }
280 |
281 | @Override
282 | protected void onDraw(Canvas canvas) {
283 | super.onDraw(canvas);
284 |
285 | // fade back
286 | if (mIsBackUseDrawable) {
287 | if (mFadeBack && mCurrentBackDrawable != null && mNextBackDrawable != null) {
288 | int alpha = (int) (255 * (isChecked() ? getProcess() : (1 - getProcess())));
289 | mCurrentBackDrawable.setAlpha(alpha);
290 | mCurrentBackDrawable.draw(canvas);
291 | alpha = 255 - alpha;
292 | mNextBackDrawable.setAlpha(alpha);
293 | mNextBackDrawable.draw(canvas);
294 | } else {
295 | mBackDrawable.setAlpha(255);
296 | mBackDrawable.draw(canvas);
297 | }
298 | } else {
299 | if (mFadeBack) {
300 | int alpha;
301 | int colorAlpha;
302 |
303 | // curr back
304 | alpha = (int) (255 * (isChecked() ? getProcess() : (1 - getProcess())));
305 | colorAlpha = Color.alpha(mCurrBackColor);
306 | colorAlpha = colorAlpha * alpha / 255;
307 | mPaint.setARGB(colorAlpha, Color.red(mCurrBackColor), Color.green(mCurrBackColor), Color.blue(mCurrBackColor));
308 | canvas.drawRoundRect(mBackRectF, mBackRadius, mBackRadius, mPaint);
309 |
310 | // next back
311 | alpha = 255 - alpha;
312 | colorAlpha = Color.alpha(mNextBackColor);
313 | colorAlpha = colorAlpha * alpha / 255;
314 | mPaint.setARGB(colorAlpha, Color.red(mNextBackColor), Color.green(mNextBackColor), Color.blue(mNextBackColor));
315 | canvas.drawRoundRect(mBackRectF, mBackRadius, mBackRadius, mPaint);
316 |
317 | mPaint.setAlpha(255);
318 | } else {
319 | mPaint.setColor(mCurrBackColor);
320 | canvas.drawRoundRect(mBackRectF, mBackRadius, mBackRadius, mPaint);
321 | }
322 | }
323 |
324 | // thumb
325 | mPresentThumbRectF.set(mThumbRectF);
326 | mPresentThumbRectF.offset(mProcess * mSafeRectF.width(), 0);
327 | if (mIsThumbUseDrawable) {
328 | mThumbDrawable.setBounds((int) mPresentThumbRectF.left, (int) mPresentThumbRectF.top, (int) mPresentThumbRectF.right, (int) mPresentThumbRectF.bottom);
329 | mThumbDrawable.draw(canvas);
330 | } else {
331 | mPaint.setColor(mCurrThumbColor);
332 | canvas.drawRoundRect(mPresentThumbRectF, mThumbRadius, mThumbRadius, mPaint);
333 | }
334 |
335 | if (mDrawDebugRect) {
336 | mRectPaint.setColor(Color.parseColor("#AA0000"));
337 | canvas.drawRect(mBackRectF, mRectPaint);
338 | mRectPaint.setColor(Color.parseColor("#0000FF"));
339 | canvas.drawRect(mPresentThumbRectF, mRectPaint);
340 | }
341 | }
342 |
343 | @Override
344 | protected void drawableStateChanged() {
345 | super.drawableStateChanged();
346 |
347 | if (!mIsThumbUseDrawable && mThumbColor != null) {
348 | mCurrThumbColor = mThumbColor.getColorForState(getDrawableState(), mCurrThumbColor);
349 | } else {
350 | setDrawableState(mThumbDrawable);
351 | }
352 |
353 | int[] nextState = isChecked() ? UNCHECKED_PRESSED_STATE : CHECKED_PRESSED_STATE;
354 | if (!mIsBackUseDrawable && mBackColor != null) {
355 | mCurrBackColor = mBackColor.getColorForState(getDrawableState(), mCurrBackColor);
356 | mNextBackColor = mBackColor.getColorForState(nextState, mCurrBackColor);
357 | } else {
358 | if (mBackDrawable instanceof StateListDrawable && mFadeBack) {
359 | mBackDrawable.setState(nextState);
360 | mNextBackDrawable = mBackDrawable.getCurrent().mutate();
361 | } else {
362 | mNextBackDrawable = null;
363 | }
364 | setDrawableState(mBackDrawable);
365 | if (mBackDrawable != null) {
366 | mCurrentBackDrawable = mBackDrawable.getCurrent().mutate();
367 | }
368 | }
369 | }
370 |
371 | @Override
372 | public boolean onTouchEvent(MotionEvent event) {
373 |
374 | if (!isEnabled()) {
375 | return false;
376 | }
377 |
378 | int action = event.getAction();
379 |
380 | float deltaX = event.getX() - mStartX;
381 | float deltaY = event.getY() - mStartY;
382 |
383 | // status the view going to change to when finger released
384 | boolean nextStatus;
385 |
386 | switch (action) {
387 | case MotionEvent.ACTION_DOWN:
388 | catchView();
389 | mStartX = event.getX();
390 | mStartY = event.getY();
391 | mLastX = mStartX;
392 | setPressed(true);
393 | break;
394 |
395 | case MotionEvent.ACTION_MOVE:
396 | float x = event.getX();
397 | setProcess(getProcess() + (x - mLastX) / mSafeRectF.width());
398 | mLastX = x;
399 | break;
400 |
401 | case MotionEvent.ACTION_CANCEL:
402 | case MotionEvent.ACTION_UP:
403 | setPressed(false);
404 | nextStatus = getStatusBasedOnPos();
405 | float time = event.getEventTime() - event.getDownTime();
406 | if (deltaX < mTouchSlop && deltaY < mTouchSlop && time < mClickTimeout) {
407 | performClick();
408 | } else {
409 | if (nextStatus != isChecked()) {
410 | playSoundEffect(SoundEffectConstants.CLICK);
411 | setChecked(nextStatus);
412 | } else {
413 | animateToState(nextStatus);
414 | }
415 | }
416 | break;
417 |
418 | default:
419 | break;
420 | }
421 | return super.onTouchEvent(event);
422 | }
423 |
424 |
425 | /**
426 | * return the status based on position of thumb
427 | *
428 | * @return
429 | */
430 | private boolean getStatusBasedOnPos() {
431 | return getProcess() > 0.5f;
432 | }
433 |
434 | public final float getProcess() {
435 | return mProcess;
436 | }
437 |
438 | public final void setProcess(final float process) {
439 | float tp = process;
440 | if (tp > 1) {
441 | tp = 1;
442 | } else if (tp < 0) {
443 | tp = 0;
444 | }
445 | this.mProcess = tp;
446 | invalidate();
447 | }
448 |
449 | @Override
450 | public boolean performClick() {
451 | return super.performClick();
452 | }
453 |
454 | /**
455 | * processing animation
456 | *
457 | * @param checked checked or unChecked
458 | */
459 | protected void animateToState(boolean checked) {
460 | if (mProcessAnimator == null) {
461 | return;
462 | }
463 | if (mProcessAnimator.isRunning()) {
464 | mProcessAnimator.cancel();
465 | }
466 | mProcessAnimator.setDuration(mAnimationDuration);
467 | if (checked) {
468 | mProcessAnimator.setFloatValues(mProcess, 1f);
469 | } else {
470 | mProcessAnimator.setFloatValues(mProcess, 0);
471 | }
472 | mProcessAnimator.start();
473 | }
474 |
475 | private void catchView() {
476 | ViewParent parent = getParent();
477 | if (parent != null) {
478 | parent.requestDisallowInterceptTouchEvent(true);
479 | }
480 | }
481 |
482 | @Override
483 | public void setChecked(final boolean checked) {
484 | super.setChecked(checked);
485 | animateToState(checked);
486 | }
487 |
488 | public void setCheckedImmediately(boolean checked) {
489 | super.setChecked(checked);
490 | if (mProcessAnimator != null && mProcessAnimator.isRunning()) {
491 | mProcessAnimator.cancel();
492 | }
493 | setProcess(checked ? 1 : 0);
494 | invalidate();
495 | }
496 |
497 | public void toggleImmediately() {
498 | setCheckedImmediately(!isChecked());
499 | }
500 |
501 | private void setDrawableState(Drawable drawable) {
502 | if (drawable != null) {
503 | int[] myDrawableState = getDrawableState();
504 | drawable.setState(myDrawableState);
505 | invalidate();
506 | }
507 | }
508 |
509 | public boolean isDrawDebugRect() {
510 | return mDrawDebugRect;
511 | }
512 |
513 | public void setDrawDebugRect(boolean drawDebugRect) {
514 | mDrawDebugRect = drawDebugRect;
515 | invalidate();
516 | }
517 |
518 | public long getAnimationDuration() {
519 | return mAnimationDuration;
520 | }
521 |
522 | public void setAnimationDuration(long animationDuration) {
523 | mAnimationDuration = animationDuration;
524 | }
525 |
526 | public Drawable getThumbDrawable() {
527 | return mThumbDrawable;
528 | }
529 |
530 | public void setThumbDrawable(Drawable thumbDrawable) {
531 | mThumbDrawable = thumbDrawable;
532 | mIsThumbUseDrawable = mThumbDrawable != null;
533 | setup();
534 | refreshDrawableState();
535 | requestLayout();
536 | invalidate();
537 | }
538 |
539 | public void setThumbDrawableRes(int thumbDrawableRes) {
540 | setThumbDrawable(ContextCompat.getDrawable(getContext(), thumbDrawableRes));
541 | }
542 |
543 | public Drawable getBackDrawable() {
544 | return mBackDrawable;
545 | }
546 |
547 | public void setBackDrawable(Drawable backDrawable) {
548 | mBackDrawable = backDrawable;
549 | mIsBackUseDrawable = mBackDrawable != null;
550 | setup();
551 | refreshDrawableState();
552 | requestLayout();
553 | invalidate();
554 | }
555 |
556 | public void setBackDrawableRes(int backDrawableRes) {
557 | setBackDrawable(ContextCompat.getDrawable(getContext(), backDrawableRes));
558 | }
559 |
560 | public ColorStateList getBackColor() {
561 | return mBackColor;
562 | }
563 |
564 | public void setBackColor(ColorStateList backColor) {
565 | mBackColor = backColor;
566 | if (mBackColor != null) {
567 | setBackDrawable(null);
568 | }
569 | invalidate();
570 | }
571 |
572 | public void setBackColorRes(int backColorRes) {
573 | setBackColor(ContextCompat.getColorStateList(getContext(), backColorRes));
574 | }
575 |
576 | public ColorStateList getThumbColor() {
577 | return mThumbColor;
578 | }
579 |
580 | public void setThumbColor(ColorStateList thumbColor) {
581 | mThumbColor = thumbColor;
582 | if (mThumbColor != null) {
583 | setThumbDrawable(null);
584 | }
585 | }
586 |
587 | public void setThumbColorRes(int thumbColorRes) {
588 | setThumbColor(ContextCompat.getColorStateList(getContext(), thumbColorRes));
589 | }
590 |
591 | public float getBackMeasureRatio() {
592 | return mBackMeasureRatio;
593 | }
594 |
595 | public void setBackMeasureRatio(float backMeasureRatio) {
596 | mBackMeasureRatio = backMeasureRatio;
597 | requestLayout();
598 | }
599 |
600 | public RectF getThumbMargin() {
601 | return mThumbMargin;
602 | }
603 |
604 | public void setThumbMargin(RectF thumbMargin) {
605 | if (thumbMargin == null) {
606 | setThumbMargin(0, 0, 0, 0);
607 | } else {
608 | setThumbMargin(thumbMargin.left, thumbMargin.top, thumbMargin.right, thumbMargin.bottom);
609 | }
610 | }
611 |
612 | public void setThumbMargin(float left, float top, float right, float bottom) {
613 | mThumbMargin.set(left, top, right, bottom);
614 | requestLayout();
615 | }
616 |
617 | public void setThumbSize(float width, float height) {
618 | mThumbSizeF.set(width, height);
619 | setup();
620 | requestLayout();
621 | }
622 |
623 | public float getThumbWidth() {
624 | return mThumbSizeF.x;
625 | }
626 |
627 | public float getThumbHeight() {
628 | return mThumbSizeF.y;
629 | }
630 |
631 | public void setThumbSize(PointF size) {
632 | if (size == null) {
633 | float defaultSize = getResources().getDisplayMetrics().density * DEFAULT_THUMB_SIZE_DP;
634 | setThumbSize(defaultSize, defaultSize);
635 | } else {
636 | setThumbSize(size.x, size.y);
637 | }
638 | }
639 |
640 | public PointF getThumbSizeF() {
641 | return mThumbSizeF;
642 | }
643 |
644 | public float getThumbRadius() {
645 | return mThumbRadius;
646 | }
647 |
648 | public void setThumbRadius(float thumbRadius) {
649 | mThumbRadius = thumbRadius;
650 | if (!mIsThumbUseDrawable) {
651 | invalidate();
652 | }
653 | }
654 |
655 | public PointF getBackSizeF() {
656 | return new PointF(mBackRectF.width(), mBackRectF.height());
657 | }
658 |
659 | public float getBackRadius() {
660 | return mBackRadius;
661 | }
662 |
663 | public void setBackRadius(float backRadius) {
664 | mBackRadius = backRadius;
665 | if (!mIsBackUseDrawable) {
666 | invalidate();
667 | }
668 | }
669 |
670 | public boolean isFadeBack() {
671 | return mFadeBack;
672 | }
673 |
674 | public void setFadeBack(boolean fadeBack) {
675 | mFadeBack = fadeBack;
676 | }
677 |
678 | public int getTintColor() {
679 | return mTintColor;
680 | }
681 |
682 | public void setTintColor(int tintColor) {
683 | mTintColor = tintColor;
684 | mThumbColor = ColorUtils.generateThumbColorWithTintColor(mTintColor);
685 | mBackColor = ColorUtils.generateBackColorWithTintColor(mTintColor);
686 | mIsBackUseDrawable = false;
687 | mIsThumbUseDrawable = false;
688 | // call this method to refresh color states
689 | refreshDrawableState();
690 | invalidate();
691 | }
692 |
693 |
694 |
695 | }
--------------------------------------------------------------------------------