├── .gitignore ├── ASCV Import Instructions.pdf ├── AndroidSegmentedControlView.iml ├── LICENSE ├── README.md ├── ascvexample ├── .gitignore ├── ascvexample.iml ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── mitre │ │ └── ascv │ │ └── example │ │ └── Example.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ └── activity_example.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── example_values.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── lib ├── .gitignore ├── README.md ├── build.gradle ├── lib.iml ├── proguard-rules.pro ├── sample_ascv_image.png └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── mitre │ │ └── ascv │ │ └── AndroidSegmentedControlView.java │ └── res │ ├── drawable │ ├── left_option.xml │ ├── left_option_selected.xml │ ├── middle_option.xml │ ├── middle_option_selected.xml │ ├── right_option.xml │ └── right_option_selected.xml │ └── values │ ├── attrs.xml │ └── colors.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /.idea 8 | /gradle 9 | gradlew 10 | gradlew.bat 11 | local.properties 12 | /lib/build 13 | /ascvexample/build 14 | -------------------------------------------------------------------------------- /ASCV Import Instructions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klongmitre/android-segmented-control-view/54056f04e0a5e2551ac71cc01f6b71576425936a/ASCV Import Instructions.pdf -------------------------------------------------------------------------------- /AndroidSegmentedControlView.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014 The MITRE Corporation 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](lib/sample_ascv_image.png) 2 | 3 | ###NOTICE 4 | This is the copyright work of The MITRE Corporation, and was produced for 5 | the U. S. Government under Contract Number DTFAWA-10-C-00080, and is subject 6 | to Federal Aviation Administration Acquisition Management System Clause 7 | 3.5-13, Rights In Data-General, Alt. III and Alt. IV (Oct. 1996). No other 8 | use other than that granted to the U. S. Government, or to those acting on 9 | behalf of the U. S. Government, under that Clause is authorized without the 10 | express written permission of The MITRE Corporation. For further information, 11 | please contact The MITRE Corporation, Contracts Office,7515 Colshire Drive, 12 | McLean, VA 22102-7539, (703) 983-6000. 13 | 14 | Approved for Public Release; Distribution Unlimited. Case Number 14-4045 15 | 16 | Copyright 2014 The MITRE Corporation. All Rights Reserved. 17 | 18 | ###LICENSE 19 | Copyright 2014 The MITRE Corporation 20 | 21 | Licensed under the Apache License, Version 2.0 (the "License"); 22 | you may not use this file except in compliance with the License. 23 | You may obtain a copy of the License at 24 | 25 | http://www.apache.org/licenses/LICENSE-2.0 26 | 27 | Unless required by applicable law or agreed to in writing, software 28 | distributed under the License is distributed on an "AS IS" BASIS, 29 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 30 | See the License for the specific language governing permissions and 31 | limitations under the License. 32 | 33 | ###Contents of Repository 34 | 35 | This repository contains two modules 36 | 37 | 1. Android Segmented Control View Library (lib) 38 | 39 | This is the library project that can be included in your own project 40 | and contains the code for the Android Segmented Control View 41 | 42 | 2. Android Segmented Control View Example Application (ascvexample) 43 | 44 | This is a sample application demonstrating how to include and interact 45 | with the Android Segmented Control View 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /ascvexample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /ascvexample/ascvexample.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /ascvexample/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTICE 3 | * 4 | * This is the copyright work of The MITRE Corporation, and was produced for 5 | * the U. S. Government under Contract Number DTFAWA-10-C-00080, and is subject 6 | * to Federal Aviation Administration Acquisition Management System Clause 7 | * 3.5-13, Rights In Data-General, Alt. III and Alt. IV (Oct. 1996). No other 8 | * use other than that granted to the U. S. Government, or to those acting on 9 | * behalf of the U. S. Government, under that Clause is authorized without the 10 | * express written permission of The MITRE Corporation. For further information, 11 | * please contact The MITRE Corporation, Contracts Office,7515 Colshire Drive, 12 | * McLean, VA 22102-7539, (703) 983-6000. 13 | * 14 | * Approved for Public Release; Distribution Unlimited. Case Number 14-4045 15 | */ 16 | 17 | apply plugin: 'com.android.application' 18 | 19 | android { 20 | compileSdkVersion 19 21 | buildToolsVersion "20.0.0" 22 | 23 | defaultConfig { 24 | applicationId "org.mitre.ascv.example" 25 | minSdkVersion 14 26 | targetSdkVersion 19 27 | versionCode 1 28 | versionName "1.0" 29 | } 30 | buildTypes { 31 | release { 32 | runProguard false 33 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 34 | } 35 | } 36 | } 37 | 38 | dependencies { 39 | compile fileTree(dir: 'libs', include: ['*.jar']) 40 | compile project(':lib') 41 | } 42 | -------------------------------------------------------------------------------- /ascvexample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:/Users/klong/AppData/Local/Android/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /ascvexample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 18 | 19 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /ascvexample/src/main/java/org/mitre/ascv/example/Example.java: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTICE 3 | * 4 | * This is the copyright work of The MITRE Corporation, and was produced for 5 | * the U. S. Government under Contract Number DTFAWA-10-C-00080, and is subject 6 | * to Federal Aviation Administration Acquisition Management System Clause 7 | * 3.5-13, Rights In Data-General, Alt. III and Alt. IV (Oct. 1996). No other 8 | * use other than that granted to the U. S. Government, or to those acting on 9 | * behalf of the U. S. Government, under that Clause is authorized without the 10 | * express written permission of The MITRE Corporation. For further information, 11 | * please contact The MITRE Corporation, Contracts Office,7515 Colshire Drive, 12 | * McLean, VA 22102-7539, (703) 983-6000. 13 | * 14 | * Approved for Public Release; Distribution Unlimited. Case Number 14-4045 15 | */ 16 | 17 | package org.mitre.ascv.example; 18 | 19 | import android.app.Activity; 20 | import android.graphics.Color; 21 | import android.os.Bundle; 22 | import android.widget.LinearLayout; 23 | 24 | import org.mitre.ascv.AndroidSegmentedControlView; 25 | 26 | 27 | public class Example extends Activity { 28 | 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.activity_example); 33 | LinearLayout holder = (LinearLayout) findViewById(R.id.ascv_sample_holder); 34 | try { 35 | 36 | 37 | AndroidSegmentedControlView ascv = new AndroidSegmentedControlView(this); 38 | ascv.setColors(Color.parseColor("#0066CC"),Color.parseColor("#FFFFFF")); 39 | ascv.setItems(new String[]{"Test1", "Test2", "Test3"}, new String[]{"1", "2", "3"}); 40 | ascv.setDefaultSelection(0); 41 | holder.addView(ascv); 42 | 43 | AndroidSegmentedControlView ascv2 = new AndroidSegmentedControlView(this); 44 | ascv2.setColors(Color.parseColor("#D24E4E"),Color.parseColor("#FFFFFF")); 45 | ascv2.setStretch(true); 46 | ascv2.setItems(new String[]{"Test4", "Test5", "Test6"}, new String[]{"4", "5", "6"}); 47 | ascv2.setDefaultSelection(2); 48 | holder.addView(ascv2); 49 | 50 | }catch (Exception ex){ 51 | ex.printStackTrace(); 52 | } 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /ascvexample/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klongmitre/android-segmented-control-view/54056f04e0a5e2551ac71cc01f6b71576425936a/ascvexample/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ascvexample/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klongmitre/android-segmented-control-view/54056f04e0a5e2551ac71cc01f6b71576425936a/ascvexample/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ascvexample/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klongmitre/android-segmented-control-view/54056f04e0a5e2551ac71cc01f6b71576425936a/ascvexample/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ascvexample/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klongmitre/android-segmented-control-view/54056f04e0a5e2551ac71cc01f6b71576425936a/ascvexample/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ascvexample/src/main/res/layout/activity_example.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 29 | 30 | 36 | 37 | 46 | 47 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /ascvexample/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 21 | 64dp 22 | 23 | -------------------------------------------------------------------------------- /ascvexample/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 16dp 20 | 16dp 21 | 22 | -------------------------------------------------------------------------------- /ascvexample/src/main/res/values/example_values.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | #0066CC 20 | #FFFFFF 21 | #0066CC 22 | #FFFFFF 23 | 24 | Option 1 25 | Option 2 26 | Option 3 27 | 28 | -------------------------------------------------------------------------------- /ascvexample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | "ASCV Example" 21 | Example 22 | 23 | 24 | -------------------------------------------------------------------------------- /ascvexample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTICE 3 | * 4 | * This is the copyright work of The MITRE Corporation, and was produced for 5 | * the U. S. Government under Contract Number DTFAWA-10-C-00080, and is subject 6 | * to Federal Aviation Administration Acquisition Management System Clause 7 | * 3.5-13, Rights In Data-General, Alt. III and Alt. IV (Oct. 1996). No other 8 | * use other than that granted to the U. S. Government, or to those acting on 9 | * behalf of the U. S. Government, under that Clause is authorized without the 10 | * express written permission of The MITRE Corporation. For further information, 11 | * please contact The MITRE Corporation, Contracts Office,7515 Colshire Drive, 12 | * McLean, VA 22102-7539, (703) 983-6000. 13 | * 14 | * Approved for Public Release; Distribution Unlimited. Case Number 14-4045 15 | */ 16 | 17 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 18 | 19 | buildscript { 20 | repositories { 21 | jcenter() 22 | } 23 | dependencies { 24 | classpath 'com.android.tools.build:gradle:0.14.0' 25 | 26 | // NOTE: Do not place your application dependencies here; they belong 27 | // in the individual module build.gradle files 28 | } 29 | } 30 | 31 | allprojects { 32 | repositories { 33 | jcenter() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # NOTICE 3 | # 4 | # This is the copyright work of The MITRE Corporation, and was produced for 5 | # the U. S. Government under Contract Number DTFAWA-10-C-00080, and is subject 6 | # to Federal Aviation Administration Acquisition Management System Clause 7 | # 3.5-13, Rights In Data-General, Alt. III and Alt. IV (Oct. 1996). No other 8 | # use other than that granted to the U. S. Government, or to those acting on 9 | # behalf of the U. S. Government, under that Clause is authorized without the 10 | # express written permission of The MITRE Corporation. For further information, 11 | # please contact The MITRE Corporation, Contracts Office,7515 Colshire Drive, 12 | # McLean, VA 22102-7539, (703) 983-6000. 13 | # 14 | 15 | # Project-wide Gradle settings. 16 | 17 | # IDE (e.g. Android Studio) users: 18 | # Settings specified in this file will override any Gradle settings 19 | # configured through the IDE. 20 | 21 | # For more details on how to configure your build environment visit 22 | # http://www.gradle.org/docs/current/userguide/build_environment.html 23 | 24 | # Specifies the JVM arguments used for the daemon process. 25 | # The setting is particularly useful for tweaking memory settings. 26 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 27 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 28 | 29 | # When configured, Gradle will run in incubating parallel mode. 30 | # This option should only be used with decoupled projects. More details, visit 31 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 32 | # org.gradle.parallel=true 33 | 34 | 35 | -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /lib/README.md: -------------------------------------------------------------------------------- 1 | How to add it to your projects 2 | ------------- 3 | ASCV can be added to layouts either through the Android layout designer using xml markup, or dynamically via code. 4 | 5 | ####Add ASCV via XML markup: 6 | 7 | 16 | 17 | ####Add ASCV via XML markup: 18 | 19 | AndroidSegmentedControlView ascv = new AndroidSegmentedControlView(this); 20 | ascv.setColors(Color.parseColor("#0066CC"),Color.parseColor("#FFFFFF")); 21 | ascv.setItems(new String[]{"Test1", "Test2", "Test3"}, new String[]{"1", "2", "3"}); 22 | ascv.setDefaultSelection(0); 23 | holder.addView(ascv); 24 | 25 | -------------------------------------------------------------------------------- /lib/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTICE 3 | * 4 | * This is the copyright work of The MITRE Corporation, and was produced for 5 | * the U. S. Government under Contract Number DTFAWA-10-C-00080, and is subject 6 | * to Federal Aviation Administration Acquisition Management System Clause 7 | * 3.5-13, Rights In Data-General, Alt. III and Alt. IV (Oct. 1996). No other 8 | * use other than that granted to the U. S. Government, or to those acting on 9 | * behalf of the U. S. Government, under that Clause is authorized without the 10 | * express written permission of The MITRE Corporation. For further information, 11 | * please contact The MITRE Corporation, Contracts Office,7515 Colshire Drive, 12 | * McLean, VA 22102-7539, (703) 983-6000. 13 | * 14 | * Approved for Public Release; Distribution Unlimited. Case Number 14-4045 15 | */ 16 | 17 | apply plugin: 'com.android.library' 18 | 19 | android { 20 | compileSdkVersion 19 21 | buildToolsVersion "20.0.0" 22 | 23 | defaultConfig { 24 | applicationId "org.mitre.ascv" 25 | minSdkVersion 10 26 | targetSdkVersion 19 27 | versionCode 1 28 | versionName "1.0" 29 | } 30 | buildTypes { 31 | release { 32 | runProguard false 33 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 34 | } 35 | } 36 | } 37 | 38 | dependencies { 39 | compile fileTree(dir: 'libs', include: ['*.jar']) 40 | } 41 | -------------------------------------------------------------------------------- /lib/lib.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 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 | -------------------------------------------------------------------------------- /lib/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:/Users/klong/AppData/Local/Android/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /lib/sample_ascv_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klongmitre/android-segmented-control-view/54056f04e0a5e2551ac71cc01f6b71576425936a/lib/sample_ascv_image.png -------------------------------------------------------------------------------- /lib/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /lib/src/main/java/org/mitre/ascv/AndroidSegmentedControlView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTICE 3 | * 4 | * This is the copyright work of The MITRE Corporation, and was produced for 5 | * the U. S. Government under Contract Number DTFAWA-10-C-00080, and is subject 6 | * to Federal Aviation Administration Acquisition Management System Clause 7 | * 3.5-13, Rights In Data-General, Alt. III and Alt. IV (Oct. 1996). No other 8 | * use other than that granted to the U. S. Government, or to those acting on 9 | * behalf of the U. S. Government, under that Clause is authorized without the 10 | * express written permission of The MITRE Corporation. For further information, 11 | * please contact The MITRE Corporation, Contracts Office,7515 Colshire Drive, 12 | * McLean, VA 22102-7539, (703) 983-6000. 13 | * 14 | * Approved for Public Release; Distribution Unlimited. Case Number 14-4045 15 | */ 16 | 17 | package org.mitre.ascv; 18 | 19 | import android.annotation.TargetApi; 20 | import android.content.Context; 21 | import android.content.res.ColorStateList; 22 | import android.content.res.TypedArray; 23 | import android.graphics.Color; 24 | import android.graphics.Typeface; 25 | import android.graphics.drawable.GradientDrawable; 26 | import android.graphics.drawable.StateListDrawable; 27 | import android.os.Build; 28 | import android.util.AttributeSet; 29 | import android.util.TypedValue; 30 | import android.view.Gravity; 31 | import android.view.ViewGroup; 32 | import android.widget.RadioButton; 33 | import android.widget.RadioGroup; 34 | 35 | import java.util.ArrayList; 36 | import java.util.Iterator; 37 | import java.util.LinkedHashMap; 38 | import java.util.Map; 39 | 40 | /** 41 | * Created by KLONG on 7/2/2014. 42 | */ 43 | public class AndroidSegmentedControlView extends RadioGroup { 44 | 45 | //Helpers 46 | private int mSdk; 47 | private Context mCtx; 48 | 49 | //Interaction 50 | private OnSelectionChangedListener mListener; 51 | 52 | //UI 53 | private int selectedColor = Color.parseColor("#0099CC"); 54 | private int unselectedColor = Color.TRANSPARENT; 55 | private int unselectedTextColor = Color.parseColor("#0099CC"); 56 | private int defaultSelection = -1; 57 | private boolean stretch = false; 58 | private int selectedTextColor = Color.WHITE; 59 | private boolean equalWidth = false; 60 | private String identifier = ""; 61 | private ColorStateList textColorStateList; 62 | 63 | //Item organization 64 | private LinkedHashMap itemMap = new LinkedHashMap(); 65 | private ArrayList options; 66 | 67 | public AndroidSegmentedControlView(Context context) { 68 | super(context, null); 69 | //Initialize 70 | init(context); 71 | // Setup the view 72 | update(); 73 | } 74 | 75 | public AndroidSegmentedControlView(Context context, AttributeSet attrs) throws Exception { 76 | super(context, attrs); 77 | 78 | //Initialize 79 | init(context); 80 | 81 | //Here's where overwrite the defaults with the values from the xml attributes 82 | TypedArray attributes = context.getTheme().obtainStyledAttributes( 83 | attrs, 84 | R.styleable.MultipleSelectionButton, 85 | 0, 0); 86 | 87 | try { 88 | 89 | selectedColor = attributes.getColor(R.styleable.MultipleSelectionButton_ascv_selectedColor, selectedColor); 90 | selectedTextColor = attributes.getColor(R.styleable.MultipleSelectionButton_ascv_selectedTextColor, selectedTextColor); 91 | unselectedColor = attributes.getColor(R.styleable.MultipleSelectionButton_ascv_unselectedColor, unselectedColor); 92 | unselectedTextColor = attributes.getColor(R.styleable.MultipleSelectionButton_ascv_unselectedTextColor, selectedColor); 93 | 94 | //Set text selectedColor state list 95 | textColorStateList = new ColorStateList(new int[][]{ 96 | {-android.R.attr.state_checked}, {android.R.attr.state_checked}}, 97 | new int[]{unselectedTextColor, selectedTextColor} 98 | ); 99 | 100 | defaultSelection = attributes.getInt(R.styleable.MultipleSelectionButton_ascv_defaultSelection, defaultSelection); 101 | equalWidth = attributes.getBoolean(R.styleable.MultipleSelectionButton_ascv_equalWidth, equalWidth); 102 | stretch = attributes.getBoolean(R.styleable.MultipleSelectionButton_ascv_stretch, stretch); 103 | identifier = attributes.getString(R.styleable.MultipleSelectionButton_ascv_identifier); 104 | 105 | CharSequence[] itemArray = attributes.getTextArray(R.styleable.MultipleSelectionButton_ascv_items); 106 | CharSequence[] valueArray = attributes.getTextArray(R.styleable.MultipleSelectionButton_ascv_values); 107 | 108 | // TODO: Need to look into better setting up the item for the preview view 109 | if (this.isInEditMode()) { 110 | itemArray = new CharSequence[]{"YES", "NO", "MAYBE", "DON'T KNOW"}; 111 | } 112 | 113 | //Item and value arrays need to be of the same length 114 | if (itemArray != null && valueArray != null) { 115 | if (itemArray.length != valueArray.length) { 116 | throw new Exception("Item labels and value arrays must be the same size"); 117 | } 118 | } 119 | 120 | if (itemArray != null) { 121 | 122 | if (valueArray != null) { 123 | for (int i = 0; i < itemArray.length; i++) { 124 | itemMap.put(itemArray[i].toString(), valueArray[i].toString()); 125 | } 126 | 127 | } else { 128 | 129 | for (CharSequence item : itemArray) { 130 | itemMap.put(item.toString(), item.toString()); 131 | } 132 | 133 | } 134 | 135 | } 136 | 137 | } finally { 138 | attributes.recycle(); 139 | } 140 | 141 | //Setup the view 142 | update(); 143 | } 144 | 145 | private void init(Context context) { 146 | mCtx = context; 147 | //Needed for calling the right "setbackground" method 148 | mSdk = android.os.Build.VERSION.SDK_INT; 149 | //Provide a tad bit of padding for the view 150 | this.setPadding(10, 10, 10, 10); 151 | } 152 | 153 | /** 154 | * Does the setup and re-setup of the view based on the currently set options 155 | */ 156 | @TargetApi(16) 157 | private void update() { 158 | 159 | //Remove all views... 160 | this.removeAllViews(); 161 | 162 | //Get size of two DP (size of stroke) 163 | int twoDP = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics()); 164 | 165 | //Ensure orientation is horizontal 166 | this.setOrientation(RadioGroup.HORIZONTAL); 167 | 168 | 169 | 170 | 171 | float textWidth = 0; 172 | options = new ArrayList(); 173 | 174 | Iterator itemIterator = itemMap.entrySet().iterator(); 175 | int i = 0; 176 | while (itemIterator.hasNext()) { 177 | 178 | Map.Entry item = (Map.Entry) itemIterator.next(); 179 | RadioButton rb = new RadioButton(mCtx); 180 | rb.setTextColor(textColorStateList); 181 | LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); 182 | if (stretch) { 183 | params.weight = 1.0f; 184 | } 185 | if (i > 0) { 186 | params.setMargins(-twoDP, 0, 0, 0); 187 | } 188 | 189 | rb.setLayoutParams(params); 190 | 191 | 192 | //Clear out button drawable (text only) 193 | rb.setButtonDrawable(new StateListDrawable()); 194 | 195 | //Create state list for background 196 | if (i == 0) { 197 | //Left 198 | GradientDrawable leftUnselected = (GradientDrawable) mCtx.getResources().getDrawable(R.drawable.left_option).mutate(); 199 | leftUnselected.setStroke(twoDP, selectedColor); 200 | 201 | leftUnselected.setColor(unselectedColor); 202 | GradientDrawable leftSelected = (GradientDrawable) mCtx.getResources().getDrawable(R.drawable.left_option_selected).mutate(); 203 | leftSelected.setColor(selectedColor); 204 | leftSelected.setStroke(twoDP, selectedColor); 205 | 206 | StateListDrawable leftStateListDrawable = new StateListDrawable(); 207 | leftStateListDrawable.addState(new int[]{-android.R.attr.state_checked}, leftUnselected); 208 | leftStateListDrawable.addState(new int[]{android.R.attr.state_checked}, leftSelected); 209 | if (mSdk < Build.VERSION_CODES.JELLY_BEAN) { 210 | rb.setBackgroundDrawable(leftStateListDrawable); 211 | } else { 212 | rb.setBackground(leftStateListDrawable); 213 | } 214 | 215 | 216 | } else if (i == (itemMap.size() - 1)) { 217 | //Right 218 | GradientDrawable rightUnselected = (GradientDrawable) mCtx.getResources().getDrawable(R.drawable.right_option).mutate(); 219 | rightUnselected.setStroke(twoDP, selectedColor); 220 | 221 | rightUnselected.setColor(unselectedColor); 222 | GradientDrawable rightSelected = (GradientDrawable) mCtx.getResources().getDrawable(R.drawable.right_option_selected).mutate(); 223 | rightSelected.setColor(selectedColor); 224 | rightSelected.setStroke(twoDP, selectedColor); 225 | 226 | StateListDrawable rightStateListDrawable = new StateListDrawable(); 227 | rightStateListDrawable.addState(new int[]{-android.R.attr.state_checked}, rightUnselected); 228 | rightStateListDrawable.addState(new int[]{android.R.attr.state_checked}, rightSelected); 229 | if (mSdk < Build.VERSION_CODES.JELLY_BEAN) { 230 | rb.setBackgroundDrawable(rightStateListDrawable); 231 | } else { 232 | rb.setBackground(rightStateListDrawable); 233 | } 234 | 235 | } else { 236 | //Middle 237 | GradientDrawable middleUnselected = (GradientDrawable) mCtx.getResources().getDrawable(R.drawable.middle_option).mutate(); 238 | middleUnselected.setStroke(twoDP, selectedColor); 239 | middleUnselected.setDither(true); 240 | middleUnselected.setColor(unselectedColor); 241 | GradientDrawable middleSelected = (GradientDrawable) mCtx.getResources().getDrawable(R.drawable.middle_option_selected).mutate(); 242 | middleSelected.setColor(selectedColor); 243 | middleSelected.setStroke(twoDP, selectedColor); 244 | 245 | StateListDrawable middleStateListDrawable = new StateListDrawable(); 246 | middleStateListDrawable.addState(new int[]{-android.R.attr.state_checked}, middleUnselected); 247 | middleStateListDrawable.addState(new int[]{android.R.attr.state_checked}, middleSelected); 248 | if (mSdk < Build.VERSION_CODES.JELLY_BEAN) { 249 | rb.setBackgroundDrawable(middleStateListDrawable); 250 | } else { 251 | rb.setBackground(middleStateListDrawable); 252 | } 253 | 254 | } 255 | 256 | rb.setLayoutParams(params); 257 | rb.setMinWidth(twoDP * 10); 258 | rb.setGravity(Gravity.CENTER); 259 | rb.setTypeface(null, Typeface.BOLD); 260 | rb.setText(item.getKey()); 261 | textWidth = Math.max(rb.getPaint().measureText(item.getKey()), textWidth); 262 | options.add(rb); 263 | 264 | i++; 265 | } 266 | 267 | //We do this to make all the segments the same width 268 | for (RadioButton option : options) { 269 | if (equalWidth) { 270 | option.setWidth((int) (textWidth + (twoDP * 20))); 271 | } 272 | this.addView(option); 273 | } 274 | 275 | this.setOnCheckedChangeListener(selectionChangedlistener); 276 | 277 | if (defaultSelection > -1) { 278 | this.check(((RadioButton) getChildAt(defaultSelection)).getId()); 279 | } 280 | } 281 | 282 | /** 283 | * Get currently selected segment and the view identifier 284 | * 285 | * @return string array of identifier [0] value of currently selected segment [1] 286 | */ 287 | public String[] getCheckedWithIdentifier() { 288 | return new String[]{identifier, itemMap.get(((RadioButton) this.findViewById(this.getCheckedRadioButtonId())).getText().toString())}; 289 | } 290 | 291 | /** 292 | * Get currently selected segment 293 | * 294 | * @return value of currently selected segment 295 | */ 296 | public String getChecked() { 297 | return itemMap.get(((RadioButton) this.findViewById(this.getCheckedRadioButtonId())).getText().toString()); 298 | } 299 | 300 | /** 301 | * Used to pass along the selection change event 302 | * Calls onSelectionChangedListener with identifier and value of selected segment 303 | */ 304 | private OnCheckedChangeListener selectionChangedlistener = new OnCheckedChangeListener() { 305 | @Override 306 | public void onCheckedChanged(RadioGroup group, int checkedId) { 307 | if (mListener != null) { 308 | mListener.newSelection(identifier, itemMap.get(((RadioButton) group.findViewById(checkedId)).getText().toString())); 309 | } 310 | 311 | } 312 | }; 313 | 314 | /** 315 | * Interface for for the selection change event 316 | */ 317 | public interface OnSelectionChangedListener { 318 | public void newSelection(String identifier, String value); 319 | } 320 | 321 | /** 322 | * Sets the items and vaules for each segements. 323 | * 324 | * @param itemArray 325 | * @param valueArray 326 | * @throws Exception 327 | */ 328 | public void setItems(String[] itemArray, String[] valueArray) throws Exception { 329 | 330 | itemMap.clear(); 331 | 332 | if (itemArray != null && valueArray != null) { 333 | if (itemArray.length != valueArray.length) { 334 | throw new Exception("Item labels and value arrays must be the same size"); 335 | } 336 | } 337 | 338 | if (itemArray != null) { 339 | 340 | if (valueArray != null) { 341 | for (int i = 0; i < itemArray.length; i++) { 342 | itemMap.put(itemArray[i].toString(), valueArray[i].toString()); 343 | } 344 | 345 | } else { 346 | 347 | for (CharSequence item : itemArray) { 348 | itemMap.put(item.toString(), item.toString()); 349 | } 350 | 351 | } 352 | 353 | 354 | } 355 | 356 | update(); 357 | } 358 | 359 | /** 360 | * Sets the items and vaules for each segements. Also provides a helper to setting the 361 | * default selection 362 | * 363 | * @param items 364 | * @param values 365 | * @param defaultSelection 366 | * @throws Exception 367 | */ 368 | public void setItems(String[] items, String[] values, int defaultSelection) throws Exception { 369 | 370 | if (defaultSelection > (items.length - 1)) { 371 | throw new Exception("Default selection cannot be greater than the number of items"); 372 | } else { 373 | this.defaultSelection = defaultSelection; 374 | setItems(items, values); 375 | } 376 | } 377 | 378 | /** 379 | * Sets the item that is selected by default. Must be greater than -1. 380 | * 381 | * @param defaultSelection 382 | * @throws Exception 383 | */ 384 | public void setDefaultSelection(int defaultSelection) throws Exception { 385 | if (defaultSelection > (itemMap.size() - 1)) { 386 | throw new Exception("Default selection cannot be greater than the number of items"); 387 | } else { 388 | this.defaultSelection = defaultSelection; 389 | update(); 390 | } 391 | } 392 | 393 | /** 394 | * Sets the colors used when drawing the view. The primary color will be used for selected color 395 | * and unselected text color, while the secondary color will be used for unselected color 396 | * and selected text color. 397 | * 398 | * @param primaryColor 399 | * @param secondaryColor 400 | */ 401 | public void setColors(int primaryColor, int secondaryColor) { 402 | this.selectedColor = primaryColor; 403 | this.selectedTextColor = secondaryColor; 404 | this.unselectedColor = secondaryColor; 405 | this.unselectedTextColor = primaryColor; 406 | 407 | //Set text selectedColor state list 408 | textColorStateList = new ColorStateList(new int[][]{ 409 | {-android.R.attr.state_checked}, {android.R.attr.state_checked}}, 410 | new int[]{unselectedTextColor, selectedTextColor} 411 | ); 412 | 413 | update(); 414 | } 415 | 416 | /** 417 | * Sets the colors used when drawing the view 418 | * 419 | * @param selectedColor 420 | * @param selectedTextColor 421 | * @param unselectedColor 422 | * @param unselectedTextColor 423 | */ 424 | public void setColors(int selectedColor, int selectedTextColor, int unselectedColor, int unselectedTextColor) { 425 | this.selectedColor = selectedColor; 426 | this.selectedTextColor = selectedTextColor; 427 | this.unselectedColor = unselectedColor; 428 | this.unselectedTextColor = unselectedTextColor; 429 | 430 | //Set text selectedColor state list 431 | textColorStateList = new ColorStateList(new int[][]{ 432 | {-android.R.attr.state_checked}, {android.R.attr.state_checked}}, 433 | new int[]{unselectedTextColor, selectedTextColor} 434 | ); 435 | 436 | update(); 437 | } 438 | 439 | /** 440 | * Used to set the selected value based on the value (not the visible text) provided in the 441 | * value array provided via xml or code 442 | * 443 | * @param value 444 | */ 445 | public void setByValue(String value) { 446 | String buttonText = ""; 447 | if (this.itemMap.containsValue(value)) { 448 | for (String entry : itemMap.keySet()) { 449 | if (itemMap.get(entry).equalsIgnoreCase(value)) { 450 | buttonText = entry; 451 | } 452 | } 453 | } 454 | 455 | for (RadioButton option : options) { 456 | if (option.getText().toString().equalsIgnoreCase(buttonText)) { 457 | this.check(option.getId()); 458 | } 459 | } 460 | 461 | } 462 | 463 | /** 464 | * Sets the mListener that gets called when a selection is changed 465 | * 466 | * @param listener 467 | */ 468 | public void setOnSelectionChangedListener(OnSelectionChangedListener listener) { 469 | this.mListener = listener; 470 | } 471 | 472 | /** 473 | * For use with multiple views. This identifier will be provided in the 474 | * onSelectionChanged mListener 475 | * 476 | * @param identifier 477 | */ 478 | public void setIdentifier(String identifier) { 479 | this.identifier = identifier; 480 | } 481 | 482 | /** 483 | * Set to true if you want each segment to be equal width 484 | * 485 | * @param equalWidth 486 | */ 487 | public void setEqualWidth(boolean equalWidth) { 488 | this.equalWidth = equalWidth; 489 | update(); 490 | } 491 | 492 | /** 493 | * Set to true if the view should be stretched to fill it's parent view 494 | * 495 | * @param stretch 496 | */ 497 | public void setStretch(boolean stretch) { 498 | this.stretch = stretch; 499 | update(); 500 | } 501 | 502 | } 503 | -------------------------------------------------------------------------------- /lib/src/main/res/drawable/left_option.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 21 | 24 | 25 | 30 | 33 | -------------------------------------------------------------------------------- /lib/src/main/res/drawable/left_option_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 21 | 24 | 25 | 30 | 33 | -------------------------------------------------------------------------------- /lib/src/main/res/drawable/middle_option.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 21 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /lib/src/main/res/drawable/middle_option_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 21 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /lib/src/main/res/drawable/right_option.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 21 | 24 | 25 | 30 | 33 | -------------------------------------------------------------------------------- /lib/src/main/res/drawable/right_option_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 21 | 24 | 25 | 30 | 33 | -------------------------------------------------------------------------------- /lib/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /lib/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | #0099CC 20 | #FFFFFF 21 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTICE 3 | * 4 | * This is the copyright work of The MITRE Corporation, and was produced for 5 | * the U. S. Government under Contract Number DTFAWA-10-C-00080, and is subject 6 | * to Federal Aviation Administration Acquisition Management System Clause 7 | * 3.5-13, Rights In Data-General, Alt. III and Alt. IV (Oct. 1996). No other 8 | * use other than that granted to the U. S. Government, or to those acting on 9 | * behalf of the U. S. Government, under that Clause is authorized without the 10 | * express written permission of The MITRE Corporation. For further information, 11 | * please contact The MITRE Corporation, Contracts Office,7515 Colshire Drive, 12 | * McLean, VA 22102-7539, (703) 983-6000. 13 | * 14 | * Approved for Public Release; Distribution Unlimited. Case Number 14-4045 15 | */ 16 | 17 | include ':lib', ':ascvexample' 18 | --------------------------------------------------------------------------------