{"id":15032086,"url":"https://github.com/duanhong169/drawabletoolbox","last_synced_at":"2025-04-13T06:22:54.155Z","repository":{"id":45469610,"uuid":"143123260","full_name":"duanhong169/DrawableToolbox","owner":"duanhong169","description":"🛠️ The missing drawable toolbox for Android. Create drawables programmatically and get rid of the boring and always repeated drawable.xml files.","archived":false,"fork":false,"pushed_at":"2020-05-20T10:55:31.000Z","size":5297,"stargazers_count":1147,"open_issues_count":11,"forks_count":99,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-04-04T05:05:47.440Z","etag":null,"topics":["android","android-drawables","android-library","flip-drawable","gradient-drawable","kotlin","kotlin-android","kotlin-library","layer-drawable","layer-list","programmatically","rotate-drawable","scale-drawable","shape-drawable","state-list-drawable"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/duanhong169.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":"2018-08-01T07:57:06.000Z","updated_at":"2025-03-17T03:23:59.000Z","dependencies_parsed_at":"2022-07-14T21:16:51.740Z","dependency_job_id":null,"html_url":"https://github.com/duanhong169/DrawableToolbox","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duanhong169%2FDrawableToolbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duanhong169%2FDrawableToolbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duanhong169%2FDrawableToolbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duanhong169%2FDrawableToolbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/duanhong169","download_url":"https://codeload.github.com/duanhong169/DrawableToolbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247123103,"owners_count":20887261,"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-drawables","android-library","flip-drawable","gradient-drawable","kotlin","kotlin-android","kotlin-library","layer-drawable","layer-list","programmatically","rotate-drawable","scale-drawable","shape-drawable","state-list-drawable"],"created_at":"2024-09-24T20:17:17.045Z","updated_at":"2025-04-04T05:06:14.293Z","avatar_url":"https://github.com/duanhong169.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DrawableToolbox\n[![gitHub release](https://img.shields.io/github/release/duanhong169/DrawableToolbox.svg?style=social)](https://github.com/duanhong169/DrawableToolbox/releases)\n[![platform](https://img.shields.io/badge/platform-android-brightgreen.svg)](https://developer.android.com/index.html)\n\u003ca target=\"_blank\" href=\"https://android-arsenal.com/api?level=14\"\u003e\u003cimg src=\"https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat\"\u003e\u003c/a\u003e\n[![license](https://img.shields.io/badge/license-Apache%202-green.svg)](https://github.com/duanhong169/DrawableToolbox/blob/master/LICENSE)\n[![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin)\n\nEnglish | [中文](README_cn.md)\n\nThe missing DrawableToolbox for Android. Create drawables programmatically and get rid of the boring and always repeated `drawable.xml` files.\n\n\u003cimg src='art/screen-shot-1.jpg' height='500px'/\u003e \u003cimg src='art/screen-video-1.gif' height='500px'/\u003e \u003cbr/\u003e\n\u003cimg src='art/screen-shot-2.jpg' height='500px'/\u003e \u003cimg src='art/screen-video-2.gif' height='500px'/\u003e\n\n## Features\n\n* Create drawables programmatically\n* Support `\u003cshape\u003e`, `\u003crotate\u003e`, `\u003cscale\u003e`, `\u003cripple\u003e`, `\u003clayer-list\u003e` drawables\n* Support 'flip' (vertical or horizontal)\n\n## Contribute\n\n* Please file an [issue](https://github.com/duanhong169/DrawableToolbox/issues) or [pull request](https://github.com/duanhong169/DrawableToolbox/pulls) \n\n## Gradle\n\n```\ndependencies {\n    implementation 'com.github.duanhong169:drawabletoolbox:${latestVersion}'\n    ...\n}\n```\n\n\u003e Replace `${latestVersion}` with the latest version code. See [releases](https://github.com/duanhong169/DrawableToolbox/releases).\n\n## Usage\n\nUse the `DrawableBuilder` to setup the `Drawable` and call `build()` to create it. \n\n\u003e Please check all the supported APIs in [DrawableBuilder.kt](https://github.com/duanhong169/DrawableToolbox/blob/master/drawabletoolbox/src/main/java/top/defaults/drawabletoolbox/DrawableBuilder.kt).\n\nHere are some examples:\n\nCode:\n\n```kotlin\nDrawableBuilder()\n        .rectangle()\n        .hairlineBordered()\n        .strokeColor(COLOR_DEFAULT)\n        .strokeColorPressed(COLOR_PRESSED)\n        .ripple()\n        .build()\n```\n\nResult:\n\n![Bordered with Ripple](art/sample-1.png)\n\nCode:\n\n```kotlin\nDrawableBuilder()\n        .rectangle()\n        .hairlineBordered()\n        .mediumDashed()\n        .strokeColor(COLOR_DEFAULT)\n        .strokeColorPressed(COLOR_PRESSED)\n        .ripple()\n        .build()\n```\n\nResult:\n\n![Medium-dashed, Bordered with Ripple](art/sample-2.png)\n\nCode:\n\n```kotlin\nDrawableBuilder()\n        .rectangle()\n        .rounded()\n        .solidColor(COLOR_DEFAULT)\n        .solidColorPressed(COLOR_PRESSED)\n        .build()\n```\n\nResult:\n\n![Rounded, Filled with States](art/sample-4.png)\n\nCode:\n\n```kotlin\nDrawableBuilder()\n        .rectangle()\n        .hairlineBordered()\n        .longDashed()\n        .rounded()\n        .strokeColor(COLOR_DEFAULT)\n        .strokeColorPressed(COLOR_PRESSED)\n        .ripple()\n        .build()\n```\n\nResult:\n\n![Rounded, Long-dashed, Bordered with Ripple](art/sample-6.png)\n\nCode:\n\n```kotlin\nDrawableBuilder()\n        .rectangle()\n        .rounded()\n        .gradient()\n        .linearGradient()\n        .angle(90)\n        .startColor(COLOR_DEFAULT)\n        .endColor(ContextCompat.getColor(context, R.color.colorPrimaryDark))\n        .ripple()\n        .rippleColor(COLOR_PRESSED)\n        .build()\n```\n\nResult:\n\n![Rounded, Gradient with Ripple](art/sample-8.png)\n\nCode:\n\n```kotlin\nval baseBuilder = DrawableBuilder()\n        .rectangle()\n        .rounded()\n        .gradient()\n        .gradientType(GradientDrawable.LINEAR_GRADIENT)\n        .angle(90)\nval normalState = baseBuilder\n        .startColor(COLOR_DEFAULT)\n        .endColor(ContextCompat.getColor(context, R.color.colorPrimaryDark))\n        .build()\nval pressedState = baseBuilder\n        .startColor(COLOR_PRESSED)\n        .endColor(ContextCompat.getColor(context, R.color.colorAccentDark))\n        .build()\n\nStateListDrawableBuilder()\n        .normal(normalState)\n        .pressed(pressedState)\n        .build()\n```\n\nResult:\n\n![Rounded, Gradient with States](art/sample-9.png)\n\nCode:\n\n```kotlin\nval baseBuilder = DrawableBuilder()\n        .rectangle()\n        .rounded()\n        .hairlineBordered()\n        .strokeColor(COLOR_DEFAULT)\n        .solidColorSelected(COLOR_DEFAULT)\n        .ripple()\n\nreturn when(type) {\n    SegmentedControlDrawableSpec.TYPE_LEFT_MOST -\u003e {\n        baseBuilder.topRightRadius(0)\n                .bottomRightRadius(0)\n                .build()\n    }\n    SegmentedControlDrawableSpec.TYPE_RIGHT_MOST -\u003e {\n        baseBuilder.topLeftRadius(0)\n                .bottomLeftRadius(0)\n                .build()\n    }\n    else -\u003e {\n        baseBuilder.cornerRadius(0).build()\n    }\n}\n```\n\nResult:\n\n![Segmented Control](art/sample-10.png)\n\nCode:\n\n```kotlin\nval layer1 = DrawableBuilder()\n        .size(200)\n        .rectangle()\n        .rounded()\n        .hairlineBordered()\n        .strokeColor(COLOR_DEFAULT)\n        .strokeColorPressed(COLOR_PRESSED)\n        .build()\nval layer2 = DrawableBuilder()\n        .rectangle()\n        .rounded()\n        .solidColor(COLOR_DEFAULT)\n        .build()\nval layer3 = DrawableBuilder()\n        .rectangle()\n        .rounded()\n        .solidColor(Color.WHITE)\n        .ripple()\n        .rippleColor(COLOR_DEFAULT)\n        .build()\nLayerDrawableBuilder()\n        .add(layer1)\n        .add(layer2)\n        .inset(10)\n        .add(layer3)\n        .inset(20)\n        .build()\n```\n\nResult:\n\n![Layer List: Several Borders](art/sample-14.png)\n\nCode:\n\n```kotlin\nval layer1 = DrawableBuilder()\n        .size(180)\n        .rectangle()\n        .build()\nval layer2 = DrawableBuilder()\n        .oval()\n        .solidColor(COLOR_DEFAULT)\n        .build()\nval layer3 = DrawableBuilder()\n        .rectangle()\n        .solidColor(COLOR_DEFAULT_DARK)\n        .rotate(45f)\n        .build()\nval layer4 = DrawableBuilder()\n        .rectangle()\n        .bottomLeftRadius(100)\n        .solidColor(COLOR_DEFAULT_DARK)\n        .build()\nval layer5 = DrawableBuilder()\n        .oval()\n        .solidColor(COLOR_DEFAULT)\n        .build()\nval layerDrawable = LayerDrawableBuilder()\n        .add(layer1)\n        .add(layer2)\n        .inset(20, 20, 100, 100)\n        .add(layer3)\n        .inset(100, 20, 20, 100)\n        .add(layer4)\n        .inset(20, 100, 100, 20)\n        .add(layer5)\n        .inset(100, 100, 20, 20)\n        .build()\nDrawableBuilder()\n        .baseDrawable(layerDrawable)\n        .rotate(0f, 360f)\n        .build()\n```\n\nResult:\n\n![Showcase: Layer List 1](art/sample-15.png)\n\n\nCode:\n\n```kotlin\n// Rotate \u0026 Leveled the Ring\nDrawableBuilder()\n        .size(200)\n        .ring()\n        .useLevelForRing()\n        .solidColor(COLOR_DEFAULT)\n        .innerRadiusRatio(3f)\n        .thicknessRatio(10f)\n        .rotate(0f, 720f)\n        .build()\n```\n\nResult:\n\n![Rotate \u0026 Leveled the Ring](art/sample-11.png)\n\nCode:\n\n```kotlin\n// Rotate, Sweep \u0026 Flip the Ring\nDrawableBuilder()\n        .size(200)\n        .ring()\n        .innerRadiusRatio(3f)\n        .thicknessRatio(10f)\n        .gradient()\n        .sweepGradient()\n        .rotate(0f, 360f)\n        .flip()\n        .build()\n```\n\nResult:\n\n![Rotate, Sweep \u0026 Flip the Ring](art/sample-12.png)\n\nCode:\n\n```kotlin\n// Rotate, Sweep \u0026 Scale the Oval with States\nval baseBuilder = DrawableBuilder()\n        .size(400)\n        .oval()\n        .gradient()\n        .sweepGradient()\n        .rotate(0f, 360f)\n        .scale(0.5f)\n        .scaleGravity(Gravity.START or Gravity.TOP)\nval normalState = baseBuilder.build()\nval pressedState = baseBuilder\n        .startColor(COLOR_PRESSED)\n        .endColor(0x7FFFFFFF)\n        .build()\nStateListDrawableBuilder()\n        .normal(normalState)\n        .pressed(pressedState)\n        .build()\n```\n\nResult:\n\n![Rotate, Sweep \u0026 Scale the Oval with States](art/sample-13.png)\n\nPlease check out the app sample code [SampleCodeSnippets.kt](https://github.com/duanhong169/DrawableToolbox/blob/master/app/src/main/java/top/defaults/drawabletoolboxapp/SampleCodeSnippets.kt) for more details.\n\n## License\n\n    Copyright 2018 Hong Duan\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n        http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduanhong169%2Fdrawabletoolbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduanhong169%2Fdrawabletoolbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduanhong169%2Fdrawabletoolbox/lists"}