├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── addisonelliott │ │ └── segmentedbutton │ │ ├── ButtonActor.java │ │ ├── EmptyView.java │ │ ├── SegmentedButton.java │ │ └── SegmentedButtonGroup.java │ └── res │ └── values │ └── attrs.xml ├── sample ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── addisonelliott │ │ └── segmentedbutton │ │ └── sample │ │ ├── MainActivity.java │ │ └── drawable │ │ └── BadgeDrawable.java │ └── res │ ├── drawable-hdpi │ ├── ic_aragorn.png │ ├── ic_b1.png │ ├── ic_b11.png │ ├── ic_b12.png │ ├── ic_b13.png │ ├── ic_b17.png │ ├── ic_b2.png │ ├── ic_b3.png │ ├── ic_b4.png │ ├── ic_b5.png │ ├── ic_b6.png │ ├── ic_b7.png │ ├── ic_b8.png │ ├── ic_b9.png │ ├── ic_gimli.png │ └── ic_legolas.png │ ├── drawable-mdpi │ ├── ic_aragorn.png │ ├── ic_b1.png │ ├── ic_b11.png │ ├── ic_b12.png │ ├── ic_b13.png │ ├── ic_b17.png │ ├── ic_b2.png │ ├── ic_b3.png │ ├── ic_b4.png │ ├── ic_b5.png │ ├── ic_b6.png │ ├── ic_b7.png │ ├── ic_b8.png │ ├── ic_b9.png │ ├── ic_gimli.png │ └── ic_legolas.png │ ├── drawable-xhdpi │ ├── ic_aragorn.png │ ├── ic_b1.png │ ├── ic_b11.png │ ├── ic_b12.png │ ├── ic_b13.png │ ├── ic_b17.png │ ├── ic_b2.png │ ├── ic_b3.png │ ├── ic_b4.png │ ├── ic_b5.png │ ├── ic_b6.png │ ├── ic_b7.png │ ├── ic_b8.png │ ├── ic_b9.png │ ├── ic_gimli.png │ └── ic_legolas.png │ ├── drawable-xxhdpi │ ├── ic_aragorn.png │ ├── ic_b1.png │ ├── ic_b11.png │ ├── ic_b12.png │ ├── ic_b13.png │ ├── ic_b17.png │ ├── ic_b2.png │ ├── ic_b3.png │ ├── ic_b4.png │ ├── ic_b5.png │ ├── ic_b6.png │ ├── ic_b7.png │ ├── ic_b8.png │ ├── ic_b9.png │ ├── ic_gimli.png │ └── ic_legolas.png │ ├── drawable-xxxhdpi │ ├── ic_aragorn.png │ ├── ic_b1.png │ ├── ic_b11.png │ ├── ic_b12.png │ ├── ic_b13.png │ ├── ic_b17.png │ ├── ic_b2.png │ ├── ic_b3.png │ ├── ic_b4.png │ ├── ic_b5.png │ ├── ic_b6.png │ ├── ic_b7.png │ ├── ic_b8.png │ ├── ic_b9.png │ ├── ic_gimli.png │ └── ic_legolas.png │ ├── drawable │ ├── gradient_drawable.xml │ ├── gradient_drawable_divider.xml │ ├── gradient_drawable_selector.xml │ ├── ic_chart_bar.xml │ ├── ic_chart_donut.xml │ └── ic_chart_pie.xml │ ├── font │ ├── aniron.ttf │ └── shaka_pow.ttf │ ├── layout │ └── activity_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/androidstudio 2 | # Edit at https://www.gitignore.io/?templates=androidstudio 3 | 4 | ### AndroidStudio ### 5 | # Covers files to be ignored for android development using Android Studio. 6 | 7 | # Built application files 8 | *.apk 9 | *.ap_ 10 | 11 | # Files for the ART/Dalvik VM 12 | *.dex 13 | 14 | # Java class files 15 | *.class 16 | 17 | # Generated files 18 | bin/ 19 | gen/ 20 | out/ 21 | 22 | # Gradle files 23 | .gradle 24 | .gradle/ 25 | build/ 26 | 27 | # Signing files 28 | .signing/ 29 | 30 | # Local configuration file (sdk path, etc) 31 | local.properties 32 | 33 | # Proguard folder generated by Eclipse 34 | proguard/ 35 | 36 | # Log Files 37 | *.log 38 | 39 | # Android Studio 40 | /*/build/ 41 | /*/local.properties 42 | /*/out 43 | /*/*/build 44 | /*/*/production 45 | captures/ 46 | .navigation/ 47 | *.ipr 48 | *~ 49 | *.swp 50 | 51 | # Android Patch 52 | gen-external-apklibs 53 | 54 | # External native build folder generated in Android Studio 2.2 and later 55 | .externalNativeBuild 56 | 57 | # NDK 58 | obj/ 59 | 60 | # IntelliJ IDEA 61 | *.iml 62 | *.iws 63 | /out/ 64 | 65 | # User-specific configurations 66 | .idea 67 | 68 | # OS-specific files 69 | .DS_Store 70 | .DS_Store? 71 | ._* 72 | .Spotlight-V100 73 | .Trashes 74 | ehthumbs.db 75 | Thumbs.db 76 | 77 | # Legacy Eclipse project files 78 | .classpath 79 | .project 80 | .cproject 81 | .settings/ 82 | 83 | # Mobile Tools for Java (J2ME) 84 | .mtj.tmp/ 85 | 86 | # Package Files # 87 | *.war 88 | *.ear 89 | 90 | # virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml) 91 | hs_err_pid* 92 | 93 | ## Plugin-specific files: 94 | 95 | # mpeltonen/sbt-idea plugin 96 | .idea_modules/ 97 | 98 | # JIRA plugin 99 | atlassian-ide-plugin.xml 100 | 101 | # Mongo Explorer plugin 102 | .idea/mongoSettings.xml 103 | 104 | # Crashlytics plugin (for Android Studio and IntelliJ) 105 | com_crashlytics_export_strings.xml 106 | crashlytics.properties 107 | crashlytics-build.properties 108 | fabric.properties 109 | 110 | ### AndroidStudio Patch ### 111 | 112 | !/gradle/wrapper/gradle-wrapper.jar 113 | 114 | # End of https://www.gitignore.io/api/androidstudio -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-SegmentedButton-green.svg?style=true)](https://android-arsenal.com/details/1/4445) [![](https://jitpack.io/v/addisonelliott/segmentedbutton.svg)](https://jitpack.io/#addisonelliott/segmentedbutton) 2 | 3 | # SegmentedButton 4 | 5 | Android view that mimics iOS's [SegmentedControl](https://developer.apple.com/design/human-interface-guidelines/ios/controls/segmented-controls/) 6 | 7 | ## Features 8 | * Customizable text color, size and font 9 | * Custom button drawables 10 | * Customizable button dividers 11 | * Solid and dashed border support 12 | * Ripple effect on button tap 13 | * Draggable buttons 14 | * Animations 15 | * Support for API 16+ 16 | 17 | ## Old Library 18 | 19 | This project is originally forked from [ceryle/SegmentedButton](https://github.com/ceryle/SegmentedButton) but has been revamped and given some TLC. The parent repository has been stagnant since **October 17th, 2017**. 20 | 21 | ## Preview 22 | 23 | [![1](https://www.addisonelliott.net/SegmentedButtonImages/Gradient.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L26) 24 | [![2](https://www.addisonelliott.net/SegmentedButtonImages/LordOfTheRings.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L91) 25 | [![3](https://www.addisonelliott.net/SegmentedButtonImages/DCSuperheros.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L147) 26 | [![4](https://www.addisonelliott.net/SegmentedButtonImages/MarvelSuperheros.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L216) 27 | [![5](https://www.addisonelliott.net/SegmentedButtonImages/Guys.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L253) 28 | [![6](https://www.addisonelliott.net/SegmentedButtonImages/StarWars.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L285) 29 | [![7](https://www.addisonelliott.net/SegmentedButtonImages/DarthVader.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L334) 30 | [![8](https://www.addisonelliott.net/SegmentedButtonImages/YesNoMaybe.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L399) 31 | [![9](https://www.addisonelliott.net/SegmentedButtonImages/YesNoMaybeRound.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L583) 32 | [![10](https://www.addisonelliott.net/SegmentedButtonImages/LeftRight.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L459) 33 | [![11](https://www.addisonelliott.net/SegmentedButtonImages/PickupDropoff.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L498) 34 | [![12](https://www.addisonelliott.net/SegmentedButtonImages/RoundedTransparentButtons.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L634) 35 | [![12](https://www.addisonelliott.net/SegmentedButtonImages/SportsEquipment.gif)](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml#L690) 36 | 37 | Code for all images can be found in the [sample project](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml) 38 | 39 | ## Installation 40 | 41 | #### Gradle 42 | 43 | Add it to your build.gradle with: 44 | ```gradle 45 | allprojects { 46 | repositories { 47 | maven { url "https://jitpack.io" } 48 | } 49 | } 50 | ``` 51 | and: 52 | 53 | ```gradle 54 | dependencies { 55 | implementation 'com.github.addisonelliott:SegmentedButton:$LATEST_VERSION' 56 | } 57 | ``` 58 | 59 | **Note:** The `$LATEST_VERSION` string should be replaced with the latest version. The available versions can be found 60 | here: https://jitpack.io/#addisonElliott/SegmentedButton 61 | 62 | **Note:** This library uses the AndroidX packages rather than the older Android support libraries. Periodic releases 63 | with the Android support library will be released based on user demand with the version appended with `-support` (e.g. 64 | `3.1.2-support` for `$LATEST_VERSION`). It is strongly recommended to upgrade your project to AndroidX to obtain the 65 | latest features & bug fixes. 66 | 67 | **Note:** Java 8 is required to use this library. This can be done by adding the following code to `build.gradle` while 68 | using the Android plugin with a version of `3.0.0` or higher. 69 | 70 | ```gradle 71 | android { 72 | compileOptions { 73 | sourceCompatibility '1.8' 74 | targetCompatibility '1.8' 75 | } 76 | } 77 | ``` 78 | 79 | ## Usage 80 | 81 | ### Layout XML 82 | ```xml 83 | 101 | 102 | 113 | 114 | 125 | 126 | 137 | 138 | ``` 139 | 140 | ### Java 141 | ```java 142 | segmentedButtonGroup.setOnPositionChangedListener(new OnPositionChangedListener() { 143 | @Override 144 | public void onPositionChanged(final int position) { 145 | // Handle stuff here 146 | } 147 | }); 148 | 149 | // Get current position 150 | segmentedButtonGroup.getPosition(); 151 | ``` 152 | 153 | Check out the [sample project](https://github.com/addisonElliott/SegmentedButton/blob/master/sample/src/main/res/layout/activity_main.xml) for additional examples 154 | 155 | ## Attributes 156 | 157 | ### SegmentedButtonGroup 158 | 159 | | Attribute | Format | Description | 160 | | ---------------------------------- | ----------------- | -------------------------------------------------------------------------- | 161 | | android:background | `drawable\|color` | Set background for every button when unselected (default: transparent) | 162 | | app:selectedBackground | `drawable\|color` | Set background for every button when selected (default: transparent) | 163 | | app:borderWidth | `dimension` | Width of border around button group | 164 | | app:borderColor | `color` | Color of border | 165 | | app:borderDashWidth | `dimension` | Width of dashes, 0 indicates solid line | 166 | | app:borderDashGap | `dimension` | Width of gaps in dashes | 167 | | app:selectedBorderWidth | `dimension` | Width of border around selected button in group | 168 | | app:selectedBorderColor | `color` | Color of border for selected button in group | 169 | | app:selectedBorderDashWidth | `dimension` | Width of dashes for selected button in group, 0 indicates solid line | 170 | | app:selectedBorderDashGap | `dimension` | Width of gaps in dashes for selected button in group | 171 | | app:radius | `dimension` | Radius of corners for button group | 172 | | app:selectedButtonRadius | `dimension` | Radius of corners for selected button in group | 173 | | app:position | `integer` | Default button that is selected | 174 | | app:draggable | `boolean` | Whether or not buttons can be dragged to change selected state | 175 | | app:ripple | `boolean` | Whether or not ripple effect is enabled for all buttons | 176 | | app:rippleColor | `color` | Ripple effect tint color for each button | 177 | | app:divider | `drawable\|color` | Drawable or color to display for divider between buttons | 178 | | app:dividerWidth | `dimension` | Width of the divider between buttons, 0 indicates no dividers | 179 | | app:dividerRadius | `dimension` | Corner radius for divider to round edges | 180 | | app:dividerPadding | `dimension` | Divider padding on top and bottom of divider | 181 | | app:selectionAnimationDuration | `integer` | Duration in ms for change button selection animation | 182 | | app:selectionAnimationInterpolator | `enum` | Type of animation used for changing button. Valid options are listed below | 183 | 184 | ### SegmentedButton 185 | 186 | | Option Name | Format | Description | 187 | | ------------------------------- | ----------------- | ---------------------------------------------------------------------------- | 188 | | android:background | `drawable\|color` | Set background for button when unselected (default: transparent) | 189 | | app:selectedBackground | `drawable\|color` | Set background for button when selected (default: transparent) | 190 | | app:rounded | `boolean` | Whether or not the button is rounded.
**Note:** This is used to round **BOTH** sides of a button. The typical use case is for rounded buttons with a transparent background. | 191 | | app:rippleColor | `color` | Ripple effect tint color when user taps on button | 192 | | app:drawable | `drawable` | Drawable to display | 193 | | app:drawablePadding | `dimension` | Padding between drawable and text | 194 | | app:drawableTint | `color` | Tint color for drawable when unselected | 195 | | app:selectedDrawableTint | `color` | Tint color for drawable when selected | 196 | | app:drawableWidth | `dimension` | Width of drawable (default uses intrinsic) | 197 | | app:drawableHeight | `dimension` | Height of drawable (default uses intrinsic) | 198 | | app:drawableGravity | `enum` | Determines where drawable should be placed in relation to the text. Valid options are `Gravity.LEFT`, `Gravity.TOP`, `Gravity.RIGHT`, and `Gravity.BOTTOM` | 199 | | app:text | `string` | Text to display on button | 200 | | app:textColor | `color` | Color of text when button is unselected | 201 | | app:selectedTextColor | `color` | Color of text when button is selected | 202 | | app:textSize | `dimension` | Font size of text | 203 | | android:fontFamily | `font` | Font for displaying text | 204 | | app:textStyle | `flag` | Text style, can be `Typeface.NORMAL`, `Typeface.BOLD`, and `Typeface.ITALIC` | 205 | | app:selectedTextStyle | `flag` | Selected text style, can be `Typeface.NORMAL`, `Typeface.BOLD`, and `Typeface.ITALIC` 206 | | app:linesCount | `int` | Maximum lines count, multiline by default, works with not-none ellipsize type| 207 | | android:ellipsize | `enum` | Ellipsize type, can be `none`, `start`, `middle`, `end`, `marquee`, none by default 208 | 209 | **All layout attributes have a corresponding function in Java that can be called to change programatically. See Javadocs of source code for more information.** 210 | 211 | ### Available Animations 212 | 213 | - fastOutSlowIn 214 | - bounce 215 | - linear 216 | - decelerate 217 | - cycle 218 | - anticipate 219 | - accelerateDecelerate 220 | - accelerate 221 | - anticipateOvershoot 222 | - fastOutLinearIn 223 | - linearOutSlowIn 224 | - overshoot 225 | 226 | These animations can be set using the attribute noted above like so: `app:selectionAnimationInterpolator="bounce"`. 227 | 228 | ## Support 229 | 230 | Issues and pull requests are encouraged. 231 | 232 | ## License 233 | 234 | This project is licensed under the Apache License Version 2.0 - see the [LICENSE](LICENSE) file for details 235 | 236 | ``` 237 | Copyright (C) 2016 ceryle 238 | Copyright (C) 2019 Addison Elliott 239 | 240 | Licensed under the Apache License, Version 2.0 (the "License"); 241 | you may not use this file except in compliance with the License. 242 | You may obtain a copy of the License at 243 | 244 | http://www.apache.org/licenses/LICENSE-2.0 245 | 246 | Unless required by applicable law or agreed to in writing, software 247 | distributed under the License is distributed on an "AS IS" BASIS, 248 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 249 | See the License for the specific language governing permissions and 250 | limitations under the License. 251 | ``` 252 | 253 | -------------------------------------------------------------------------------- /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 | google() 7 | } 8 | 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.5.2' 11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' 12 | 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | jcenter() 19 | google() 20 | maven { 21 | url "https://jitpack.io" 22 | } 23 | } 24 | } 25 | 26 | ext { 27 | minSdkVersion = 16 28 | compileSdkVersion = 28 29 | buildToolsVersion = '28.0.3' 30 | } 31 | 32 | task clean(type: Delete) { 33 | delete rootProject.buildDir 34 | } 35 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | android.enableJetifier=true 20 | android.useAndroidX=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Sep 14 09:50:46 CDT 2019 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-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /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 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | 4 | group='com.github.addisonelliott' 5 | 6 | android { 7 | compileSdkVersion rootProject.compileSdkVersion 8 | buildToolsVersion rootProject.buildToolsVersion 9 | 10 | defaultConfig { 11 | minSdkVersion rootProject.minSdkVersion 12 | targetSdkVersion rootProject.compileSdkVersion 13 | versionCode 12 14 | versionName "3.1.9" 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | 24 | // Configure only for each module that uses Java 8 language features (either in its source code or through 25 | // dependencies). 26 | compileOptions { 27 | sourceCompatibility '1.8' 28 | targetCompatibility '1.8' 29 | } 30 | } 31 | 32 | // build a jar with source files 33 | task sourcesJar(type: Jar) { 34 | from android.sourceSets.main.java.srcDirs 35 | classifier = 'sources' 36 | } 37 | 38 | task javadoc(type: Javadoc) { 39 | failOnError false 40 | source = android.sourceSets.main.java.srcDirs 41 | configurations.implementation.setCanBeResolved(true) 42 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + configurations.implementation 43 | } 44 | 45 | task javadocJar(type: Jar, dependsOn: javadoc) { 46 | classifier = 'javadoc' 47 | from javadoc.destinationDir 48 | } 49 | 50 | artifacts { 51 | archives sourcesJar 52 | archives javadocJar 53 | } 54 | 55 | dependencies { 56 | implementation fileTree(dir: 'libs', include: ['*.jar']) 57 | testImplementation 'junit:junit:4.13-beta-3' 58 | 59 | implementation "androidx.appcompat:appcompat:1.0.2" 60 | implementation "androidx.interpolator:interpolator:1.0.0" 61 | implementation "androidx.core:core:1.0.2" 62 | api 'com.github.addisonElliott:RippleDrawable:3.0.0' 63 | } 64 | -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /library/src/main/java/com/addisonelliott/segmentedbutton/ButtonActor.java: -------------------------------------------------------------------------------- 1 | package com.addisonelliott.segmentedbutton; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | import androidx.annotation.Nullable; 7 | 8 | /** 9 | * Empty, transparent view used as a "dummy" or filler view 10 | * 11 | * This view is used as spacers for the SegmentedButtonGroup LinearLayout that handles the dividers 12 | * 13 | * Each view has a model SegmentedButton that it mimics the width & height of. The width & height is adjusted for the 14 | * divider width to appropriate position the dividers in between the two buttons. 15 | */ 16 | class ButtonActor extends View 17 | { 18 | // Button to mimics size of 19 | private SegmentedButton button = null; 20 | 21 | // Divider width 22 | private int dividerWidth = 0; 23 | 24 | public ButtonActor(Context context) 25 | { 26 | super(context); 27 | } 28 | 29 | public ButtonActor(Context context, @Nullable AttributeSet attrs) 30 | { 31 | super(context, attrs); 32 | } 33 | 34 | public ButtonActor(Context context, @Nullable AttributeSet attrs, int defStyleAttr) 35 | { 36 | super(context, attrs, defStyleAttr); 37 | } 38 | 39 | public void setButton(SegmentedButton button) 40 | { 41 | this.button = button; 42 | } 43 | 44 | public void setDividerWidth(int width) 45 | { 46 | dividerWidth = width; 47 | } 48 | 49 | @Override 50 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 51 | { 52 | // Desired size is the suggested minimum size 53 | // Resolve size based on the measure spec and go from there 54 | // resolveSize 55 | // View.onMeasure uses getDefaultSize which is similar to resolveSize except in the case of 56 | // MeasureSpec.AT_MOST, the maximum value will be returned. In other words, View will expand to fill the 57 | // available area while resolveSize will only use the desired size. 58 | 59 | // Width and height to set the view to 60 | int width; 61 | int height; 62 | 63 | if (button != null) 64 | { 65 | // Calculate the amount to offset the model buttons parent width by 66 | // 67 | // (dividerWidth / 2) is subtracted from the width for each divider present 68 | // Buttons with neighboring buttons on both sides, this adds up to dividerWidth 69 | // Left-most and right-most buttons only have one divider, so this is (dividerWidth / 2) 70 | // And if there is EXACTLY one button being shown, no dividers are present and so the offset is 0 71 | int widthOffset; 72 | if (button.isLeftButton() && button.isRightButton()) 73 | widthOffset = 0; 74 | else if (button.isLeftButton() || button.isRightButton()) 75 | widthOffset = dividerWidth / 2; 76 | else 77 | widthOffset = dividerWidth; 78 | 79 | // Calculate the width & height based on the desired width & height and the measure specs 80 | width = resolveSize(button.getMeasuredWidth() - widthOffset, widthMeasureSpec); 81 | height = resolveSize(button.getMeasuredHeight(), heightMeasureSpec); 82 | } 83 | else 84 | { 85 | // Fallback option to calculate the size based on suggested minimum width & height 86 | width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 87 | height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 88 | } 89 | 90 | setMeasuredDimension(width, height); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /library/src/main/java/com/addisonelliott/segmentedbutton/EmptyView.java: -------------------------------------------------------------------------------- 1 | package com.addisonelliott.segmentedbutton; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | import androidx.annotation.Nullable; 7 | 8 | /** 9 | * Empty, transparent view used as a "dummy" or filler view 10 | * 11 | * This view has a desired size of (minimumWidth, minimumHeight) but will not expand past this size if the space is 12 | * available. This is contrary to View's implementation, which will expand to fill the available space. 13 | * 14 | * The difference is in the onMeasure function between View and EmptyView, specifically for the case of 15 | * MeasureSpec.AT_MOST. 16 | * 17 | * View 18 | *
19 |  * setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
20 |  *     getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
21 |  * 
22 | * where getDefaultSize is defined as: 23 | *
24 |  * public static int getDefaultSize(int size, int measureSpec) {
25 |  *     ...
26 |  *         case MeasureSpec.AT_MOST:
27 |  *         case MeasureSpec.EXACTLY:
28 |  *             result = specSize;
29 |  *             break;
30 |  *     ...
31 |  * }
32 |  * 
33 | * 34 | * Now, rather EmptyView uses resolveSize function and here is how it implements MeasureSpec.AT_MOST 35 | *
36 |  * public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
37 |  *     ...
38 |  *         case MeasureSpec.AT_MOST:
39 |  *             if (specSize < size) {
40 |  *                 result = specSize | MEASURED_STATE_TOO_SMALL;
41 |  *             } else {
42 |  *                 result = size;
43 |  *             }
44 |  *             break;
45 |  *
46 |  *         case MeasureSpec.EXACTLY:
47 |  *             result = specSize;
48 |  *             break;
49 |  *     ...
50 |  * }
51 |  * 
52 | * 53 | * For the case of getDefaultSize for View, AT_MOST will return the maximum value but resolveSize will return UP TO 54 | * the max size, but it will prefer the desired value. 55 | */ 56 | class EmptyView extends View { 57 | 58 | public EmptyView(Context context) { 59 | super(context); 60 | } 61 | 62 | public EmptyView(Context context, @Nullable AttributeSet attrs) { 63 | super(context, attrs); 64 | } 65 | 66 | public EmptyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 67 | super(context, attrs, defStyleAttr); 68 | } 69 | 70 | @Override 71 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 72 | // Desired size is the suggested minimum size 73 | // Resolve size based on the measure spec and go from there 74 | // resolveSize 75 | // View.onMeasure uses getDefaultSize which is similar to resolveSize except in the case of 76 | // MeasureSpec.AT_MOST, the maximum value will be returned. In other words, View will expand to fill the 77 | // available area while resolveSize will only use the desired size. 78 | final int widthSize = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 79 | final int heightSize = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 80 | 81 | setMeasuredDimension(widthSize, heightSize); 82 | } 83 | } -------------------------------------------------------------------------------- /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 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion rootProject.compileSdkVersion 5 | buildToolsVersion rootProject.buildToolsVersion 6 | 7 | defaultConfig { 8 | applicationId "com.addisonelliott.segmentedbutton.sample" 9 | minSdkVersion rootProject.minSdkVersion 10 | targetSdkVersion rootProject.compileSdkVersion 11 | versionCode 1 12 | versionName "0.0.1" 13 | } 14 | 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | // Configure only for each module that uses Java 8 language features (either in its source code or through 23 | // dependencies). 24 | compileOptions { 25 | sourceCompatibility '1.8' 26 | targetCompatibility '1.8' 27 | } 28 | } 29 | 30 | dependencies { 31 | implementation fileTree(dir: 'libs', include: ['*.jar']) 32 | 33 | implementation "androidx.appcompat:appcompat:1.0.2" 34 | 35 | implementation 'com.jakewharton:butterknife:10.1.0' 36 | annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0' 37 | 38 | api project(":library") 39 | } 40 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /sample/src/main/java/com/addisonelliott/segmentedbutton/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.addisonelliott.segmentedbutton.sample; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.Typeface; 5 | import android.graphics.drawable.Drawable; 6 | import android.os.Build.VERSION; 7 | import android.os.Build.VERSION_CODES; 8 | import android.os.Bundle; 9 | import android.view.Gravity; 10 | import android.view.View; 11 | import android.widget.AdapterView; 12 | import android.widget.AdapterView.OnItemSelectedListener; 13 | import android.widget.ArrayAdapter; 14 | import android.widget.Button; 15 | import android.widget.LinearLayout; 16 | import android.widget.LinearLayout.LayoutParams; 17 | import android.widget.Spinner; 18 | import androidx.appcompat.app.AppCompatActivity; 19 | import androidx.core.content.ContextCompat; 20 | import butterknife.BindView; 21 | import butterknife.ButterKnife; 22 | import butterknife.OnClick; 23 | import com.addisonelliott.segmentedbutton.SegmentedButton; 24 | import com.addisonelliott.segmentedbutton.SegmentedButtonGroup; 25 | import com.addisonelliott.segmentedbutton.sample.drawable.BadgeDrawable; 26 | import java.util.ArrayList; 27 | import java.util.Random; 28 | 29 | enum Action 30 | { 31 | None, 32 | ChangeBorder1, 33 | ChangeBorder2, 34 | ChangeBackgroundColor, 35 | ChangeBackgroundDrawable, 36 | ChangeRadius, 37 | ChangePositionAnimated, 38 | ChangePosition, 39 | ToggleDraggable, 40 | ToggleRipple, 41 | ToggleRippleColor, 42 | ChangeDivider, 43 | ChangeAnimation, 44 | RemoveButtonDrawable, 45 | ChangeButtonDrawable, 46 | ChangeDrawableTint, 47 | ToggleDrawableSize, 48 | ChangeDrawableGravity, 49 | ChangeText, 50 | ChangeTextColor, 51 | ChangeTextSize, 52 | ChangeTypeface, 53 | ChangeSelectedButtonRadius, 54 | ChangeSelectedButtonBorderSolid, 55 | ChangeSelectedButtonBorderDashed, 56 | ToggleHiddenButtons, 57 | ChangeTextSize2; 58 | 59 | public String getDisplayText() 60 | { 61 | if (this == None) 62 | return ""; 63 | else if (this == ChangeBorder1) 64 | return "Change border 1"; 65 | else if (this == ChangeBorder2) 66 | return "Change border 2"; 67 | else if (this == ChangeBackgroundColor) 68 | return "Change background and selected background to color"; 69 | else if (this == ChangeBackgroundDrawable) 70 | return "Change background and selected background to drawable"; 71 | else if (this == ChangeRadius) 72 | return "Change radius"; 73 | else if (this == ChangePositionAnimated) 74 | return "Change position and animate movement"; 75 | else if (this == ChangePosition) 76 | return "Change position without animating"; 77 | else if (this == ToggleDraggable) 78 | return "Toggle draggable boolean"; 79 | else if (this == ToggleRipple) 80 | return "Toggle ripple"; 81 | else if (this == ToggleRippleColor) 82 | return "Toggle ripple color between black/white"; 83 | else if (this == ChangeDivider) 84 | return "Change divider"; 85 | else if (this == ChangeAnimation) 86 | return "Change animation duration & interpolator"; 87 | else if (this == RemoveButtonDrawable) 88 | return "Remove button drawable"; 89 | else if (this == ChangeButtonDrawable) 90 | return "Change button drawable"; 91 | else if (this == ChangeDrawableTint) 92 | return "Change drawable tint color"; 93 | else if (this == ToggleDrawableSize) 94 | return "Toggle drawable size"; 95 | else if (this == ChangeDrawableGravity) 96 | return "Change drawable gravity"; 97 | else if (this == ChangeText) 98 | return "Change text"; 99 | else if (this == ChangeTextColor) 100 | return "Change text color"; 101 | else if (this == ChangeTextSize) 102 | return "Change text size"; 103 | else if (this == ChangeTypeface) 104 | return "Change typeface"; 105 | else if (this == ChangeSelectedButtonRadius) 106 | return "Change selected button radius"; 107 | else if (this == ChangeSelectedButtonBorderSolid) 108 | return "Change selected button border (solid)"; 109 | else if (this == ChangeSelectedButtonBorderDashed) 110 | return "Change selected button border (dashed)"; 111 | else if (this == ToggleHiddenButtons) 112 | return "Toggle hidden buttons"; 113 | else if (this == ChangeTextSize2) 114 | return "Change Text Size 2"; 115 | else 116 | return ""; 117 | } 118 | } 119 | 120 | public class MainActivity extends AppCompatActivity implements OnItemSelectedListener 121 | { 122 | private static final String TAG = "SegmentedButtonSample"; 123 | 124 | @BindView(R.id.linearLayout) 125 | LinearLayout linearLayout; 126 | @BindView(R.id.spinner) 127 | Spinner spinner; 128 | @BindView(R.id.button_changePosition) 129 | Button changePositionButton; 130 | @BindView(R.id.buttonGroup_gradient) 131 | SegmentedButtonGroup gradientButtonGroup; 132 | @BindView(R.id.buttonGroup_lordOfTheRings) 133 | SegmentedButtonGroup lordOfTheRingsButtonGroup; 134 | @BindView(R.id.buttonGroup_DCSuperheros) 135 | SegmentedButtonGroup DCSuperHerosButtonGroup; 136 | @BindView(R.id.buttonGroup_marvelSuperheros) 137 | SegmentedButtonGroup marvelSuperherosButtonGroup; 138 | @BindView(R.id.buttonGroup_guys) 139 | SegmentedButtonGroup guysButtonGroup; 140 | @BindView(R.id.buttonGroup_starWars) 141 | SegmentedButtonGroup starWarsButtonGroup; 142 | @BindView(R.id.buttonGroup_darthVader) 143 | SegmentedButtonGroup darthVaderButtonGroup; 144 | @BindView(R.id.buttonGroup_draggable) 145 | SegmentedButtonGroup draggableButtonGroup; 146 | @BindView(R.id.buttonGroup_dynamic) 147 | SegmentedButtonGroup dynamicButtonGroup; 148 | @BindView(R.id.button_left) 149 | SegmentedButton leftButton; 150 | @BindView(R.id.button_right) 151 | SegmentedButton rightButton; 152 | @BindView(R.id.buttonGroup_pickupDropoffBoth) 153 | SegmentedButtonGroup pickupDropoffButtonGroup; 154 | @BindView(R.id.buttonGroup_starWarsAlt) 155 | SegmentedButtonGroup starWarsAltButtonGroup; 156 | @BindView(R.id.buttonGroup_roundSelectedButton) 157 | SegmentedButtonGroup roundSelectedButtonGroup; 158 | 159 | SegmentedButtonGroup yesNoMaybePButtonGroup; 160 | SegmentedButtonGroup starWarsPButtonGroup; 161 | SegmentedButtonGroup countPButtonGroup; 162 | 163 | @Override 164 | protected void onCreate(Bundle savedInstanceState) 165 | { 166 | super.onCreate(savedInstanceState); 167 | setContentView(R.layout.activity_main); 168 | 169 | // Initialize all variables annotated with @BindView and other variants 170 | ButterKnife.bind(this); 171 | 172 | ArrayList spinnerItems = new ArrayList<>(); 173 | 174 | for (Action action : Action.values()) 175 | { 176 | spinnerItems.add(action.getDisplayText()); 177 | } 178 | 179 | ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerItems); 180 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 181 | spinner.setAdapter(adapter); 182 | spinner.setOnItemSelectedListener(this); 183 | 184 | updateButton(gradientButtonGroup.getPosition()); 185 | gradientButtonGroup.setOnPositionChangedListener(position -> updateButton(position)); 186 | 187 | setupDynamicDrawables(); 188 | setupYesNoMaybePButtonGroup(); 189 | setupStarWarsPButtonGroup(); 190 | setupCountPButtonGroup(); 191 | 192 | // Basic checks 193 | if (starWarsButtonGroup.getButtons().size() != 3) 194 | { 195 | throw new AssertionError("Buttons size incorrect"); 196 | } 197 | 198 | if (!lordOfTheRingsButtonGroup.getButton(1).getText().equals("Gimli")) 199 | { 200 | throw new AssertionError("Button name is incorrect"); 201 | } 202 | } 203 | 204 | @Override 205 | public void onItemSelected(final AdapterView parent, final View view, final int position, final long id) 206 | { 207 | Action action = Action.values()[position]; 208 | 209 | switch (action) 210 | { 211 | case None: 212 | break; 213 | 214 | case ChangeBorder1: 215 | lordOfTheRingsButtonGroup.setBorder(5, Color.RED, 25, 8); 216 | marvelSuperherosButtonGroup.setBorder(5, Color.BLACK, 30, 10); 217 | break; 218 | 219 | case ChangeBorder2: 220 | lordOfTheRingsButtonGroup.setBorder(2, Color.RED, 25, 8); 221 | marvelSuperherosButtonGroup.setBorder(2, Color.BLACK, 30, 10); 222 | break; 223 | 224 | case ChangeBackgroundColor: 225 | lordOfTheRingsButtonGroup.setBackground(ContextCompat.getColor(getApplicationContext(), 226 | R.color.brown_600)); 227 | lordOfTheRingsButtonGroup.setSelectedBackground(ContextCompat.getColor(getApplicationContext(), 228 | R.color.blue_800)); 229 | break; 230 | 231 | case ChangeBackgroundDrawable: 232 | lordOfTheRingsButtonGroup.setBackground(ContextCompat.getDrawable(getApplicationContext(), 233 | R.drawable.gradient_drawable)); 234 | lordOfTheRingsButtonGroup.setSelectedBackground(ContextCompat.getDrawable(getApplicationContext(), 235 | R.drawable.gradient_drawable_selector)); 236 | break; 237 | 238 | case ChangeRadius: 239 | marvelSuperherosButtonGroup.setRadius(5); 240 | DCSuperHerosButtonGroup.setRadius(50); 241 | break; 242 | 243 | case ChangePositionAnimated: 244 | lordOfTheRingsButtonGroup.setPosition(((lordOfTheRingsButtonGroup.getPosition() + 1) % 3), true); 245 | break; 246 | 247 | case ChangePosition: 248 | lordOfTheRingsButtonGroup.setPosition(((lordOfTheRingsButtonGroup.getPosition() + 1) % 3), false); 249 | break; 250 | 251 | case ToggleDraggable: 252 | darthVaderButtonGroup.setDraggable(!darthVaderButtonGroup.isDraggable()); 253 | break; 254 | 255 | case ToggleRipple: 256 | starWarsButtonGroup.setRipple(!starWarsButtonGroup.hasRipple()); 257 | break; 258 | 259 | case ToggleRippleColor: 260 | starWarsButtonGroup.setRipple(starWarsButtonGroup.getRippleColor() == Color.WHITE ? Color.BLACK : 261 | Color.WHITE); 262 | break; 263 | 264 | case ChangeDivider: 265 | lordOfTheRingsButtonGroup.setDivider(Color.MAGENTA, 10, 10, 10); 266 | guysButtonGroup.setDivider(ContextCompat.getDrawable(getApplicationContext(), 267 | R.drawable.gradient_drawable_divider), 20, 0, 0); 268 | break; 269 | 270 | case ChangeAnimation: 271 | lordOfTheRingsButtonGroup.setSelectionAnimationDuration( 272 | lordOfTheRingsButtonGroup.getSelectionAnimationDuration() == 500 ? 5000 : 500); 273 | 274 | final int random = new Random().nextInt(12); 275 | lordOfTheRingsButtonGroup.setSelectionAnimationInterpolator(random); 276 | break; 277 | 278 | case RemoveButtonDrawable: 279 | lordOfTheRingsButtonGroup.getButton(0).setDrawable(null); 280 | break; 281 | 282 | case ChangeButtonDrawable: 283 | lordOfTheRingsButtonGroup.getButton(0).setDrawable(ContextCompat.getDrawable(getApplicationContext(), 284 | R.drawable.ic_b9)); 285 | DCSuperHerosButtonGroup.getButton(1).setDrawable(ContextCompat.getDrawable(getApplicationContext(), 286 | R.drawable.ic_aragorn)); 287 | break; 288 | 289 | case ChangeDrawableTint: 290 | lordOfTheRingsButtonGroup.getButton(0).setSelectedDrawableTint(Color.RED); 291 | lordOfTheRingsButtonGroup.getButton(1).setDrawableTint(Color.GREEN); 292 | lordOfTheRingsButtonGroup.getButton(2).setDrawableTint(Color.BLUE); 293 | darthVaderButtonGroup.getButton(1).removeDrawableTint(); 294 | break; 295 | 296 | case ToggleDrawableSize: 297 | final boolean setSize = !DCSuperHerosButtonGroup.getButton(0).hasDrawableWidth(); 298 | final float size = dpToPx(96); 299 | 300 | for (SegmentedButton button : DCSuperHerosButtonGroup.getButtons()) 301 | { 302 | button.setDrawableWidth(setSize ? (int)size : -1); 303 | button.setDrawableHeight(setSize ? (int)size : -1); 304 | } 305 | break; 306 | 307 | case ChangeDrawableGravity: 308 | gradientButtonGroup.getButton(0).setDrawableGravity(Gravity.LEFT); 309 | starWarsButtonGroup.getButton(0).setDrawableGravity(Gravity.RIGHT); 310 | 311 | int currentGravity = DCSuperHerosButtonGroup.getButton(0).getDrawableGravity(); 312 | 313 | switch (currentGravity) 314 | { 315 | case Gravity.LEFT: 316 | currentGravity = Gravity.TOP; 317 | break; 318 | case Gravity.TOP: 319 | currentGravity = Gravity.RIGHT; 320 | break; 321 | case Gravity.RIGHT: 322 | currentGravity = Gravity.BOTTOM; 323 | break; 324 | case Gravity.BOTTOM: 325 | currentGravity = Gravity.LEFT; 326 | break; 327 | } 328 | 329 | DCSuperHerosButtonGroup.getButton(0).setDrawableGravity(currentGravity); 330 | break; 331 | 332 | case ChangeText: 333 | lordOfTheRingsButtonGroup.getButton(0).setText("Testing"); 334 | lordOfTheRingsButtonGroup.getButton(1).setText(""); 335 | break; 336 | 337 | case ChangeTextColor: 338 | lordOfTheRingsButtonGroup.getButton(0).setSelectedTextColor(Color.RED); 339 | lordOfTheRingsButtonGroup.getButton(1).setTextColor(Color.BLUE); 340 | gradientButtonGroup.getButton(1).removeSelectedTextColor(); 341 | break; 342 | 343 | case ChangeTextSize: 344 | lordOfTheRingsButtonGroup.getButton(1).setTextSize(48.0f); 345 | DCSuperHerosButtonGroup.getButton(0).setTextSize(48.0f); 346 | break; 347 | 348 | case ChangeTypeface: 349 | lordOfTheRingsButtonGroup.getButton(0).setTextTypeface(Typeface.create((Typeface)null, Typeface.BOLD)); 350 | break; 351 | 352 | case ChangeSelectedButtonRadius: 353 | { 354 | final float radius = dpToPx(30); 355 | 356 | lordOfTheRingsButtonGroup.setSelectedButtonRadius((int)radius); 357 | roundSelectedButtonGroup.setSelectedButtonRadius(0); 358 | } 359 | break; 360 | 361 | case ChangeSelectedButtonBorderSolid: 362 | lordOfTheRingsButtonGroup.setSelectedBorder(5, Color.MAGENTA, 0, 0); 363 | roundSelectedButtonGroup.setSelectedBorder(0, 0, 0, 0); 364 | break; 365 | 366 | case ChangeSelectedButtonBorderDashed: 367 | lordOfTheRingsButtonGroup.setSelectedBorder(5, Color.MAGENTA, 6, 3); 368 | roundSelectedButtonGroup.setSelectedBorder(16, Color.BLACK, 6, 2); 369 | break; 370 | 371 | case ToggleHiddenButtons: 372 | { 373 | SegmentedButton button = gradientButtonGroup.getButton(0); 374 | button.setVisibility(button.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); 375 | 376 | button = starWarsButtonGroup.getButton(1); 377 | button.setVisibility(button.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); 378 | 379 | button = darthVaderButtonGroup.getButton(2); 380 | button.setVisibility(button.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); 381 | 382 | button = draggableButtonGroup.getButton(0); 383 | button.setVisibility(button.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); 384 | 385 | button = roundSelectedButtonGroup.getButton(2); 386 | button.setVisibility(button.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); 387 | } 388 | break; 389 | 390 | case ChangeTextSize2: 391 | yesNoMaybePButtonGroup.getButton(0).setTextSize(dpToPx(36)); 392 | yesNoMaybePButtonGroup.getButton(1).setTextSize(dpToPx(36)); 393 | yesNoMaybePButtonGroup.getButton(2).setTextSize(dpToPx(36)); 394 | break; 395 | 396 | default: 397 | break; 398 | } 399 | 400 | // Reset back to the normal value 401 | spinner.setSelection(0); 402 | } 403 | 404 | @Override 405 | public void onNothingSelected(final AdapterView parent) 406 | { 407 | 408 | } 409 | 410 | @OnClick(R.id.button_changePosition) 411 | public void changePositionButton_onClick(View view) 412 | { 413 | int position = gradientButtonGroup.getPosition(); 414 | position = ++position % 3; 415 | updateButton(position); 416 | 417 | gradientButtonGroup.setPosition(position, true); 418 | } 419 | 420 | private void setupDynamicDrawables() 421 | { 422 | final BadgeDrawable drawable = new BadgeDrawable(Color.RED, 80, 50, 3, 3); 423 | leftButton.setDrawable(drawable); 424 | 425 | dynamicButtonGroup.setOnPositionChangedListener(position -> { 426 | if (position == 0) 427 | { 428 | drawable.setCount(drawable.getCount() + 1); 429 | } 430 | }); 431 | 432 | final Drawable drawable2 = ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_b1); 433 | rightButton.setDrawable(drawable2); 434 | } 435 | 436 | private void updateButton(int position) 437 | { 438 | changePositionButton.setText("Position: " + position); 439 | } 440 | 441 | private float dpToPx(float dp) 442 | { 443 | return dp * getResources().getDisplayMetrics().density; 444 | } 445 | 446 | private float pxToDp(float px) 447 | { 448 | return px / getResources().getDisplayMetrics().density; 449 | } 450 | 451 | private float spToPx(float sp) 452 | { 453 | return sp * getResources().getDisplayMetrics().scaledDensity; 454 | } 455 | 456 | private float pxToSp(float px) 457 | { 458 | return px / getResources().getDisplayMetrics().scaledDensity; 459 | } 460 | 461 | private void setupYesNoMaybePButtonGroup() 462 | { 463 | SegmentedButtonGroup buttonGroup = new SegmentedButtonGroup(this); 464 | buttonGroup.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 465 | ((LayoutParams)buttonGroup.getLayoutParams()).setMargins((int)dpToPx(4), (int)dpToPx(4), 466 | (int)dpToPx(4), (int)dpToPx(4)); 467 | if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) 468 | buttonGroup.setElevation(dpToPx(2)); 469 | buttonGroup.setBackground(Color.WHITE); 470 | buttonGroup.setRadius((int)dpToPx(30)); 471 | buttonGroup.setRipple(Color.BLACK); 472 | buttonGroup.setSelectedBackground(getResources().getColor(R.color.blue_500)); 473 | buttonGroup.setSelectedBorder((int)dpToPx(2), Color.rgb(0x55, 0x55, 0x55), 0, 0); 474 | buttonGroup.setSelectedButtonRadius((int)dpToPx(30)); 475 | buttonGroup.setSelectionAnimationDuration(1000); 476 | 477 | SegmentedButton yesButton = new SegmentedButton(this); 478 | yesButton.setText("Yes"); 479 | yesButton.setPadding((int)dpToPx(8), (int)dpToPx(8), (int)dpToPx(8), (int)dpToPx(8)); 480 | yesButton.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1)); 481 | yesButton.setTextColor(Color.BLACK); 482 | yesButton.setSelectedTextColor(Color.WHITE); 483 | yesButton.setTextSize(spToPx(24)); 484 | buttonGroup.addView(yesButton); 485 | 486 | SegmentedButton maybeButton = new SegmentedButton(this); 487 | maybeButton.setText("Maybe"); 488 | maybeButton.setPadding((int)dpToPx(8), (int)dpToPx(8), (int)dpToPx(8), (int)dpToPx(8)); 489 | maybeButton.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1)); 490 | maybeButton.setTextColor(Color.BLACK); 491 | maybeButton.setSelectedTextColor(Color.WHITE); 492 | maybeButton.setTextSize(spToPx(24)); 493 | buttonGroup.addView(maybeButton); 494 | 495 | SegmentedButton noButton = new SegmentedButton(this); 496 | noButton.setText("No"); 497 | noButton.setPadding((int)dpToPx(8), (int)dpToPx(8), (int)dpToPx(8), (int)dpToPx(8)); 498 | noButton.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1)); 499 | noButton.setTextColor(Color.BLACK); 500 | noButton.setSelectedTextColor(Color.WHITE); 501 | noButton.setTextSize(spToPx(24)); 502 | buttonGroup.addView(noButton); 503 | 504 | buttonGroup.setPosition(1, false); 505 | linearLayout.addView(buttonGroup); 506 | yesNoMaybePButtonGroup = buttonGroup; 507 | } 508 | 509 | private void setupStarWarsPButtonGroup() 510 | { 511 | SegmentedButtonGroup buttonGroup = new SegmentedButtonGroup(this); 512 | buttonGroup.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 513 | ((LinearLayout.LayoutParams)buttonGroup.getLayoutParams()).setMargins((int)dpToPx(4), (int)dpToPx(4), 514 | (int)dpToPx(4), (int)dpToPx(4)); 515 | ((LayoutParams)buttonGroup.getLayoutParams()).gravity = Gravity.CENTER_HORIZONTAL; 516 | if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) 517 | buttonGroup.setElevation(dpToPx(2)); 518 | buttonGroup.setBackground(getResources().getColor(R.color.red_400)); 519 | buttonGroup.setRadius((int)dpToPx(2)); 520 | buttonGroup.setRipple(getResources().getColor(R.color.red_200)); 521 | buttonGroup.setSelectedBackground(getResources().getColor(R.color.green_200)); 522 | buttonGroup.setDivider(Color.WHITE, (int)dpToPx(2), (int)dpToPx(10), (int)dpToPx(10)); 523 | 524 | SegmentedButton button1 = new SegmentedButton(this); 525 | button1.setLayoutParams(new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1)); 526 | button1.setPadding((int)dpToPx(20), (int)dpToPx(6), (int)dpToPx(20), (int)dpToPx(6)); 527 | button1.setDrawable(getResources().getDrawable(R.drawable.ic_b8)); 528 | buttonGroup.addView(button1); 529 | 530 | SegmentedButton button2 = new SegmentedButton(this); 531 | button2.setLayoutParams(new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, 2)); 532 | button2.setPadding((int)dpToPx(45), (int)dpToPx(6), (int)dpToPx(45), (int)dpToPx(6)); 533 | button2.setDrawable(getResources().getDrawable(R.drawable.ic_b9)); 534 | buttonGroup.addView(button2); 535 | 536 | SegmentedButton button3 = new SegmentedButton(this); 537 | button3.setLayoutParams(new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1)); 538 | button3.setPadding((int)dpToPx(20), (int)dpToPx(6), (int)dpToPx(20), (int)dpToPx(6)); 539 | button3.setDrawable(getResources().getDrawable(R.drawable.ic_b11)); 540 | buttonGroup.addView(button3); 541 | 542 | buttonGroup.setPosition(1, false); 543 | linearLayout.addView(buttonGroup); 544 | starWarsPButtonGroup = buttonGroup; 545 | } 546 | 547 | private void setupCountPButtonGroup() 548 | { 549 | SegmentedButtonGroup buttonGroup = new SegmentedButtonGroup(this); 550 | buttonGroup.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 551 | ((LinearLayout.LayoutParams)buttonGroup.getLayoutParams()).setMargins((int)dpToPx(32), (int)dpToPx(16), 552 | (int)dpToPx(32), (int)dpToPx(16)); 553 | ((LayoutParams)buttonGroup.getLayoutParams()).gravity = Gravity.CENTER_HORIZONTAL; 554 | buttonGroup.setBorder(3, Color.LTGRAY, 0, 0); 555 | buttonGroup.setDivider(Color.DKGRAY, 5, 5, 5); 556 | buttonGroup.setOnPositionChangedListener(position -> { 557 | if (countPButtonGroup == null) 558 | return; 559 | 560 | countPButtonGroup.getButton(2).setText(countPButtonGroup.getButton(2).getText()); 561 | }); 562 | 563 | String[] names = { 564 | "Two", 565 | "One", 566 | "None" 567 | }; 568 | 569 | for (String name : names) 570 | { 571 | SegmentedButton button = new SegmentedButton(this); 572 | button.setText(name); 573 | button.setTextSize(dpToPx(18)); 574 | button.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 575 | button.setPadding((int)dpToPx(20), (int)dpToPx(20), (int)dpToPx(20), (int)dpToPx(20)); 576 | button.setTextColor(Color.BLACK); 577 | button.setSelectedTextColor(Color.WHITE); 578 | button.setSelectedBackgroundColor(getResources().getColor(R.color.colorPrimary)); 579 | buttonGroup.addView(button); 580 | } 581 | 582 | linearLayout.addView(buttonGroup); 583 | countPButtonGroup = buttonGroup; 584 | } 585 | } 586 | -------------------------------------------------------------------------------- /sample/src/main/java/com/addisonelliott/segmentedbutton/sample/drawable/BadgeDrawable.java: -------------------------------------------------------------------------------- 1 | package com.addisonelliott.segmentedbutton.sample.drawable; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.ColorFilter; 5 | import android.graphics.Paint; 6 | import android.graphics.Path; 7 | import android.graphics.PixelFormat; 8 | import android.graphics.Rect; 9 | import android.graphics.RectF; 10 | import android.graphics.drawable.Drawable; 11 | import androidx.annotation.NonNull; 12 | 13 | public class BadgeDrawable extends Drawable { 14 | 15 | private Paint paint; 16 | private int color; 17 | private int width; 18 | private int height; 19 | private int borderWidth; 20 | private int borderRadius; 21 | 22 | private RectF rect; 23 | private Path path; 24 | private int count = 10; 25 | 26 | public BadgeDrawable(int color, int width, int height, int borderWidth, int borderRadius) { 27 | paint = new Paint(Paint.ANTI_ALIAS_FLAG); 28 | paint.setStyle(Paint.Style.FILL); 29 | paint.setTextSize(32); 30 | 31 | path = new Path(); 32 | path.setFillType(Path.FillType.EVEN_ODD); 33 | 34 | rect = new RectF(); 35 | 36 | this.color = color; 37 | this.width = width; 38 | this.height = height; 39 | this.borderWidth = borderWidth; 40 | this.borderRadius = borderRadius; 41 | } 42 | 43 | @Override 44 | public int getIntrinsicWidth() { 45 | return width; 46 | } 47 | 48 | @Override 49 | public int getIntrinsicHeight() { 50 | return height; 51 | } 52 | 53 | @Override 54 | protected void onBoundsChange(Rect bounds) { 55 | path.reset(); 56 | 57 | path.addRect(bounds.left, bounds.top, bounds.right, bounds.bottom, Path.Direction.CW); 58 | rect.set(bounds.left + borderWidth, bounds.top + borderWidth, 59 | bounds.right - borderWidth, bounds.bottom - borderWidth); 60 | path.addRoundRect(rect, borderRadius, borderRadius, Path.Direction.CW); 61 | } 62 | 63 | @Override 64 | public void draw(@NonNull Canvas canvas) { 65 | paint.setColor(color); 66 | canvas.drawPath(path, paint); 67 | 68 | Rect textBounds = new Rect(); 69 | String countString = String.valueOf(count); 70 | paint.getTextBounds(countString, 0, countString.length(), textBounds); 71 | canvas.drawText(countString, 72 | rect.right - (rect.right - rect.left) / 2 - textBounds.width() / 2, 73 | rect.top + textBounds.height() / 2 + (rect.bottom - rect.top) / 2, 74 | paint 75 | ); 76 | } 77 | 78 | @Override 79 | public void setAlpha(int alpha) { 80 | paint.setAlpha(alpha); 81 | } 82 | 83 | @Override 84 | public void setColorFilter(ColorFilter cf) { 85 | paint.setColorFilter(cf); 86 | } 87 | 88 | @Override 89 | public int getOpacity() { 90 | return PixelFormat.TRANSLUCENT; 91 | } 92 | 93 | public int getCount() { 94 | return count; 95 | } 96 | 97 | public void setCount(int count) { 98 | this.count = count; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_aragorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_aragorn.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b1.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b11.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b12.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b13.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b17.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b2.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b3.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b4.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b5.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b6.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b7.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b8.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_b9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_b9.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_gimli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_gimli.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_legolas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-hdpi/ic_legolas.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_aragorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_aragorn.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b1.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b11.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b12.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b13.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b17.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b2.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b3.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b4.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b5.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b6.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b7.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b8.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_b9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_b9.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_gimli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_gimli.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_legolas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-mdpi/ic_legolas.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_aragorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_aragorn.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b1.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b11.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b12.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b13.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b17.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b2.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b3.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b4.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b5.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b6.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b7.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b8.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_b9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_b9.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_gimli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_gimli.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_legolas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xhdpi/ic_legolas.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_aragorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_aragorn.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b1.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b11.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b12.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b13.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b17.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b2.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b3.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b4.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b5.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b6.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b7.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b8.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_b9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_b9.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_gimli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_gimli.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_legolas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxhdpi/ic_legolas.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_aragorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_aragorn.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b1.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b11.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b12.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b13.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b17.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b2.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b3.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b4.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b5.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b6.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b7.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b8.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_b9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_b9.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_gimli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_gimli.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_legolas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/drawable-xxxhdpi/ic_legolas.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable/gradient_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/gradient_drawable_divider.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/gradient_drawable_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_chart_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_chart_donut.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_chart_pie.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/font/aniron.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/font/aniron.ttf -------------------------------------------------------------------------------- /sample/src/main/res/font/shaka_pow.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/addisonElliott/SegmentedButton/8b4bd4832873ba15970f6115b52e46be2330790f/sample/src/main/res/font/shaka_pow.ttf -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 18 | 19 | 27 | 28 | 34 | 35 |