{"id":15040888,"url":"https://github.com/bryanx/themed-toggle-button-group","last_synced_at":"2025-04-12T23:40:47.840Z","repository":{"id":37265376,"uuid":"244230033","full_name":"Bryanx/themed-toggle-button-group","owner":"Bryanx","description":"Customisable toggle buttons inside a FlexboxLayout.","archived":false,"fork":false,"pushed_at":"2022-01-29T09:58:33.000Z","size":6353,"stargazers_count":748,"open_issues_count":11,"forks_count":47,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-12T23:40:05.143Z","etag":null,"topics":["android","android-development","android-library","android-ui","kotlin","kotlin-android","kotlin-library","toggle-button-group","toggle-buttons"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Bryanx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-01T21:57:20.000Z","updated_at":"2025-01-23T18:28:40.000Z","dependencies_parsed_at":"2022-08-08T19:30:59.725Z","dependency_job_id":null,"html_url":"https://github.com/Bryanx/themed-toggle-button-group","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bryanx%2Fthemed-toggle-button-group","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bryanx%2Fthemed-toggle-button-group/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bryanx%2Fthemed-toggle-button-group/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bryanx%2Fthemed-toggle-button-group/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Bryanx","download_url":"https://codeload.github.com/Bryanx/themed-toggle-button-group/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647254,"owners_count":21139081,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-development","android-library","android-ui","kotlin","kotlin-android","kotlin-library","toggle-button-group","toggle-buttons"],"created_at":"2024-09-24T20:45:14.448Z","updated_at":"2025-04-12T23:40:47.818Z","avatar_url":"https://github.com/Bryanx.png","language":"Kotlin","readme":"# ThemedToggleButtonGroup\n![CI](https://github.com/Bryanx/themed-toggle-button-group/workflows/CI/badge.svg)\n![API](https://img.shields.io/static/v1?label=API\u0026message=14%2B\u0026color=blue)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) \n[![Maven Central](https://img.shields.io/maven-central/v/nl.bryanderidder/themed-toggle-button-group.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22nl.bryanderidder%22%20AND%20a:%22themed-toggle-button-group%22)\n\nCustomisable toggle buttons inside a [FlexboxLayout](https://github.com/google/flexbox-layout).\n\nThemedToggleButtonGroup is a highly modular lightweight toggle button library for Android. It can be configured for single selection or multi selection. For multi selection the minimum/maximum amount of buttons that are required/enabled can be specified. Icon's can be added. Selection includes a fun press and circular reveal animation.\n\nThe main class [ThemedToggleButtonGroup.kt](https://github.com/Bryanx/themed-toggle-button-group/blob/master/library/src/main/java/nl/bryanderidder/themedtogglebuttongroup/ThemedToggleButtonGroup.kt) extends Google's [FlexboxLayout](https://github.com/google/flexbox-layout). Allowing you to use styling similar to [CSS Flexbox](https://www.w3schools.com/css/css3_flexbox.asp) for the button's inside the toggle group.\n\n## Notice\nAs of version 1.3.2 hosting will be moved from Bintray to MavenCentral. I will move all versions to mavenCentral, but to be safe please use the latest version of this library.\n\n## Installation\nAdd the dependency in your app's `build.gradle` file:\n```groovy\ndependencies {\n  implementation 'nl.bryanderidder:themed-toggle-button-group:1.4.1'\n}\n```\nFor Java projects you also have to add `implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.6.0'`\n\n## Single selection\n![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/basic.gif)\n```xml\n\u003cnl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup\n    android:id=\"@+id/time\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    app:justifyContent=\"center\"\u003e \u003c!-- this attribute is from the underlying FlexboxLayout --\u003e\n\n      \u003cnl.bryanderidder.themedtogglebuttongroup.ThemedButton\n          android:id=\"@+id/btn1\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"38dp\"\n          app:toggle_text=\"5:30PM\" /\u003e\n\n      \u003cnl.bryanderidder.themedtogglebuttongroup.ThemedButton\n          android:id=\"@+id/btn2\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"38dp\"\n          app:toggle_text=\"7:30PM\" /\u003e\n\n      \u003cnl.bryanderidder.themedtogglebuttongroup.ThemedButton\n          android:id=\"@+id/btn3\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"38dp\"\n          app:toggle_text=\"8:00PM\" /\u003e\n\n\u003c/nl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup\u003e\n```\n\n## Multiple selection\n![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/labels.gif) \\\nDeclare how many buttons **may** be selected with `toggle_selectableAmount`. \\\nDeclare how many buttons **must** be selected with `toggle_requiredAmount`.\n```xml\n\u003cnl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup\n    android:id=\"@+id/tags\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    app:toggle_selectableAmount=\"3\"\n    app:justifyContent=\"space_between\"\n    app:flexWrap=\"wrap\"\u003e\n\n    \u003cnl.bryanderidder.themedtogglebuttongroup.ThemedButton\n        android:id=\"@+id/tag1\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"30dp\"\n        android:layout_margin=\"3dp\"\n        app:toggle_text=\"social\" /\u003e\n\n    \u003cnl.bryanderidder.themedtogglebuttongroup.ThemedButton\n        android:id=\"@+id/tag2\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"30dp\"\n        android:layout_margin=\"3dp\"\n        app:toggle_text=\"music\" /\u003e\n  \n    \u003c!-- ... --\u003e\n  \n  \u003c/nl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup\u003e\n```\n\n## Animations\nCIRCULAR_REVEAL | FADE | HORIZONTAL_SLIDE\n--- | --- | ---\n![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/circular_reveal.gif) | ![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/fade.gif) | ![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/horizontal_slide.gif)\n\nVERTICAL_SLIDE | HORIZONTAL_WINDOW | VERTICAL_WINDOW\n--- | --- | ---\n![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/vertical_slide.gif) | ![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/horizontal_window.gif) | ![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/vertical_window.gif)\n\nTo set the animation on your layout add this to the toggle group: `app:toggle_selectAnimation=\"circular_reveal\"`.\nYou can also set the animation programmatically:\n\u003cdetails\u003e\n\u003csummary\u003eJava\u003c/summary\u003e\n\u003cp\u003e\n\n```java\nThemedToggleButtonGroup themedToggleButtonGroup = findViewById\u003cThemedToggleButtonGroup\u003e(R.id.themedToggleButtonGroup);\nthemedToggleButtonGroup.setSelectAnimation(SelectAnimation.HORIZONTAL_SLIDE);\n```\n\n\u003c/p\u003e\n\u003c/details\u003e  \n\n```kotlin\nval themedToggleButtonGroup = findViewById\u003cThemedToggleButtonGroup\u003e(R.id.themedToggleButtonGroup)\nthemedToggleButtonGroup.selectAnimation = SelectAnimation.HORIZONTAL_SLIDE\n```\n\n## Icon selection\n![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/icontoggle.gif) \\\nIt is possible to add icons to the buttons and show a different icon when the button is selected. This example also shows how to add borders.\n```xml\n\u003cnl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup\n    android:id=\"@+id/toggleGroup\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"80dp\"\n    app:alignItems=\"center\"\n    app:justifyContent=\"center\"\n    app:toggle_requiredAmount=\"0\"\n    app:toggle_selectableAmount=\"3\"\u003e\n\n    \u003cnl.bryanderidder.themedtogglebuttongroup.ThemedButton\n        android:id=\"@+id/btnMic\"\n        android:layout_width=\"70dp\"\n        android:layout_height=\"70dp\"\n        app:toggle_btnCornerRadius=\"50dp\"\n        app:toggle_borderWidth=\"5dp\"\n        app:toggle_borderColor=\"#C6C6C6\"\n        app:toggle_selectedBorderColor=\"#5e6fed\"\n        app:toggle_icon=\"@drawable/ic_mic_off_black_24dp\"\n        app:toggle_iconColor=\"#C6C6C6\"\n        app:toggle_selectedIcon=\"@drawable/ic_mic_black_24dp\"\n        app:toggle_backgroundColor=\"@android:color/white\"\n        app:toggle_iconPadding=\"18dp\" /\u003e\n\n    \u003c!-- ... --\u003e\n\n\u003c/nl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup\u003e\n```\n\n## Text + icon selection\n![demo](https://raw.githubusercontent.com/Bryanx/themed-toggle-button-group/master/demo-toggle-cards/assets/togg.gif) \\\nA demo for this example can be found here: [demo-toggle-cards](https://github.com/Bryanx/themed-toggle-button-group/tree/master/demo-toggle-cards). You need to use SVG icons to allow the color to be altered. \n```xml\n\u003cnl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup\n    android:id=\"@+id/cards\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"155dp\"\n    android:layout_marginHorizontal=\"32dp\"\n    app:alignItems=\"center\"\u003e\n\n    \u003cnl.bryanderidder.themedtogglebuttongroup.ThemedButton\n        android:id=\"@+id/card1\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"145dp\"\n        app:layout_flexGrow=\"1\"\n        app:toggle_selectedTextColor=\"@android:color/white\"\n        app:toggle_selectedBackgroundColor=\"#5e6fed\"\n        app:toggle_icon=\"@drawable/replace_with_svg_icon\"\n        app:toggle_iconGravity=\"top|center\"\n        app:toggle_iconPaddingTop=\"15dp\"\n        app:toggle_iconPaddingHorizontal=\"15dp\"\n        app:toggle_textPaddingBottom=\"20dp\"\n        app:toggle_text=\"Multiple choice\"\n        app:toggle_textGravity=\"bottom|center\" /\u003e\n\n    \u003c!-- ... --\u003e\n\n\u003c/nl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup\u003e\n```\n\n## Selection listener\nThe easiest way to react to selection changes is to use `group.setOnSelectListener(() -\u003e {})`.\n\u003cdetails\u003e\n\u003csummary\u003eJava\u003c/summary\u003e\n\u003cp\u003e\n\n```java\nThemedToggleButtonGroup themedButtonGroup = findViewById\u003cThemedToggleButtonGroup\u003e(R.id.idOfYourThemedButtonGroup);\nthemedButtonGroup.setOnSelectListener((ThemedButton btn) -\u003e {\n    // handle selected button\n    return kotlin.Unit.INSTANCE;\n});\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n```kotlin\nval themedButtonGroup = findViewById\u003cThemedToggleButtonGroup\u003e(R.id.idOfYourThemedButtonGroup)\nthemedButtonGroup.setOnSelectListener { button: ThemedButton -\u003e\n    // handle selected button\n}\n```\nOnce a button is selected its property `isSelected` will be set to true.\n\u003cdetails\u003e\n\u003csummary\u003eJava\u003c/summary\u003e\n\u003cp\u003e\n\n```java\n// get the selected buttons:\nList\u003cThemedButton\u003e selectedButtons = themedButtonGroup.getSelectedButtons();\n// get all buttons\nList\u003cThemedButton\u003e allButtons = themedButtonGroup.getButtons();\n// get all unselected buttons\nList\u003cThemedButton\u003e unselectedButtons = allButtons.stream().filter(btn -\u003e !btn.isSelected()).collect(Collectors.toList());\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n```kotlin\n// get the selected buttons:\nval selectedButtons = themedButtonGroup.selectedButtons\n// get all buttons\nval allButtons = themedButtonGroup.buttons\n// get all unselected buttons\nval unselectedButtons = allButtons.filter { !it.isSelected }\n```\n\n## Programmatically adding buttons\nA demo project for this can be found here: [programmatically-add-buttons](https://github.com/Bryanx/themed-toggle-button-group/tree/master/demo-programmatically-add-buttons). \\\nProgrammatically create a `ThemedToggleButtonGroup`:\n\u003cdetails\u003e\n\u003csummary\u003eJava\u003c/summary\u003e\n\u003cp\u003e\n\n```java\nThemedToggleButtonGroup buttonGroup = ThemedToggleButtonGroup(context);\nbuttonGroup.setJustifyContent(JustifyContent.CENTER);\nyourRootView.addView(buttonGroup);\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n```kotlin\nval buttonGroup = ThemedToggleButtonGroup(context)\nbuttonGroup.justifyContent = JustifyContent.CENTER\nyourRootView.addView(buttonGroup)\n```\nAdd a button:\n\u003cdetails\u003e\n\u003csummary\u003eJava\u003c/summary\u003e\n\u003cp\u003e\n\n```java\nThemedButton btn1 = ThemedButton(context);\nbtn1.setText(\"Button 1\");\nbuttonGroup.addView(btn1, \n        ViewGroup.LayoutParams(\n            ViewGroup.LayoutParams.WRAP_CONTENT,\n            ViewGroup.LayoutParams.MATCH_PARENT\n        )\n    );\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n```kotlin\nval btn1 = ThemedButton(context)\nbtn1.text = \"Button 1\"\nbuttonGroup.addView(btn1, \n        ViewGroup.LayoutParams(\n            ViewGroup.LayoutParams.WRAP_CONTENT,\n            ViewGroup.LayoutParams.MATCH_PARENT\n        )\n    )\n```\nSelect/deselect a button programmatically:\nYou can pass in the `ThemedButton` itself or its resId. This will toggle selection. Fire the method a second time to deselect the button.\n```kotlin\nbuttonGroup.selectButtonWithAnimation(btn)\nbuttonGroup.selectButton(btn)\n```\nEnabling/disabling buttons:\n\u003cdetails\u003e\n\u003csummary\u003eJava\u003c/summary\u003e\n\u003cp\u003e\n\n```java\nbtn.setEnabled(false);\n// this will fail:\nbuttonGroup.selectButton(btn);\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n```kotlin\nbtn.isEnabled = false\n// this will fail:\nbuttonGroup.selectButton(btn)\n```\n\n# Customization\nThese lists include all custom attributes from this library. Please take a look [FlexboxLayout](https://github.com/google/flexbox-layout) to see all custom attributes that can also be applied to these Views.\n## ThemedToggleButtonGroup custom attributes\nAttribute | Default value | Description\n--- | --- | ---\n`app:toggle_selectableAmount` | 1 | The amount of buttons that are allowed to be selected. If the user tries to select more buttons, the button that was last selected will be deselected.\n`app:toggle_requiredAmount` | 1 | The amount of buttons that are required to be selected. If the user tries to deselect a button below the required amount, the selection is blocked. You can programmatically specify which buttons should be selected initially by setting `ThemedButton.isSelected`. Otherwise a random button will be selected initially.\n`app:toggle_horizontalSpacing` | 10dp | The amount of space between the buttons when they are positioned next to each other.\n`app:toggle_selectAnimation` | SelectAnimation.CIRCULAR_REVEAL | The type of animations that occur upon selecting a button. Some animations require a certain API level. If the API level is not met SelectAnimation.FADE is used instead.\n\n## ThemedButton custom attributes\n![Color_customisation](https://github.com/Bryanx/themed-toggle-button-group/blob/master/demo-toggle-cards/assets/dark.gif?raw=true) \\\nYou can fully customise colors, positioning, font size, etc. with these attributes.\n\nAttribute | Default value | Description\n--- | --- | ---\n`app:toggle_text` | Empty string | Text of the button.\n`app:toggle_selectedText` | `app:toggle_text` | Text when the button is selected. If not present the text of `toggle_text` is used.\n`app:toggle_textSize` | 15sp | Size of the text in the button.\n`app:toggle_textAlignment` | center | Alignment of the text. (API 17+)\n`app:toggle_fontFamily` | Roboto (Android default) | The font of the text. Put your font file in `/src/main/assets`. And enter the the rest of the path here. For example if your font is in: `/src/main/assets/fonts/arial.ttf` enter this in your layout: `app:toggle_fontFamily=\"/fonts/arial.ttf\"`\n`app:toggle_backgroundColor` | ![#EBEBEB](https://placehold.it/15/EBEBEB/000000?text=+) `#EBEBEB` | Background color when the button is not selected.\n`app:toggle_selectedBackgroundColor` | ![#5E6FED](https://placehold.it/15/5E6FED/000000?text=+) `#5E6FED` | Background color when the button is selected.\n`app:toggle_textColor` | ![#5E5E5E](https://placehold.it/15/5E5E5E/000000?text=+) `#5E5E5E` | Text color when the button is not selected. This also sets the color of the icon if it is not set.\n`app:toggle_selectedTextColor` | ![#FFFFFF](https://placehold.it/15/FFFFFF/000000?text=+) `#FFFFFF` |  Text color when the button is selected. This also sets the color of the selected icon if it is not set.\n`app:toggle_icon` | null | Optional icon inside the button.\n`app:toggle_selectedIcon` | `app:toggle_icon` | Icon when the button is selected. By default the icon of `app:toggle_icon` is used.\n`app:toggle_iconColor` | ![#5E5E5E](https://placehold.it/15/5E5E5E/000000?text=+) `#5E5E5E` | Color of the icon when the button is not selected.\n`app:toggle_btnCornerRadius` | 21dp | Curve amount of the button's corners.\n`app:toggle_circularCornerRadius` | false | This makes the button circular. This overrides the corner radius.\n`app:toggle_borderWidth` | 0dp | The width of the border.\n`app:toggle_selectedBorderWidth` | `app:toggle_borderWidth` | The width of the border when the button is selected. By default the width of `toggle_borderWidth` is used.\n`app:toggle_borderColor` | ![#5E5E5E](https://placehold.it/15/5E5E5E/000000?text=+) `#5E5E5E` | The color of the border.\n`app:toggle_selectedBorderColor` | `app:toggle_borderColor` | The color of the border when the button is selected.. By default the color of `app:toggle_borderColor` is used.\n`app:toggle_padding` | 0dp | Padding of the button.\n`app:toggle_textPadding` | 14dp (horizontal) | Padding of the text.\n`app:toggle_iconPadding` | 0dp | Padding of the icon.\n`app:toggle_iconGravity` | top\\|start | Position of the icon.\n`app:toggle_textGravity` | top\\|start | Position of the text.\n\n## Contributing\nYou can contribute by [opening an issue](https://github.com/Bryanx/themed-toggle-button-group/issues) or forking this repository and creating a pull request.\n\n## License\n[License of this library](https://github.com/Bryanx/themed-toggle-button-group/blob/master/LICENSE)\\\n[License of FlexboxLayout](https://github.com/google/flexbox-layout/blob/master/LICENSE)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbryanx%2Fthemed-toggle-button-group","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbryanx%2Fthemed-toggle-button-group","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbryanx%2Fthemed-toggle-button-group/lists"}