├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md ├── ci-reporter.yml ├── labels.json ├── no-response.yml └── stale.yml ├── .gitignore ├── .idea ├── checkstyle-idea.xml ├── codeStyleSettings.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── copyright │ ├── Apache_2_0.xml │ └── profiles_settings.xml └── detekt.xml ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── RELEASING.md ├── art ├── banner.png ├── demo_1.gif ├── playstore_getiton.png ├── project.dot.png ├── screenshot_api_16.png ├── screenshot_api_27.png ├── screenshot_api_27_bottom_fab_left_expansion.png ├── screenshot_api_27_top_fab_bottom_expansion.png └── web_hi_res_512.png ├── build-conventions ├── build.gradle ├── settings.gradle └── src │ └── main │ └── groovy │ ├── speeddial.android-conventions.gradle │ ├── speeddial.android-library-conventions.gradle │ ├── speeddial.android-sample-conventions.gradle │ ├── speeddial.artifact-publish-library-conventions.gradle │ ├── speeddial.artifact-publish-root-conventions.gradle │ ├── speeddial.buildlog-conventions.gradle │ ├── speeddial.config-conventions.gradle │ ├── speeddial.dependencies-conventions.gradle │ ├── speeddial.dependency-graph-conventions.gradle │ ├── speeddial.detekt-conventions.gradle │ ├── speeddial.merged-manifests-conventions.gradle │ ├── speeddial.ruler-conventions.gradle │ ├── speeddial.spotless-conventions.gradle │ ├── speeddial.versions-conventions.gradle │ └── speeddial.violation-comments-to-github-conventions.gradle ├── build.gradle ├── checkstyle.gradle ├── config ├── checkstyle │ ├── checkstyle-suppressions.xml │ └── checkstyle.xml ├── detekt │ └── detekt.yml ├── diktat │ └── diktat-analysis.yml ├── greclipse │ └── greclipse.properties ├── lint │ └── lint.xml ├── prettier │ ├── prettierrc-graphql.yml │ └── prettierrc-yml.yml └── ruler │ └── ownership.yaml ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library-compose ├── .gitignore ├── build.gradle ├── consumer-proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── kotlin │ └── com │ └── leinardi │ └── android │ └── speeddial │ └── compose │ ├── ExpansionMode.kt │ ├── FabWithLabel.kt │ ├── SpeedDial.kt │ ├── SpeedDialItemScope.kt │ ├── SpeedDialOverlay.kt │ ├── SpeedDialScope.kt │ ├── SpeedDialScopeMarker.kt │ └── SpeedDialState.kt ├── library-view ├── .gitignore ├── build.gradle ├── consumer-proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── leinardi │ │ └── android │ │ └── speeddial │ │ ├── FabWithLabelView.java │ │ ├── SpeedDialActionItem.java │ │ ├── SpeedDialOverlayLayout.java │ │ ├── SpeedDialView.java │ │ ├── UiUtils.java │ │ └── ViewGroupUtils.java │ └── res │ ├── anim │ ├── sd_fade_and_translate_in.xml │ ├── sd_fade_and_translate_out.xml │ ├── sd_scale_fade_and_translate_in.xml │ └── sd_scale_fade_and_translate_out.xml │ ├── layout │ ├── sd_fab_with_label_view.xml │ └── sd_fill_fab.xml │ ├── values-night │ └── colors.xml │ ├── values-v21 │ └── styles.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── configs.xml │ ├── dimens.xml │ ├── ids.xml │ ├── strings.xml │ └── styles.xml ├── sample ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── com │ │ │ └── leinardi │ │ │ └── android │ │ │ └── speeddial │ │ │ └── sample │ │ │ ├── CustomAdapter.kt │ │ │ ├── SampleApp.kt │ │ │ ├── ViewActivity.kt │ │ │ ├── compose │ │ │ ├── ComposeActivity.kt │ │ │ ├── component │ │ │ │ └── TopAppBar.kt │ │ │ └── theme │ │ │ │ ├── Color.kt │ │ │ │ ├── SampleTheme.kt │ │ │ │ ├── Shape.kt │ │ │ │ └── Type.kt │ │ │ ├── interactor │ │ │ ├── GetVersionInteractor.kt │ │ │ └── ToggleNightModeInteractor.kt │ │ │ └── usecases │ │ │ ├── BaseUseCaseActivity.kt │ │ │ ├── UseCase1Activity.kt │ │ │ └── UseCasesActivity.kt │ │ └── res │ │ ├── anim │ │ ├── bottom_sheet_slide_in.xml │ │ └── bottom_sheet_slide_out.xml │ │ ├── drawable-hdpi │ │ ├── ic_custom_color.png │ │ └── ic_lorem_ipsum.png │ │ ├── drawable-mdpi │ │ ├── ic_custom_color.png │ │ └── ic_lorem_ipsum.png │ │ ├── drawable-xhdpi │ │ ├── ic_custom_color.png │ │ └── ic_lorem_ipsum.png │ │ ├── drawable-xxhdpi │ │ ├── ic_custom_color.png │ │ └── ic_lorem_ipsum.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_custom_color.png │ │ └── ic_lorem_ipsum.png │ │ ├── drawable │ │ ├── ic_add_action_white_24dp.xml │ │ ├── ic_add_white_24dp.xml │ │ ├── ic_animation_white_24dp.xml │ │ ├── ic_close_white_24dp.xml │ │ ├── ic_day_night_white_24dp.xml │ │ ├── ic_delete_white_24dp.xml │ │ ├── ic_expansion_mode_white_24dp.xml │ │ ├── ic_link_white_24dp.xml │ │ ├── ic_list_white_24dp.xml │ │ ├── ic_pencil_alt_white_24dp.xml │ │ ├── ic_replace_white_24dp.xml │ │ ├── ic_rotation_angle_white_24dp.xml │ │ ├── ic_show_white_24dp.xml │ │ ├── ic_snack_white_24dp.xml │ │ ├── ic_theme_white_24dp.xml │ │ └── ic_use_case_white_24dp.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── activity_use_case_1.xml │ │ ├── activity_use_cases.xml │ │ ├── appbarlayout.xml │ │ └── text_row_item.xml │ │ ├── menu │ │ ├── menu_base_use_case.xml │ │ ├── menu_main.xml │ │ └── menu_use_cases.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-it │ │ └── strings.xml │ │ ├── values-night │ │ └── themes.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ ├── motion.xml │ │ ├── shape.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ ├── themes.xml │ │ ├── themes_compose.xml │ │ └── type.xml └── versions │ ├── dependencies │ ├── debugAndroidTestRuntimeClasspathDependencies.txt │ ├── debugRuntimeClasspathDependencies.txt │ ├── debugUnitTestRuntimeClasspathDependencies.txt │ ├── releaseRuntimeClasspathDependencies.txt │ └── releaseUnitTestRuntimeClasspathDependencies.txt │ └── mergedManifests │ ├── debug │ └── AndroidManifest.xml │ └── release │ └── AndroidManifest.xml └── settings.gradle /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | education, socio-economic status, nationality, personal appearance, race, 10 | religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at roberto@leinardi.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ====== 3 | Considering that this project is actively maintained, contributions of all types are welcome. 4 | 5 | 6 | Opening issues 7 | ------- 8 | Open a new issue when: 9 | - you notice an unwanted behavior 10 | - you want a new feature implemented 11 | - you have just some doubts 12 | 13 | To open a new issue, please use the provided issue template and fill it out as much as possible. 14 | If you are interested to an existing issue, feel free to comment the issue or subscribe to it. 15 | 16 | 17 | Submitting pull requests 18 | ------- 19 | If you want to fix a bug or implement a new feature, feel free to submit a new pull request. 20 | To submit a pull request, you have to fork this repository and fill the PR template. 21 | When you want to submit a pull request, remember to: 22 | - follow this project's code style 23 | - run `./gradlew clean check` 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | ### Step 1: Are you in the right place? 7 | - [ ] I have verified there are no duplicate active or recent bugs, questions, or requests 8 | - [ ] I have verified that I am using the latest version of the library. 9 | 10 | ### Step 2: Describe your environment 11 | - Library version: `?` 12 | - Android version: `?` 13 | - Support library version: `?` 14 | - Device brand: `?` 15 | - Device model: `?` 16 | 17 | ### Step 3: Describe the problem: 18 | #### Steps to reproduce: 19 | 20 | 1. _____ 21 | 2. _____ 22 | 3. _____ 23 | 24 | 27 | #### Observed Results: 28 | 29 | * 30 | 31 | 34 | #### Expected Results: 35 | 36 | * 37 | 38 | #### Relevant Code: 39 | 42 | ```java 43 | System.out.println("Hello, world!"); 44 | ``` 45 | 46 | 50 | ```Gradle 51 | java.lang.RuntimeException: This is an example Exception log 52 | at jahirfiquitiva.libs.fabsmenu.HelloWorld 53 | at jahirfiquitiva.libs.fabsmenu.HelloWorld$ThisIsNotARealLog 54 | at android.app.Instrumentation.callActivityOnResume(Instrumentation.kt) 55 | ``` 56 | 57 | 60 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | ### First time contributor checklist 7 | 8 | - [ ] I have read [how to contribute](/.github/CONTRIBUTING.md) to this project 9 | - [ ] I have read [the code of conduct](/.github/CODE_OF_CONDUCT.md) to this project 10 | 11 | ### Contributor checklist 12 | 13 | - [ ] I am using the provided [codeStyleConfig.xml](/.idea/codeStyles) 14 | - [ ] I have tested my contribution on these devices: 15 | * Device A, Android X.Y.Z 16 | * Device B, Android Z.Y 17 | * Virtual device W, Android Y.Y.Z 18 | - [ ] My contribution is fully baked and ready to be merged as is 19 | - [ ] I ensure that all the open issues my contribution fixes are mentioned in the commit message of my first commit 20 | using the `Fixes #1234` [syntax](https://help.github.com/articles/closing-issues-using-keywords/) 21 | 22 | ---------- 23 | 24 | ### Description 25 | 30 | -------------------------------------------------------------------------------- /.github/ci-reporter.yml: -------------------------------------------------------------------------------- 1 | # Set to false to create a new comment instead of updating the app's first one 2 | updateComment: true 3 | 4 | # Use a custom string, or set to false to disable 5 | before: "Unfortunately, the [{{ provider }} build]({{ targetUrl }}) is failing as of {{ commit }}. Here's the output:" 6 | 7 | # Use a custom string, or set to false to disable 8 | after: "If you need help with this issue, don't hesitate to ask a maintainer of the project!" 9 | -------------------------------------------------------------------------------- /.github/labels.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Priority: Critical", 4 | "color": "#D32F2F" 5 | }, 6 | { 7 | "name": "Priority: High", 8 | "color": "#FF9800" 9 | }, 10 | { 11 | "name": "Priority: Low", 12 | "color": "#4CAF50" 13 | }, 14 | { 15 | "name": "Priority: Medium", 16 | "color": "#CDDC39" 17 | }, 18 | { 19 | "name": "Status: Abandoned", 20 | "color": "#000000" 21 | }, 22 | { 23 | "name": "Status: Accepted", 24 | "color": "#4CAF50" 25 | }, 26 | { 27 | "name": "Status: Available", 28 | "color": "#C8E6C9" 29 | }, 30 | { 31 | "name": "Status: Blocked", 32 | "color": "#D32F2F" 33 | }, 34 | { 35 | "name": "Status: Completed", 36 | "color": "#009688" 37 | }, 38 | { 39 | "name": "Status: In Progress", 40 | "color": "#E0E0E0" 41 | }, 42 | { 43 | "name": "Status: Info needed", 44 | "color": "#5C6BC0" 45 | }, 46 | { 47 | "name": "Status: On Hold", 48 | "color": "#D32F2F" 49 | }, 50 | { 51 | "name": "Status: Pending", 52 | "color": "#FFF176" 53 | }, 54 | { 55 | "name": "Status: Review Needed", 56 | "color": "#CDDC39" 57 | }, 58 | { 59 | "name": "Status: Revision Needed", 60 | "color": "#D32F2F" 61 | }, 62 | { 63 | "name": "Status: Stale", 64 | "color": "#9E9E9E" 65 | }, 66 | { 67 | "name": "triage", 68 | "color": "#81D4FA" 69 | }, 70 | { 71 | "name": "Type: Bug", 72 | "color": "#D32F2F" 73 | }, 74 | { 75 | "name": "Type: Enhancement", 76 | "color": "#546E7A" 77 | }, 78 | { 79 | "name": "Type: Maintenance", 80 | "color": "#CDDC39" 81 | }, 82 | { 83 | "name": "Type: Question", 84 | "color": "#673AB7" 85 | } 86 | ] 87 | -------------------------------------------------------------------------------- /.github/no-response.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-no-response - https://github.com/probot/no-response 2 | 3 | # Number of days of inactivity before an Issue is closed for lack of response 4 | daysUntilClose: 21 5 | # Label requiring a response 6 | responseRequiredLabel: 'Status: Info needed' 7 | # Comment to post when closing an Issue for lack of response. Set to `false` to disable 8 | closeComment: > 9 | This issue has been automatically closed because there has been no response 10 | to our request for more information from the original author. With only the 11 | information that is currently in the issue, we don't have enough information 12 | to take action. Please reach out if you have or find the answers we need so 13 | that we can investigate further. 14 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 60 5 | 6 | # Number of days of inactivity before a stale Issue or Pull Request is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: false 9 | 10 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 11 | exemptLabels: 12 | - pinned 13 | - security 14 | 15 | # Set to true to ignore issues in a project (defaults to false) 16 | exemptProjects: false 17 | 18 | # Set to true to ignore issues in a milestone (defaults to false) 19 | exemptMilestones: false 20 | 21 | # Label to use when marking as stale 22 | staleLabel: 'Status: Stale' 23 | 24 | # Comment to post when marking as stale. Set to `false` to disable 25 | markComment: > 26 | This issue has been automatically marked as stale because it has not had activity in the last 60 days. 27 | 28 | # Comment to post when removing the stale label. 29 | # unmarkComment: > 30 | # Your comment here. 31 | 32 | # Comment to post when closing a stale Issue or Pull Request. 33 | # closeComment: > 34 | # Your comment here. 35 | 36 | # Limit the number of actions per hour, from 1-30. Default is 30 37 | limitPerRun: 30 38 | # Limit to only `issues` or `pulls` 39 | # only: issues 40 | 41 | # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': 42 | # pulls: 43 | # daysUntilStale: 30 44 | # markComment: > 45 | # This pull request has been automatically marked as stale because it has not had 46 | # recent activity. It will be closed if no further activity occurs. Thank you 47 | # for your contributions. 48 | 49 | # issues: 50 | # exemptLabels: 51 | # - confirmed 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.aab 3 | *.apk 4 | *.ap_ 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | out/ 16 | 17 | # Gradle files 18 | .gradle/ 19 | build/ 20 | 21 | # Local configuration file (sdk path, etc) 22 | local.properties 23 | 24 | # Log Files 25 | *.log 26 | 27 | # Android Studio Navigation editor temp files 28 | .navigation/ 29 | 30 | # Android Studio captures folder 31 | captures/ 32 | 33 | # Intellij 34 | *.iml 35 | .idea/* 36 | !.idea/codeStyles/ 37 | !.idea/copyright/ 38 | !.idea/detekt.xml 39 | 40 | # External native build folder generated in Android Studio 2.2 and later 41 | .externalNativeBuild 42 | 43 | /captures 44 | /projectFilesBackup 45 | release_notes_*.txt 46 | 47 | # Release keys 48 | app-release.jks 49 | play-account.p12 50 | play-account.json 51 | keystore/ 52 | 53 | # Google Services (e.g. APIs or Firebase) 54 | google-services.json 55 | 56 | # Freeline 57 | freeline.py 58 | freeline/ 59 | freeline_project_description.json 60 | 61 | # Fastlane 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | fastlane/readme.md 67 | 68 | **/.DS_Store 69 | *.db 70 | 71 | # Reports 72 | reports/ 73 | 74 | .gitmodules 75 | -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/Apache_2_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/detekt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | true 6 | $PROJECT_DIR$/config/detekt/detekt.yml 7 | 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | sudo: true 4 | 5 | os: 6 | - linux 7 | addons: 8 | apt_packages: 9 | - pandoc 10 | 11 | before_cache: 12 | # Do not cache a few Gradle files/directories (see https://docs.travis-ci.com/user/languages/java/#Caching) 13 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 14 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 15 | 16 | cache: 17 | directories: 18 | # Gradle dependencies 19 | - $HOME/.gradle/caches/ 20 | - $HOME/.gradle/wrapper/ 21 | 22 | # Android build cache (see https://developer.android.com/studio/build/build-cache.html) 23 | - $HOME/.android/build-cache 24 | 25 | before_script: 26 | - mkdir -p $ANDROID_HOME/licenses 27 | - echo "8933bad161af4178b1185d1a37fbf41ea5269c55" > $ANDROID_HOME/licenses/android-sdk-license 28 | - echo "d56f5187479451eabf01fb78af6dfcb131a6481e" >> $ANDROID_HOME/licenses/android-sdk-license 29 | - mkdir -p $HOME/.android # silence sdkmanager warning 30 | - echo 'count=0' > $HOME/.android/repositories.cfg # silence sdkmanager warning 31 | - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'tools' 'platform-tools' 'build-tools;28.0.2' > /dev/null 32 | - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'platforms;android-27' > /dev/null 33 | 34 | script: 35 | - set -o pipefail 36 | - ./gradlew clean assemble :library:check --profile --continue 2>&1 | tee build.log 37 | - set +o pipefail 38 | - | 39 | if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then 40 | ./gradlew violationCommentsToGitHub -DGITHUB_PULLREQUESTID=$TRAVIS_PULL_REQUEST -DGITHUB_OAUTH2TOKEN=$GITHUB_OAUTH2TOKEN --info 41 | fi 42 | - pandoc `ls -1rt build/reports/profile/profile-*.html | tail -n1` -t plain 43 | - ./gradlew dependencyUpdate # Must run separately due to issues with the support library resolutionStrategy 44 | -------------------------------------------------------------------------------- /RELEASING.md: -------------------------------------------------------------------------------- 1 | # Releasing 2 | 3 | 1. Bump the `build_versions.version_name_*` property in `speeddial.config-conventions.gradle` based on Major.Minor.Patch naming scheme 4 | 2. Update `CHANGELOG.md` for the impending release. 5 | 3. Update the `README.md` with the new version. 6 | 4. `git commit -am "Prepare for release View|Compose X.Y.Z"` (where X.Y.Z is the version you set in step 1) 7 | 5. `./gradlew spotlessApply check` 8 | 6. `./gradlew clean assembleRelease` 9 | 7. `git push` 10 | 8. `./gradlew :library-view:publishReleasePublicationToSonatypeRepository` 11 | 9. `./gradlew :library-compose:publishReleasePublicationToSonatypeRepository` 12 | 10. Create a new release on Github 13 | 1. Tag View version `X.Y.Z` (`git tag -s view-X.Y.Z && git push --tags`) 14 | 2. Tag Compose version `X.Y.Z` (`git tag -s compose-X.Y.Z && git push --tags`) 15 | 3. Release title (`View X.Y.Z` or `Compose X.Y.Z`) 16 | 4. Paste the content from `CHANGELOG.md` as the description 17 | 5. Upload the sample-release.apk 18 | 11. Create a PR from [master](../../tree/master) to [release](../../tree/release) 19 | 12. Visit [Sonatype](https://s01.oss.sonatype.org/#stagingRepositories) and Close and Release the artifact 20 | 13. Visit [Google Play Console](https://play.google.com/apps/publish/) and upload and publish the new APK 21 | -------------------------------------------------------------------------------- /art/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/banner.png -------------------------------------------------------------------------------- /art/demo_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/demo_1.gif -------------------------------------------------------------------------------- /art/playstore_getiton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/playstore_getiton.png -------------------------------------------------------------------------------- /art/project.dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/project.dot.png -------------------------------------------------------------------------------- /art/screenshot_api_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/screenshot_api_16.png -------------------------------------------------------------------------------- /art/screenshot_api_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/screenshot_api_27.png -------------------------------------------------------------------------------- /art/screenshot_api_27_bottom_fab_left_expansion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/screenshot_api_27_bottom_fab_left_expansion.png -------------------------------------------------------------------------------- /art/screenshot_api_27_top_fab_bottom_expansion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/screenshot_api_27_top_fab_bottom_expansion.png -------------------------------------------------------------------------------- /art/web_hi_res_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/art/web_hi_res_512.png -------------------------------------------------------------------------------- /build-conventions/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Sharing build logic between subprojects 18 | // https://docs.gradle.org/current/samples/sample_convention_plugins.html 19 | 20 | plugins { 21 | id 'groovy-gradle-plugin' 22 | } 23 | 24 | 25 | dependencies { 26 | implementation libs.plugin.aboutlibraries 27 | implementation libs.plugin.android 28 | implementation libs.plugin.androidcachefix 29 | implementation libs.plugin.appversioning 30 | implementation libs.plugin.detekt 31 | implementation libs.plugin.easylauncher 32 | implementation libs.plugin.firebase.crashlytics 33 | implementation libs.plugin.firebase.perf 34 | implementation libs.plugin.google.services 35 | implementation libs.plugin.hilt 36 | implementation libs.plugin.kotlin 37 | implementation libs.plugin.publish 38 | implementation libs.plugin.ruler 39 | implementation libs.plugin.spotless 40 | implementation libs.plugin.versionsgradle 41 | implementation libs.plugin.violation 42 | } 43 | -------------------------------------------------------------------------------- /build-conventions/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | dependencyResolutionManagement { 18 | repositories { 19 | gradlePluginPortal() 20 | google() 21 | mavenCentral() 22 | } 23 | versionCatalogs { 24 | libs { 25 | from(files("../gradle/libs.versions.toml")) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.android-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | android { 18 | compileSdk config.android.compileSdk 19 | 20 | defaultConfig { 21 | versionCode config.android.version_code 22 | minSdk config.android.minSdk 23 | targetSdk config.android.targetSdk 24 | } 25 | compileOptions { 26 | sourceCompatibility config.android.javaVersion 27 | targetCompatibility config.android.javaVersion 28 | } 29 | testOptions { 30 | execution 'ANDROIDX_TEST_ORCHESTRATOR' 31 | animationsDisabled = true 32 | unitTests { 33 | returnDefaultValues = true 34 | includeAndroidResources = true 35 | all { 36 | jvmArgs '-noverify' 37 | } 38 | } 39 | } 40 | lintOptions { 41 | abortOnError true 42 | checkAllWarnings false 43 | checkDependencies true 44 | checkReleaseBuilds false 45 | ignoreTestSources true 46 | warningsAsErrors false 47 | disable 'ResourceType' 48 | lintConfig file("${project.rootDir}/config/lint/lint.xml") 49 | } 50 | packagingOptions { 51 | resources { 52 | // Use this block to exclude conflicting files that breaks your APK assemble task 53 | // exclude "META-INF/AL2.0" 54 | } 55 | } 56 | } 57 | 58 | tasks.withType(Test) { 59 | testLogging { 60 | events "skipped", "failed" 61 | } 62 | } 63 | 64 | dependencies { 65 | androidTestImplementation libs.androidx.test.espresso.core 66 | androidTestImplementation libs.androidx.test.ext.junit 67 | androidTestImplementation libs.androidx.test.runner 68 | androidTestUtil libs.androidx.test.orchestrator 69 | } 70 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.android-library-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | plugins { 17 | id 'com.android.library' 18 | id 'speeddial.android-conventions' 19 | } 20 | 21 | android { 22 | buildTypes { 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.android-sample-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id 'com.android.application' 19 | id 'kotlin-android' 20 | id 'kotlin-kapt' 21 | id 'speeddial.android-conventions' 22 | id 'speeddial.detekt-conventions' 23 | id 'speeddial.merged-manifests-conventions' 24 | id 'speeddial.dependencies-conventions' 25 | id 'speeddial.ruler-conventions' 26 | } 27 | 28 | android { 29 | sourceSets { 30 | main.java.srcDirs += 'src/main/kotlin' 31 | test.java.srcDirs += 'src/test/kotlin' 32 | } 33 | 34 | kotlinOptions { 35 | freeCompilerArgs += '-opt-in=kotlin.RequiresOptIn' 36 | jvmTarget = config.android.javaVersion 37 | useIR = true 38 | } 39 | 40 | buildFeatures { 41 | compose true 42 | } 43 | 44 | composeOptions { 45 | kotlinCompilerExtensionVersion libs.versions.androidx.compose.get() 46 | } 47 | } 48 | 49 | kapt { 50 | useBuildCache = true 51 | correctErrorTypes true 52 | javacOptions { 53 | option('-Xmaxerrs', Integer.MAX_VALUE) 54 | } 55 | } 56 | 57 | kotlin { 58 | sourceSets.all { 59 | languageSettings { 60 | progressiveMode = true // deprecations and bug fixes for unstable code take effect immediately 61 | } 62 | } 63 | } 64 | 65 | dependencies { 66 | // Android 67 | implementation libs.androidx.core.ktx 68 | implementation libs.androidx.appcompat 69 | 70 | // General 71 | implementation libs.timber 72 | debugImplementation libs.leakcanary 73 | } 74 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.artifact-publish-library-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | plugins { 19 | id 'maven-publish' 20 | id 'signing' 21 | id 'org.jetbrains.dokka' 22 | } 23 | 24 | task androidSourcesJar(type: Jar) { 25 | archiveClassifier.set('sources') 26 | if (project.plugins.findPlugin("com.android.library")) { 27 | // For Android libraries 28 | from android.sourceSets.main.java.srcDirs 29 | from android.sourceSets.main.kotlin.srcDirs 30 | } else { 31 | // For pure Kotlin libraries, in case you have them 32 | from sourceSets.main.java.srcDirs 33 | from sourceSets.main.kotlin.srcDirs 34 | } 35 | } 36 | 37 | tasks.withType(dokkaHtmlPartial.getClass()).configureEach { 38 | pluginsMapConfiguration.set( 39 | ["org.jetbrains.dokka.base.DokkaBase": """{ "separateInheritedMembers": true}"""] 40 | ) 41 | } 42 | 43 | task javadocJar(type: Jar, dependsOn: dokkaJavadoc) { 44 | archiveClassifier.set('javadoc') 45 | from dokkaJavadoc.outputDirectory 46 | } 47 | 48 | artifacts { 49 | archives androidSourcesJar 50 | archives javadocJar 51 | } 52 | 53 | afterEvaluate { 54 | group = PUBLISH_GROUP_ID 55 | version = PUBLISH_VERSION 56 | 57 | publishing { 58 | publications { 59 | release(MavenPublication) { 60 | // The coordinates of the library, being set from variables that 61 | // we'll set up later 62 | groupId PUBLISH_GROUP_ID 63 | artifactId PUBLISH_ARTIFACT_ID 64 | version PUBLISH_VERSION 65 | 66 | // Two artifacts, the `aar` (or `jar`) and the sources 67 | if (project.plugins.findPlugin("com.android.library")) { 68 | from components.release 69 | } else { 70 | artifact("$buildDir/libs/${project.getName()}-${version}.jar") 71 | } 72 | 73 | artifact androidSourcesJar 74 | artifact javadocJar 75 | 76 | // Mostly self-explanatory metadata 77 | pom { 78 | name = PUBLISH_ARTIFACT_ID 79 | description = 'Android library providing an implementation of the Material Design Floating Action Button Speed Dial pattern.' 80 | url = 'https://github.com/leinardi/FloatingActionButtonSpeedDial' 81 | licenses { 82 | license { 83 | name = 'FloatingActionButtonSpeedDial License' 84 | url = 'https://github.com/leinardi/FloatingActionButtonSpeedDial/blob/release/LICENSE' 85 | } 86 | } 87 | developers { 88 | developer { 89 | id = 'leinardi' 90 | name = 'Roberto Leinardi' 91 | email = 'roberto@leinardi.com' 92 | } 93 | } 94 | scm { 95 | connection = 'scm:git:github.com/leinardi/FloatingActionButtonSpeedDial.git' 96 | developerConnection = 'scm:git:ssh://github.com/leinardi/FloatingActionButtonSpeedDial.git' 97 | url = 'https://github.com/leinardi/FloatingActionButtonSpeedDial/tree/release' 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } 104 | 105 | ext["signing.keyId"] = rootProject.ext["signing.keyId"] 106 | ext["signing.password"] = rootProject.ext["signing.password"] 107 | ext["signing.secretKeyRingFile"] = rootProject.ext["signing.secretKeyRingFile"] 108 | 109 | signing { 110 | sign publishing.publications 111 | } 112 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.artifact-publish-root-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | plugins { 19 | id 'io.github.gradle-nexus.publish-plugin' 20 | } 21 | 22 | // Create variables with empty default values 23 | if (!project.hasProperty("ossrhUsername")) { 24 | ext["ossrhUsername"] = '' 25 | } 26 | if (!project.hasProperty("ossrhPassword")) { 27 | ext["ossrhPassword"] = '' 28 | } 29 | if (!project.hasProperty("sonatypeStagingProfileId")) { 30 | ext["sonatypeStagingProfileId"] = '' 31 | } 32 | if (!project.hasProperty("signing.keyId")) { 33 | ext["signing.keyId"] = '' 34 | } 35 | if (!project.hasProperty("signing.password")) { 36 | ext["signing.password"] = '' 37 | } 38 | if (!project.hasProperty("signing.secretKeyRingFile")) { 39 | ext["signing.secretKeyRingFile"] = '' 40 | } 41 | 42 | File secretPropsFile = project.rootProject.file('local.properties') 43 | if (secretPropsFile.exists()) { 44 | // Read local.properties file first if it exists 45 | Properties p = new Properties() 46 | new FileInputStream(secretPropsFile).withCloseable { is -> p.load(is) } 47 | p.each { name, value -> ext[name] = value } 48 | } else { 49 | // Use system environment variables 50 | ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME') 51 | ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD') 52 | ext["sonatypeStagingProfileId"] = System.getenv('SONATYPE_STAGING_PROFILE_ID') 53 | ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') 54 | ext["signing.password"] = System.getenv('SIGNING_PASSWORD') 55 | ext["signing.secretKeyRingFile"] = System.getenv('SIGNING_SECRET_KEY_RING_FILE') 56 | } 57 | 58 | // Set up Sonatype repository 59 | nexusPublishing { 60 | repositories { 61 | sonatype { 62 | stagingProfileId = sonatypeStagingProfileId 63 | username = ossrhUsername 64 | password = ossrhPassword 65 | nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) 66 | snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) 67 | } 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.buildlog-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import org.gradle.internal.logging.LoggingOutputInternal 17 | 18 | if (config.params.saveBuildLogToFile) { 19 | def datetime = new Date().format('yyyy-MM-dd-HH-mm-ss') 20 | def buildLogDir = "${rootDir}/build/logs" 21 | mkdir(buildLogDir) 22 | def buildLog = new File("${buildLogDir}/buildlog-${datetime}.txt") 23 | 24 | System.setProperty('org.gradle.color.error', 'RED') 25 | 26 | def outputListener = new StandardOutputListener() { 27 | void onOutput(CharSequence output) { 28 | buildLog << output 29 | } 30 | } 31 | gradle.services.get(LoggingOutputInternal).addStandardOutputListener(outputListener) 32 | gradle.services.get(LoggingOutputInternal).addStandardErrorListener(outputListener) 33 | } 34 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.config-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | def commitCount = 'git rev-list --count HEAD'.execute().text.trim() 17 | ext.config = [ 18 | android: [ 19 | 'applicationId': 'com.leinardi.android.speeddial.sample', 20 | 'compileSdk' : 31, 21 | 'javaVersion' : JavaVersion.VERSION_11, 22 | 'minSdk' : 14, 23 | 'minSdkCompose': 21, 24 | 'targetSdk' : 31, 25 | 'version_code' : commitCount.isNumber() ? commitCount as int : 0, 26 | 'version_name_view' : '3.3.0', 27 | 'version_name_compose' : '1.0.0-alpha04', 28 | 'version_name_sample' : '4.2.0', 29 | ], 30 | 31 | params : [ 32 | saveBuildLogToFile: Boolean.parseBoolean(project.properties['saveBuildLogToFile']) ?: false 33 | ], 34 | ] 35 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.dependencies-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | afterEvaluate { 18 | def outputPath = "versions/dependencies" 19 | mkdir outputPath 20 | def compileDependencyReportTask = tasks.register("generateRuntimeDependenciesReport") { 21 | description 'Generates a text file containing the Runtime classpath dependencies.' 22 | } 23 | project.configurations.findAll { it.name.contains("RuntimeClasspath") }.forEach { configuration -> 24 | def configurationTask = tasks.register("generate${configuration.name.capitalize()}DependenciesReport", DependencyReportTask) { 25 | configurations = [configuration] 26 | outputFile = file("$outputPath/${configuration.name}Dependencies.txt") 27 | } 28 | compileDependencyReportTask.configure { dependsOn configurationTask } 29 | } 30 | check.dependsOn tasks.named("generateRuntimeDependenciesReport") 31 | } 32 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.detekt-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id 'io.gitlab.arturbosch.detekt' 19 | } 20 | 21 | detekt { 22 | toolVersion = libs.versions.detekt.get() 23 | source = files("src/main/kotlin", "src/test/kotlin", "src/androidTest/kotlin") 24 | parallel = true 25 | autoCorrect = true 26 | } 27 | 28 | dependencies { 29 | detektPlugins libs.detekt 30 | } 31 | 32 | afterEvaluate { 33 | check.dependsOn tasks.named("detektMain") 34 | check.dependsOn tasks.named("detektTest") 35 | } 36 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.merged-manifests-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | tasks.register("copyMergedManifests", Copy) { 17 | dependsOn tasks.matching { (it.name ==~ /^process.*Manifest$/) } 18 | mustRunAfter tasks.matching { (it.name ==~ /^process.*Manifest$/) } 19 | mkdir 'versions/mergedManifests' 20 | from("$buildDir/intermediates/merged_manifests") { 21 | include '**/*.xml' 22 | } 23 | into 'versions/mergedManifests' 24 | filter { line -> line.replaceAll("(android:version.*=\".*\")|(android:testOnly=\".*\")", "") } 25 | } 26 | 27 | check.dependsOn tasks.named("copyMergedManifests") 28 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.ruler-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id 'com.spotify.ruler' 19 | } 20 | 21 | ruler { 22 | abi = "arm64-v8a" 23 | locale = "en" 24 | screenDensity = 480 25 | sdkVersion = 30 26 | ownershipFile.set(rootProject.file("config/ruler/ownership.yaml")) 27 | defaultOwner.set("others") 28 | } 29 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.spotless-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id 'com.diffplug.spotless' 19 | } 20 | 21 | spotless { 22 | kotlin { 23 | target '**/*.kt' 24 | targetExclude("$buildDir/**/*.kt") 25 | diktat(libs.versions.diktat.get()).configFile("$rootDir/config/diktat/diktat-analysis.yml") 26 | trimTrailingWhitespace() 27 | indentWithSpaces() 28 | endWithNewline() 29 | } 30 | 31 | groovyGradle { 32 | target '**/*.gradle' 33 | greclipse(libs.versions.greclipse.get()).configFile("$rootDir/config/greclipse/greclipse.properties") 34 | } 35 | 36 | format 'graphql', { 37 | target '**/*.graphql' 38 | prettier(libs.versions.prettier.get()).configFile("$rootDir/config/prettier/prettierrc-graphql.yml") 39 | } 40 | 41 | format 'yml', { 42 | target '**/*.yml', '**/*.yaml' 43 | prettier(libs.versions.prettier.get()).configFile("$rootDir/config/prettier/prettierrc-yml.yml") 44 | } 45 | 46 | format 'androidXml', { 47 | target '**/AndroidManifest.xml', 'src/**/*.xml' 48 | targetExclude '**/mergedManifests/**/AndroidManifest.xml', "**/build/**/*.xml" 49 | indentWithSpaces() 50 | trimTrailingWhitespace() 51 | endWithNewline() 52 | } 53 | 54 | format 'misc', { 55 | // define the files to apply `misc` to 56 | target '**/*.md', '**/.gitignore' 57 | 58 | // define the steps to apply to those files 59 | indentWithSpaces() 60 | trimTrailingWhitespace() 61 | endWithNewline() 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /build-conventions/src/main/groovy/speeddial.violation-comments-to-github-conventions.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import se.bjurr.violations.comments.github.plugin.gradle.ViolationCommentsToGitHubTask 17 | 18 | plugins { 19 | id 'se.bjurr.violations.violation-comments-to-github-gradle-plugin' 20 | } 21 | 22 | tasks.register('violationCommentsToGitHub', ViolationCommentsToGitHubTask) { 23 | repositoryOwner = "leinardi" 24 | repositoryName = "FloatingActionButtonSpeedDial" 25 | pullRequestId = System.properties['GITHUB_PULLREQUESTID'] 26 | oAuth2Token = System.properties['GITHUB_OAUTH2TOKEN'] 27 | gitHubUrl = "https://api.github.com/" 28 | createCommentWithAllSingleFileComments = false 29 | createSingleFileComments = true 30 | commentOnlyChangedContent = true 31 | keepOldComments = false 32 | violations = [ 33 | [ 34 | "KOTLINGRADLE", 35 | ".", 36 | ".*/build/logs/buildlog.*\\.txt\$", 37 | "Gradle" 38 | ], 39 | [ 40 | "CHECKSTYLE", 41 | ".", 42 | ".*/reports/detekt/.*\\.xml\$", 43 | "Detekt" 44 | ], 45 | [ 46 | "ANDROIDLINT", 47 | ".", 48 | ".*/reports/lint-results.*\\.xml\$", 49 | "Android Lint" 50 | ], 51 | [ 52 | "JUNIT", 53 | ".", 54 | ".*/build/test-results/test.*/.*\\.xml\$", 55 | "Unit" 56 | ], 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | //apply plugin: 'org.jetbrains.dokka' 17 | 18 | buildscript { 19 | repositories { 20 | repositories { 21 | google() 22 | mavenCentral() 23 | gradlePluginPortal() 24 | } 25 | } 26 | } 27 | 28 | plugins { 29 | id 'speeddial.config-conventions' 30 | id 'speeddial.buildlog-conventions' 31 | id 'speeddial.spotless-conventions' 32 | id 'speeddial.versions-conventions' 33 | id 'speeddial.dependency-graph-conventions' 34 | id 'speeddial.violation-comments-to-github-conventions' 35 | id 'speeddial.artifact-publish-root-conventions' 36 | alias(libs.plugins.gradledoctor) 37 | alias(libs.plugins.dokka) 38 | alias(libs.plugins.publish) 39 | } 40 | 41 | subprojects { 42 | gradle.projectsEvaluated { 43 | tasks.withType(JavaCompile) { 44 | options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" 45 | } 46 | } 47 | } 48 | 49 | doctor { 50 | warnWhenJetifierEnabled = false 51 | } 52 | 53 | wrapper { 54 | gradleVersion = "7.4.2" 55 | distributionType = Wrapper.DistributionType.ALL 56 | } 57 | 58 | wrapper { 59 | gradleVersion "7.4.1" 60 | distributionType = Wrapper.DistributionType.ALL 61 | } 62 | -------------------------------------------------------------------------------- /checkstyle.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'com.leinardi.android.checkstyle' // TODO 18 | 19 | checkstyle { 20 | ignoreFailures = false // Whether this task will ignore failures and continue running the build. 21 | configFile rootProject.file('config/checkstyle/checkstyle.xml') 22 | // The Checkstyle configuration file to use. 23 | toolVersion = '8.32' // The version of Checkstyle you want to be used 24 | } 25 | -------------------------------------------------------------------------------- /config/checkstyle/checkstyle-suppressions.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /config/greclipse/greclipse.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 Roberto Leinardi. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | #Whether to use 'space', 'tab' or 'mixed' (both) characters for indentation. 18 | #The default value is 'tab'. 19 | org.eclipse.jdt.core.formatter.tabulation.char=space 20 | 21 | #Number of spaces used for indentation in case 'space' characters 22 | #have been selected. The default value is 4. 23 | org.eclipse.jdt.core.formatter.tabulation.size=4 24 | 25 | #Number of spaces used for indentation in case 'mixed' characters 26 | #have been selected. The default value is 4. 27 | org.eclipse.jdt.core.formatter.indentation.size=4 28 | 29 | #Whether or not indentation characters are inserted into empty lines. 30 | #The default value is 'true'. 31 | org.eclipse.jdt.core.formatter.indent_empty_lines=false 32 | 33 | #Number of spaces used for multiline indentation. 34 | #The default value is 2. 35 | groovy.formatter.multiline.indentation=2 36 | 37 | #Length after which list are considered too long. These will be wrapped. 38 | #The default value is 30. 39 | groovy.formatter.longListLength=30 40 | 41 | #Whether opening braces position shall be the next line. 42 | #The default value is 'same'. 43 | groovy.formatter.braces.start=same 44 | 45 | #Whether closing braces position shall be the next line. 46 | #The default value is 'next'. 47 | groovy.formatter.braces.end=next 48 | 49 | #Remove unnecessary semicolons. The default value is 'false'. 50 | groovy.formatter.remove.unnecessary.semicolons=true 51 | -------------------------------------------------------------------------------- /config/lint/lint.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /config/prettier/prettierrc-graphql.yml: -------------------------------------------------------------------------------- 1 | # Configuration File for Prettier formatter used when running Spotless. 2 | # More information about config file: https://prettier.io/docs/en/configuration.html 3 | # List of rules which can be configured here: https://prettier.io/docs/en/options.html 4 | tabWidth: 4 5 | -------------------------------------------------------------------------------- /config/prettier/prettierrc-yml.yml: -------------------------------------------------------------------------------- 1 | # Configuration File for Prettier formatter used when running Spotless. 2 | # More information about config file: https://prettier.io/docs/en/configuration.html 3 | # List of rules which can be configured here: https://prettier.io/docs/en/options.html 4 | tabWidth: 2 5 | singleQuote: true 6 | -------------------------------------------------------------------------------- /config/ruler/ownership.yaml: -------------------------------------------------------------------------------- 1 | - identifier: :app 2 | owner: app 3 | 4 | - identifier: :modules:core* 5 | owner: core 6 | 7 | - identifier: :modules:feature* 8 | owner: feature 9 | 10 | - identifier: androidx.* 11 | owner: androidx 12 | 13 | - identifier: com.google.* 14 | owner: google 15 | 16 | - identifier: org.jetbrains.kotlin* 17 | owner: kotlin 18 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 Roberto Leinardi. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | org.gradle.caching=true 17 | org.gradle.jvmargs=-Xms2G -Xmx6G -XX:+UseParallelGC 18 | org.gradle.parallel=true 19 | org.gradle.warning.mode=all 20 | # Android 21 | android.builder.sdkDownload=true 22 | android.databinding.incremental=true 23 | android.enableJetifier=true 24 | android.enableResourceOptimizations=true 25 | android.experimental.cacheCompileLibResources=true 26 | android.experimental.enableSourceSetPathsMap=true 27 | android.useAndroidX=true 28 | # Kotlin 29 | kotlin.code.style=official 30 | kotlin.incremental.usePreciseJavaTracking=true 31 | kotlin.mpp.enableGranularSourceSetsMetadata=true 32 | kotlin.native.enableDependencyPropagation=false 33 | kapt.include.compile.classpath=false 34 | KEYSTORE_PATH=../keystore/release.keystore 35 | KEYSTORE_PROPERTIES_PATH=../keystore/keystore.properties 36 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 Roberto Leinardi. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | distributionBase=GRADLE_USER_HOME 18 | distributionPath=wrapper/dists 19 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip 20 | zipStoreBase=GRADLE_USER_HOME 21 | zipStorePath=wrapper/dists 22 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /library-compose/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /library-compose/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id 'kotlin-android' 19 | id 'kotlin-kapt' 20 | id 'speeddial.android-library-conventions' 21 | id 'speeddial.detekt-conventions' 22 | id 'speeddial.artifact-publish-library-conventions' 23 | } 24 | 25 | ext { 26 | PUBLISH_GROUP_ID = 'com.leinardi.android' 27 | PUBLISH_VERSION = config.android.version_name_compose 28 | PUBLISH_ARTIFACT_ID = 'speed-dial.compose' 29 | } 30 | 31 | android { 32 | defaultConfig { 33 | versionName config.android.version_name_compose 34 | minSdk config.android.minSdkCompose 35 | consumerProguardFiles 'consumer-proguard-rules.pro' 36 | } 37 | 38 | buildFeatures { 39 | compose true 40 | } 41 | 42 | composeOptions { 43 | kotlinCompilerExtensionVersion libs.versions.androidx.compose.get() 44 | } 45 | 46 | sourceSets { 47 | main.java.srcDirs += 'src/main/kotlin' 48 | test.java.srcDirs += 'src/test/kotlin' 49 | } 50 | 51 | kotlinOptions { 52 | freeCompilerArgs += '-opt-in=kotlin.RequiresOptIn' 53 | jvmTarget = config.android.javaVersion 54 | useIR = true 55 | } 56 | } 57 | 58 | kapt { 59 | useBuildCache = true 60 | correctErrorTypes true 61 | javacOptions { 62 | option('-Xmaxerrs', Integer.MAX_VALUE) 63 | } 64 | } 65 | 66 | kotlin { 67 | sourceSets.all { 68 | languageSettings { 69 | progressiveMode = true // deprecations and bug fixes for unstable code take effect immediately 70 | } 71 | } 72 | } 73 | dependencies { 74 | implementation libs.androidx.appcompat 75 | implementation libs.androidx.compose.material 76 | implementation libs.androidx.compose.runtime 77 | implementation libs.androidx.compose.tooling 78 | implementation libs.androidx.compose.ui 79 | implementation libs.androidx.core.ktx 80 | debugApi libs.androidx.customview // Workaround for https://issuetracker.google.com/issues/227767363 81 | debugApi libs.androidx.customview.poolingcontainer // Workaround for https://issuetracker.google.com/issues/227767363 82 | } 83 | -------------------------------------------------------------------------------- /library-compose/consumer-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 /home/arthur/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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /library-compose/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /library-compose/src/main/kotlin/com/leinardi/android/speeddial/compose/ExpansionMode.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.compose 18 | 19 | @Suppress("EnumNaming") 20 | enum class ExpansionMode { 21 | Bottom, End, Start, Top 22 | } 23 | -------------------------------------------------------------------------------- /library-compose/src/main/kotlin/com/leinardi/android/speeddial/compose/FabWithLabel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.compose 18 | 19 | import androidx.compose.foundation.layout.Arrangement 20 | import androidx.compose.foundation.layout.Box 21 | import androidx.compose.foundation.layout.Row 22 | import androidx.compose.foundation.layout.padding 23 | import androidx.compose.foundation.layout.size 24 | import androidx.compose.foundation.layout.widthIn 25 | import androidx.compose.foundation.shape.CornerSize 26 | import androidx.compose.material.Card 27 | import androidx.compose.material.ContentAlpha 28 | import androidx.compose.material.ExperimentalMaterialApi 29 | import androidx.compose.material.FloatingActionButton 30 | import androidx.compose.material.FloatingActionButtonDefaults 31 | import androidx.compose.material.FloatingActionButtonElevation 32 | import androidx.compose.material.LocalContentAlpha 33 | import androidx.compose.material.MaterialTheme 34 | import androidx.compose.material.ProvideTextStyle 35 | import androidx.compose.material.contentColorFor 36 | import androidx.compose.runtime.Composable 37 | import androidx.compose.runtime.CompositionLocalProvider 38 | import androidx.compose.ui.Alignment 39 | import androidx.compose.ui.Modifier 40 | import androidx.compose.ui.graphics.Color 41 | import androidx.compose.ui.graphics.Shape 42 | import androidx.compose.ui.unit.Dp 43 | import androidx.compose.ui.unit.dp 44 | 45 | @ExperimentalMaterialApi 46 | @Composable 47 | fun FabWithLabel( 48 | onClick: () -> Unit, 49 | modifier: Modifier = Modifier, 50 | labelContent: @Composable (() -> Unit)? = null, 51 | labelBackgroundColor: Color = MaterialTheme.colors.surface, 52 | labelMaxWidth: Dp = 160.dp, 53 | labelContainerElevation: Dp = 2.dp, 54 | fabShape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)), 55 | fabElevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(), 56 | fabSize: Dp = SpeedDialMiniFabSize, 57 | fabBackgroundColor: Color = MaterialTheme.colors.primary, 58 | fabContentColor: Color = contentColorFor(fabBackgroundColor), 59 | fabContent: @Composable () -> Unit, 60 | ) { 61 | Row( 62 | modifier = Modifier 63 | .padding(end = (SpeedDialFabSize - fabSize) / 2) 64 | .then(modifier), 65 | horizontalArrangement = Arrangement.spacedBy((SpeedDialFabSize - fabSize) / 2 + 16.dp, Alignment.CenterHorizontally), 66 | verticalAlignment = Alignment.CenterVertically, 67 | ) { 68 | if (labelContent != null) { 69 | Card( 70 | modifier = Modifier.widthIn(max = labelMaxWidth), 71 | onClick = onClick, 72 | backgroundColor = labelBackgroundColor, 73 | elevation = labelContainerElevation, 74 | ) { 75 | Box( 76 | modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), 77 | propagateMinConstraints = true, 78 | ) { 79 | ProvideTextStyle(value = MaterialTheme.typography.subtitle2) { 80 | CompositionLocalProvider( 81 | LocalContentAlpha provides ContentAlpha.high, 82 | content = labelContent, 83 | ) 84 | } 85 | } 86 | } 87 | } 88 | 89 | FloatingActionButton( 90 | onClick = onClick, 91 | modifier = Modifier.size(fabSize), 92 | shape = fabShape, 93 | backgroundColor = fabBackgroundColor, 94 | contentColor = fabContentColor, 95 | elevation = fabElevation, 96 | ) { 97 | fabContent() 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /library-compose/src/main/kotlin/com/leinardi/android/speeddial/compose/SpeedDialItemScope.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.compose 18 | 19 | import androidx.compose.runtime.Stable 20 | 21 | /** 22 | * Receiver scope being used by the item content parameter of SpeedDial. 23 | */ 24 | @Stable 25 | @SpeedDialScopeMarker 26 | class SpeedDialItemScope 27 | -------------------------------------------------------------------------------- /library-compose/src/main/kotlin/com/leinardi/android/speeddial/compose/SpeedDialOverlay.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.compose 18 | 19 | import androidx.compose.animation.AnimatedVisibility 20 | import androidx.compose.animation.fadeIn 21 | import androidx.compose.animation.fadeOut 22 | import androidx.compose.foundation.background 23 | import androidx.compose.foundation.clickable 24 | import androidx.compose.foundation.layout.Box 25 | import androidx.compose.foundation.layout.fillMaxSize 26 | import androidx.compose.material.MaterialTheme 27 | import androidx.compose.runtime.Composable 28 | import androidx.compose.ui.Modifier 29 | import androidx.compose.ui.graphics.Color 30 | 31 | @Composable 32 | fun SpeedDialOverlay( 33 | visible: Boolean, 34 | onClick: (() -> Unit), 35 | modifier: Modifier = Modifier, 36 | color: Color = MaterialTheme.colors.surface.copy(alpha = 0.66f), 37 | animate: Boolean = true, 38 | ) { 39 | if (animate) { 40 | AnimatedVisibility( 41 | modifier = modifier, 42 | visible = visible, 43 | enter = fadeIn(), 44 | exit = fadeOut(), 45 | ) { 46 | OverlayBox(color, onClick, modifier) 47 | } 48 | } else if (visible) { 49 | OverlayBox(color, onClick, modifier) 50 | } 51 | } 52 | 53 | @Composable 54 | private fun OverlayBox( 55 | color: Color, 56 | onClick: (() -> Unit), 57 | modifier: Modifier = Modifier, 58 | ) { 59 | Box( 60 | modifier = Modifier 61 | .fillMaxSize() 62 | .background(color) 63 | .clickable(onClick = onClick) 64 | .then(modifier), 65 | ) 66 | } 67 | -------------------------------------------------------------------------------- /library-compose/src/main/kotlin/com/leinardi/android/speeddial/compose/SpeedDialScope.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.compose 18 | 19 | import androidx.compose.foundation.lazy.LazyScopeMarker 20 | import androidx.compose.runtime.Composable 21 | 22 | /** 23 | * Receiver scope which is used by [SpeedDial]. 24 | */ 25 | @LazyScopeMarker 26 | class SpeedDialScope { 27 | private val _intervals = mutableListOf() 28 | internal val intervals: List = _intervals 29 | 30 | /** 31 | * Adds a single item. 32 | * 33 | * @param content the content of the item 34 | */ 35 | fun item( 36 | content: @Composable SpeedDialItemScope.() -> Unit, 37 | ) { 38 | _intervals.add(0, SpeedDialIntervalContent(item = { content() })) 39 | } 40 | } 41 | 42 | internal data class SpeedDialIntervalContent( 43 | val item: @Composable SpeedDialItemScope.() -> Unit, 44 | ) 45 | -------------------------------------------------------------------------------- /library-compose/src/main/kotlin/com/leinardi/android/speeddial/compose/SpeedDialScopeMarker.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.compose 18 | 19 | /** 20 | * DSL marker used to distinguish between SpeedDial layout scope and the item scope. 21 | */ 22 | @DslMarker 23 | annotation class SpeedDialScopeMarker 24 | -------------------------------------------------------------------------------- /library-compose/src/main/kotlin/com/leinardi/android/speeddial/compose/SpeedDialState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.compose 18 | 19 | import androidx.compose.runtime.MutableState 20 | import androidx.compose.runtime.ProvidableCompositionLocal 21 | import androidx.compose.runtime.compositionLocalOf 22 | 23 | /** 24 | * Enum that represents possible SpeedDial states. 25 | */ 26 | @Suppress("EnumNaming") 27 | enum class SpeedDialState { 28 | /** 29 | * State that means a component is collapsed 30 | */ 31 | Collapsed, 32 | 33 | /** 34 | * State that means a component is expanded 35 | */ 36 | Expanded; 37 | 38 | fun toggle(): SpeedDialState = if (this == Expanded) Collapsed else Expanded 39 | fun isExpanded() = this == Expanded 40 | } 41 | 42 | /** 43 | * Return corresponding SpeedDialState based on a Boolean representation 44 | * 45 | * @param value whether the SpeedDialState is Expanded or Collapsed 46 | */ 47 | 48 | val LocalSpeedDialState: ProvidableCompositionLocal> = compositionLocalOf { error("No SpeedDialState provided") } 49 | -------------------------------------------------------------------------------- /library-view/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /library-view/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id 'speeddial.android-library-conventions' 19 | id 'speeddial.artifact-publish-library-conventions' 20 | alias(libs.plugins.errorprone) 21 | // alias(libs.plugins.checkstyle) // TODO 22 | } 23 | 24 | ext { 25 | PUBLISH_GROUP_ID = 'com.leinardi.android' 26 | PUBLISH_VERSION = config.android.version_name_view 27 | PUBLISH_ARTIFACT_ID = 'speed-dial' 28 | } 29 | 30 | android { 31 | defaultConfig { 32 | versionName config.android.version_name_view 33 | consumerProguardFiles 'consumer-proguard-rules.pro' 34 | } 35 | } 36 | 37 | tasks.withType(JavaCompile) { 38 | // remove the if condition if you want to run NullAway on test code 39 | if (!name.toLowerCase().contains("test")) { 40 | options.errorprone { 41 | check("NullAway", net.ltgt.gradle.errorprone.CheckSeverity.ERROR) 42 | option("NullAway:AnnotatedPackages", "com.leinardi.android.speeddial") 43 | } 44 | } 45 | } 46 | 47 | dependencies { 48 | api libs.androidx.appcompat 49 | api libs.androidx.cardview 50 | api libs.material 51 | annotationProcessor libs.nullaway 52 | errorprone libs.errorprone.core 53 | errorproneJavac libs.errorprone.javac 54 | } 55 | -------------------------------------------------------------------------------- /library-view/consumer-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 /home/arthur/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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | -keepclassmembernames class com.google.android.material.floatingactionbutton.FloatingActionButton { 28 | com.google.android.material.floatingactionbutton.FloatingActionButtonImpl impl; 29 | } 30 | -keepclassmembernames class com.google.android.material.floatingactionbutton.FloatingActionButtonImpl { void setImageMatrixScale(float); } 31 | -------------------------------------------------------------------------------- /library-view/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /library-view/src/main/java/com/leinardi/android/speeddial/SpeedDialOverlayLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial; 18 | 19 | import android.content.Context; 20 | import android.content.res.TypedArray; 21 | import android.os.Build; 22 | import android.util.AttributeSet; 23 | import android.util.Log; 24 | import android.view.View; 25 | import android.widget.RelativeLayout; 26 | 27 | import androidx.annotation.AttrRes; 28 | import androidx.annotation.NonNull; 29 | import androidx.annotation.Nullable; 30 | import androidx.core.content.res.ResourcesCompat; 31 | 32 | @SuppressWarnings({"unused", "WeakerAccess"}) 33 | public class SpeedDialOverlayLayout extends RelativeLayout { 34 | private static final String TAG = SpeedDialOverlayLayout.class.getSimpleName(); 35 | private boolean mClickableOverlay; 36 | private int mAnimationDuration; 37 | @Nullable 38 | private OnClickListener mClickListener; 39 | 40 | public SpeedDialOverlayLayout(@NonNull Context context) { 41 | super(context); 42 | } 43 | 44 | public SpeedDialOverlayLayout(@NonNull Context context, @Nullable AttributeSet attrs) { 45 | super(context, attrs); 46 | init(context, attrs); 47 | } 48 | 49 | public SpeedDialOverlayLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int 50 | defStyleAttr) { 51 | super(context, attrs, defStyleAttr); 52 | init(context, attrs); 53 | } 54 | 55 | public boolean hasClickableOverlay() { 56 | return mClickableOverlay; 57 | } 58 | 59 | /** 60 | * Enables or disables the click on the overlay view. 61 | * 62 | * @param clickableOverlay True to enable the click, false otherwise. 63 | */ 64 | public void setClickableOverlay(boolean clickableOverlay) { 65 | mClickableOverlay = clickableOverlay; 66 | setOnClickListener(mClickListener); 67 | } 68 | 69 | public void setAnimationDuration(int animationDuration) { 70 | mAnimationDuration = animationDuration; 71 | } 72 | 73 | public void show() { 74 | show(true); 75 | } 76 | 77 | public void show(boolean animate) { 78 | if (animate) { 79 | UiUtils.fadeInAnim(this); 80 | } else { 81 | setVisibility(VISIBLE); 82 | } 83 | } 84 | 85 | public void hide() { 86 | hide(true); 87 | } 88 | 89 | public void hide(boolean animate) { 90 | if (animate) { 91 | UiUtils.fadeOutAnim(this); 92 | } else { 93 | setVisibility(GONE); 94 | } 95 | } 96 | 97 | @Override 98 | public void setOnClickListener(@Nullable OnClickListener clickListener) { 99 | mClickListener = clickListener; 100 | super.setOnClickListener(hasClickableOverlay() ? clickListener : null); 101 | } 102 | 103 | private void init(Context context, @Nullable AttributeSet attrs) { 104 | TypedArray attr = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SpeedDialOverlayLayout, 0, 0); 105 | int overlayColor = ResourcesCompat.getColor(getResources(), R.color.sd_overlay_color, context.getTheme()); 106 | try { 107 | overlayColor = attr.getColor(R.styleable.SpeedDialOverlayLayout_android_background, overlayColor); 108 | mClickableOverlay = attr.getBoolean(R.styleable.SpeedDialOverlayLayout_clickable_overlay, true); 109 | } catch (Exception e) { 110 | Log.e(TAG, "Failure setting FabOverlayLayout attrs", e); 111 | } finally { 112 | attr.recycle(); 113 | } 114 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 115 | setElevation(getResources().getDimension(R.dimen.sd_overlay_elevation)); 116 | } 117 | setBackgroundColor(overlayColor); 118 | setVisibility(View.GONE); 119 | mAnimationDuration = getResources().getInteger(android.R.integer.config_longAnimTime); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /library-view/src/main/java/com/leinardi/android/speeddial/ViewGroupUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial; 18 | 19 | import android.graphics.Matrix; 20 | import android.graphics.Rect; 21 | import android.graphics.RectF; 22 | import android.view.View; 23 | import android.view.ViewGroup; 24 | import android.view.ViewParent; 25 | 26 | class ViewGroupUtils { 27 | private static final ThreadLocal MATRIX_THREAD_LOCAL = new ThreadLocal<>(); 28 | private static final ThreadLocal RECT_F = new ThreadLocal<>(); 29 | 30 | private ViewGroupUtils() { 31 | } 32 | 33 | /** 34 | * This is a port of the common 35 | * {@link ViewGroup#offsetDescendantRectToMyCoords(View, Rect)} 36 | * from the framework, but adapted to take transformations into account. The result 37 | * will be the bounding rect of the real transformed rect. 38 | * 39 | * @param descendant view defining the original coordinate system of rect 40 | * @param rect (in/out) the rect to offset from descendant to this view's coordinate system 41 | */ 42 | static void offsetDescendantRect(ViewGroup parent, View descendant, Rect rect) { 43 | Matrix m = MATRIX_THREAD_LOCAL.get(); 44 | if (m == null) { 45 | m = new Matrix(); 46 | MATRIX_THREAD_LOCAL.set(m); 47 | } else { 48 | m.reset(); 49 | } 50 | 51 | offsetDescendantMatrix(parent, descendant, m); 52 | 53 | RectF rectF = RECT_F.get(); 54 | if (rectF == null) { 55 | rectF = new RectF(); 56 | RECT_F.set(rectF); 57 | } 58 | rectF.set(rect); 59 | m.mapRect(rectF); 60 | rect.set((int) (rectF.left + 0.5f), (int) (rectF.top + 0.5f), 61 | (int) (rectF.right + 0.5f), (int) (rectF.bottom + 0.5f)); 62 | } 63 | 64 | /** 65 | * Retrieve the transformed bounding rect of an arbitrary descendant view. 66 | * This does not need to be a direct child. 67 | * 68 | * @param descendant descendant view to reference 69 | * @param out rect to set to the bounds of the descendant view 70 | */ 71 | static void getDescendantRect(ViewGroup parent, View descendant, Rect out) { 72 | out.set(0, 0, descendant.getWidth(), descendant.getHeight()); 73 | offsetDescendantRect(parent, descendant, out); 74 | } 75 | 76 | private static void offsetDescendantMatrix(ViewParent target, View view, Matrix m) { 77 | final ViewParent parent = view.getParent(); 78 | if (parent instanceof View && parent != target) { 79 | final View vp = (View) parent; 80 | offsetDescendantMatrix(target, vp, m); 81 | m.preTranslate(-vp.getScrollX(), -vp.getScrollY()); 82 | } 83 | 84 | m.preTranslate(view.getLeft(), view.getTop()); 85 | 86 | if (!view.getMatrix().isIdentity()) { 87 | m.preConcat(view.getMatrix()); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /library-view/src/main/res/anim/sd_fade_and_translate_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 21 | 25 | 26 | 30 | 31 | -------------------------------------------------------------------------------- /library-view/src/main/res/anim/sd_fade_and_translate_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 21 | 25 | 26 | 30 | 31 | -------------------------------------------------------------------------------- /library-view/src/main/res/anim/sd_scale_fade_and_translate_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 21 | 29 | 30 | 34 | 35 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /library-view/src/main/res/anim/sd_scale_fade_and_translate_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 21 | 29 | 30 | 34 | 35 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /library-view/src/main/res/layout/sd_fab_with_label_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | 34 | 35 | 41 | 42 | 43 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /library-view/src/main/res/layout/sd_fill_fab.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 21 | 22 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /library-view/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | #bdbdbd 20 | @color/cardview_dark_background 21 | #aa000000 22 | 23 | -------------------------------------------------------------------------------- /library-view/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /library-view/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 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 | -------------------------------------------------------------------------------- /library-view/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | #757575 20 | @color/cardview_light_background 21 | #aaffffff 22 | 23 | -------------------------------------------------------------------------------- /library-view/src/main/res/values/configs.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 200 20 | 150 21 | 200 22 | 23 | -------------------------------------------------------------------------------- /library-view/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 5dp 20 | 54dp 21 | 72dp 22 | 12dp| 23 | 160dp 24 | 8dp 25 | @dimen/sd_close_elevation 26 | 27 | -------------------------------------------------------------------------------- /library-view/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /library-view/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | com.leinardi.android.speeddial.SpeedDialView$SnackbarBehavior 21 | 22 | 23 | com.leinardi.android.speeddial.SpeedDialView$ScrollingViewSnackbarBehavior 24 | 25 | 26 | -------------------------------------------------------------------------------- /library-view/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 33 | 34 | 37 | 38 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id 'speeddial.android-sample-conventions' 19 | } 20 | 21 | android { 22 | defaultConfig { 23 | applicationId config.android.applicationId 24 | archivesBaseName = "floating_action_button_speed_dial" 25 | versionName config.android.version_name_sample 26 | minSdk config.android.minSdkCompose 27 | 28 | vectorDrawables { 29 | useSupportLibrary true 30 | } 31 | } 32 | 33 | def isKeystoreInfoAvailable = file(KEYSTORE_PATH).exists() && file(KEYSTORE_PROPERTIES_PATH).exists() 34 | 35 | signingConfigs { 36 | if (isKeystoreInfoAvailable) { 37 | release { 38 | Properties props = new Properties() 39 | props.load(new FileInputStream(file(KEYSTORE_PROPERTIES_PATH))) 40 | storeFile file(KEYSTORE_PATH) 41 | storePassword props['store.password'] 42 | keyAlias props['key.alias'] 43 | keyPassword props['key.password'] 44 | } 45 | } 46 | } 47 | 48 | buildTypes { 49 | if (isKeystoreInfoAvailable) { 50 | release { 51 | minifyEnabled true 52 | shrinkResources true 53 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 54 | signingConfig signingConfigs.release 55 | } 56 | } 57 | debug { 58 | applicationIdSuffix '.debug' 59 | versionNameSuffix '-DEBUG' 60 | } 61 | } 62 | } 63 | 64 | dependencies { 65 | implementation projects.libraryView 66 | // implementation "com.leinardi.android:speed-dial:${config.android.version_name_view}" 67 | implementation libs.androidx.core.ktx 68 | implementation libs.androidx.constraintlayout 69 | implementation libs.androidx.recyclerview 70 | 71 | implementation projects.libraryCompose 72 | // implementation "com.leinardi.android:speed-dial.compose:${config.android.version_name_compose}" 73 | implementation libs.accompanist.systemuicontroller 74 | implementation libs.androidx.activity.compose 75 | implementation libs.androidx.compose.material 76 | implementation libs.androidx.compose.runtime 77 | implementation libs.androidx.compose.tooling 78 | implementation libs.androidx.compose.ui 79 | implementation libs.coroutines.core 80 | implementation libs.coroutines.android 81 | } 82 | -------------------------------------------------------------------------------- /sample/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\Admin\AppData\Local\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 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 19 | 20 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 50 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/CustomAdapter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample 18 | 19 | import android.view.LayoutInflater 20 | import android.view.View 21 | import android.view.ViewGroup 22 | import android.widget.TextView 23 | import androidx.recyclerview.widget.RecyclerView 24 | import timber.log.Timber 25 | 26 | /** 27 | * Provide views to RecyclerView with data from dataSet. 28 | */ 29 | class CustomAdapter(private val dataSet: Array) : RecyclerView.Adapter() { 30 | override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder = 31 | ViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.text_row_item, viewGroup, false)) 32 | 33 | override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { 34 | viewHolder.textView.text = dataSet[position] 35 | } 36 | 37 | override fun getItemCount() = dataSet.size 38 | 39 | /** 40 | * Provide a reference to the type of views that you are using (custom ViewHolder) 41 | */ 42 | class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { 43 | val textView: TextView 44 | 45 | init { 46 | // Define click listener for the ViewHolder's View. 47 | view.setOnClickListener { Timber.d("Element $bindingAdapterPosition clicked.") } 48 | textView = view.findViewById(R.id.textView) 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/SampleApp.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample 18 | 19 | import android.app.Application 20 | import timber.log.Timber 21 | 22 | class SampleApp : Application() { 23 | override fun onCreate() { 24 | super.onCreate() 25 | if (BuildConfig.DEBUG) { 26 | Timber.plant(Timber.DebugTree()) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/compose/component/TopAppBar.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.compose.component 18 | 19 | import androidx.compose.foundation.layout.Box 20 | import androidx.compose.foundation.layout.Column 21 | import androidx.compose.foundation.layout.RowScope 22 | import androidx.compose.foundation.layout.fillMaxWidth 23 | import androidx.compose.material.AppBarDefaults 24 | import androidx.compose.material.ContentAlpha 25 | import androidx.compose.material.Icon 26 | import androidx.compose.material.IconButton 27 | import androidx.compose.material.LocalContentAlpha 28 | import androidx.compose.material.MaterialTheme 29 | import androidx.compose.material.ProvideTextStyle 30 | import androidx.compose.material.Text 31 | import androidx.compose.material.icons.Icons 32 | import androidx.compose.material.icons.filled.ArrowBack 33 | import androidx.compose.material.icons.filled.Share 34 | import androidx.compose.runtime.Composable 35 | import androidx.compose.runtime.CompositionLocalProvider 36 | import androidx.compose.ui.Alignment 37 | import androidx.compose.ui.Modifier 38 | import androidx.compose.ui.draw.alpha 39 | import androidx.compose.ui.text.style.TextAlign 40 | import androidx.compose.ui.tooling.preview.Preview 41 | import androidx.compose.ui.unit.Dp 42 | import com.google.accompanist.systemuicontroller.rememberSystemUiController 43 | import com.leinardi.android.speeddial.sample.compose.theme.SampleTheme 44 | 45 | @Composable 46 | fun TopAppBar( 47 | title: String, 48 | modifier: Modifier = Modifier, 49 | subtitle: String? = null, 50 | onNavigateUp: (() -> Unit)? = null, 51 | titleCentered: Boolean = false, 52 | elevation: Dp = AppBarDefaults.TopAppBarElevation, 53 | actions: @Composable RowScope.() -> Unit = {}, 54 | ) { 55 | val systemUiController = rememberSystemUiController() 56 | systemUiController.setSystemBarsColor(MaterialTheme.colors.primaryVariant) 57 | Box { 58 | androidx.compose.material.TopAppBar( 59 | title = { 60 | if (!titleCentered) { 61 | Column { 62 | Text(text = title) 63 | if (!subtitle.isNullOrEmpty()) { 64 | Text( 65 | text = subtitle, 66 | style = MaterialTheme.typography.subtitle1, 67 | modifier = Modifier.alpha(ContentAlpha.medium), 68 | ) 69 | } 70 | } 71 | } 72 | }, 73 | modifier = modifier, 74 | navigationIcon = onNavigateUp?.let { 75 | { 76 | IconButton( 77 | onClick = it, 78 | ) { 79 | Icon( 80 | imageVector = Icons.Default.ArrowBack, 81 | contentDescription = null, 82 | ) 83 | } 84 | } 85 | }, 86 | actions = actions, 87 | backgroundColor = MaterialTheme.colors.primary, 88 | elevation = elevation, 89 | ) 90 | if (titleCentered) { 91 | ProvideTextStyle(value = MaterialTheme.typography.h5) { 92 | CompositionLocalProvider( 93 | LocalContentAlpha provides ContentAlpha.high, 94 | ) { 95 | Text( 96 | text = title, 97 | color = MaterialTheme.colors.primary, 98 | textAlign = TextAlign.Center, 99 | modifier = Modifier 100 | .fillMaxWidth() 101 | .align(Alignment.Center), 102 | ) 103 | } 104 | } 105 | } 106 | } 107 | } 108 | 109 | @Composable 110 | @Preview 111 | fun PreviewTopAppBarWithNavigationIcon() { 112 | SampleTheme { 113 | TopAppBar( 114 | title = "Page title", 115 | ) { } 116 | } 117 | } 118 | 119 | @Composable 120 | @Preview 121 | fun PreviewTopAppBarWithSubtitle() { 122 | SampleTheme { 123 | TopAppBar( 124 | title = "Page title", 125 | subtitle = "Page subtitle", 126 | ) { } 127 | } 128 | } 129 | 130 | @Composable 131 | @Preview 132 | fun PreviewTopAppBarWithAction() { 133 | SampleTheme { 134 | TopAppBar( 135 | title = "Page title", 136 | actions = { 137 | IconButton(onClick = {}) { 138 | Icon(Icons.Default.Share, contentDescription = "") 139 | } 140 | }, 141 | ) 142 | } 143 | } 144 | 145 | @Composable 146 | @Preview 147 | fun PreviewTopAppBarWithNavigationIconAndAction() { 148 | SampleTheme { 149 | TopAppBar( 150 | title = "Page title", 151 | actions = { 152 | IconButton(onClick = {}) { 153 | Icon(Icons.Default.Share, contentDescription = "") 154 | } 155 | }, 156 | onNavigateUp = { }, 157 | ) 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/compose/theme/Color.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.compose.theme 18 | 19 | import androidx.compose.material.Colors 20 | import androidx.compose.material.MaterialTheme 21 | import androidx.compose.material.darkColors 22 | import androidx.compose.material.lightColors 23 | import androidx.compose.runtime.Composable 24 | import androidx.compose.ui.graphics.Color 25 | 26 | val SampleLightColors = lightColors( 27 | primary = Color(0XFF4285F4), 28 | primaryVariant = Color(0XFF3367D6), 29 | secondary = Color(0XFFDB4437), 30 | secondaryVariant = Color(0XFFC62828), 31 | background = Color(0XFFFFFFFF), 32 | surface = Color(0XFFFFFFFF), 33 | error = Color(0XFFE53935), 34 | onPrimary = Color(0XFFFFFFFF), 35 | onSecondary = Color(0XFFFFFFFF), 36 | onBackground = Color(0XFF191C1B), 37 | onSurface = Color(0XFF191C1B), 38 | onError = Color(0XFFFFFFFF), 39 | ) 40 | val SampleDarkColors = darkColors( 41 | primary = Color(0xFFCE93D8), 42 | primaryVariant = Color(0xFF8E24AA), 43 | secondary = Color(0xFFA5D6A7), 44 | secondaryVariant = Color(0xFF4CAF50), 45 | background = Color(0xFF212121), 46 | surface = Color(0xFF424242), 47 | error = Color(0xFFEF9A9A), 48 | onPrimary = Color(0xFF212121), 49 | onSecondary = Color(0xFF212121), 50 | onBackground = Color(0XFFFFFFFF), 51 | onSurface = Color(0XFFFFFFFF), 52 | onError = Color(0xFF212121), 53 | ) 54 | 55 | val Colors.textPrimary: Color 56 | @Composable 57 | get() = MaterialTheme.colors.onSurface.copy(alpha = 0.87f) 58 | 59 | val Colors.textSecondary: Color 60 | @Composable 61 | get() = MaterialTheme.colors.onSurface.copy(alpha = 0.60f) 62 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/compose/theme/SampleTheme.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.compose.theme 18 | 19 | import androidx.compose.foundation.isSystemInDarkTheme 20 | import androidx.compose.material.MaterialTheme 21 | import androidx.compose.material.lightColors 22 | import androidx.compose.material.ripple.LocalRippleTheme 23 | import androidx.compose.material.ripple.RippleAlpha 24 | import androidx.compose.material.ripple.RippleTheme 25 | import androidx.compose.runtime.Composable 26 | import androidx.compose.runtime.CompositionLocalProvider 27 | import androidx.compose.ui.graphics.Color 28 | 29 | @Composable 30 | fun SampleTheme( 31 | isDarkTheme: Boolean = isSystemInDarkTheme(), 32 | content: @Composable () -> Unit, 33 | ) { 34 | MaterialTheme( 35 | colors = if (isDarkTheme) SampleDarkColors else SampleLightColors, 36 | typography = SampleTypography, 37 | shapes = SampleShapes, 38 | content = content, 39 | ) 40 | } 41 | 42 | @Composable 43 | fun PurpleTheme( 44 | content: @Composable () -> Unit, 45 | ) { 46 | MaterialTheme( 47 | colors = lightColors( 48 | primary = Color(0XFF9C27B0), 49 | primaryVariant = Color(0XFF7B1FA2), 50 | secondary = Color(0XFFAA00FF), 51 | onSecondary = Color(0XFFE1BEE7), 52 | ), 53 | typography = SampleTypography, 54 | shapes = SampleShapes, 55 | ) { 56 | CompositionLocalProvider( 57 | LocalRippleTheme provides PurpleRippleTheme, 58 | content = content, 59 | ) 60 | } 61 | } 62 | 63 | private object PurpleRippleTheme : RippleTheme { 64 | // Here you should return the ripple color you want 65 | // and not use the defaultRippleColor extension on RippleTheme. 66 | // Using that will override the ripple color set in DarkMode 67 | // or when you set light parameter to false 68 | @Composable 69 | override fun defaultColor(): Color = MaterialTheme.colors.primary 70 | 71 | @Composable 72 | override fun rippleAlpha(): RippleAlpha = RippleTheme.defaultRippleAlpha( 73 | Color.Black, 74 | lightTheme = !isSystemInDarkTheme(), 75 | ) 76 | } 77 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/compose/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.compose.theme 18 | 19 | import androidx.compose.material.Shapes 20 | 21 | val SampleShapes = Shapes() 22 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/compose/theme/Type.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.compose.theme 18 | 19 | import androidx.compose.material.Typography 20 | 21 | val SampleTypography = Typography() 22 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/interactor/GetVersionInteractor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.interactor 18 | 19 | import android.content.Context 20 | 21 | class GetVersionInteractor { 22 | operator fun invoke(context: Context): String { 23 | val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0) 24 | return packageInfo?.versionName ?: "Undefined" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/interactor/ToggleNightModeInteractor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.interactor 18 | 19 | import android.content.Context 20 | import android.content.res.Configuration 21 | import androidx.appcompat.app.AppCompatDelegate 22 | 23 | class ToggleNightModeInteractor { 24 | operator fun invoke(context: Context) { 25 | val nightModeFlats = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK 26 | if (nightModeFlats == Configuration.UI_MODE_NIGHT_NO) { 27 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) 28 | } else { 29 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/usecases/UseCase1Activity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.usecases 18 | 19 | import com.leinardi.android.speeddial.sample.R 20 | 21 | class UseCase1Activity : BaseUseCaseActivity() { 22 | override val layoutRes = R.layout.activity_use_case_1 23 | } 24 | -------------------------------------------------------------------------------- /sample/src/main/kotlin/com/leinardi/android/speeddial/sample/usecases/UseCasesActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leinardi.android.speeddial.sample.usecases 18 | 19 | import android.content.Intent 20 | import android.os.Bundle 21 | import androidx.appcompat.app.AppCompatActivity 22 | import androidx.appcompat.widget.Toolbar 23 | import com.leinardi.android.speeddial.SpeedDialView 24 | import com.leinardi.android.speeddial.sample.R 25 | 26 | class UseCasesActivity : AppCompatActivity() { 27 | override fun onCreate(savedInstanceState: Bundle?) { 28 | super.onCreate(savedInstanceState) 29 | setContentView(R.layout.activity_use_cases) 30 | setSupportActionBar(findViewById(R.id.toolbar)) 31 | val speedDialView = findViewById(R.id.speedDial) 32 | speedDialView.inflate(R.menu.menu_use_cases) 33 | speedDialView.open() 34 | speedDialView.setOnActionSelectedListener { 35 | startActivity(Intent(this@UseCasesActivity, UseCase1Activity::class.java)) 36 | true 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sample/src/main/res/anim/bottom_sheet_slide_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | 25 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /sample/src/main/res/anim/bottom_sheet_slide_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | 25 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_custom_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-hdpi/ic_custom_color.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_lorem_ipsum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-hdpi/ic_lorem_ipsum.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_custom_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-mdpi/ic_custom_color.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_lorem_ipsum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-mdpi/ic_lorem_ipsum.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_custom_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-xhdpi/ic_custom_color.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_lorem_ipsum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-xhdpi/ic_lorem_ipsum.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_custom_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-xxhdpi/ic_custom_color.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_lorem_ipsum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-xxhdpi/ic_lorem_ipsum.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_custom_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-xxxhdpi/ic_custom_color.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxxhdpi/ic_lorem_ipsum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/drawable-xxxhdpi/ic_lorem_ipsum.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_add_action_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_add_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_animation_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_close_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_day_night_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_delete_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_expansion_mode_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_link_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_list_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_pencil_alt_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_replace_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_rotation_angle_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_show_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_snack_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_theme_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_use_case_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | 25 | 30 | 31 | 38 | 39 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_use_case_1.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 25 | 26 | 27 | 28 | 33 | 34 | 39 | 40 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_use_cases.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | 25 | 28 | 29 | 34 | 35 | 36 | 37 | 41 | 42 | 46 | 47 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/appbarlayout.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 | 24 | 25 | 30 | 31 | 37 | 38 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/text_row_item.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 26 | 27 | 35 | 36 | -------------------------------------------------------------------------------- /sample/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 21 | 27 | 28 | -------------------------------------------------------------------------------- /sample/src/main/res/menu/menu_use_cases.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leinardi/FloatingActionButtonSpeedDial/20daccfd1ed718f3dfbf18ce2712090ededd9fdc/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/values-it/strings.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | Aggiungi action item 19 | Rimuovi action item 20 | Mostra/Nascondi FAB 21 | Mostra snackbar 22 | Alterna modalità Day/Night 23 | Toggle lista 24 | Toggle reverse animation in chiususa 25 | Casi d\'uso 26 | FAB Speed Dial Sample 27 | FAB Speed Dial Sample Compose 28 | v%1$s 29 | Basso 30 | Chiudi menu Speed Dial 31 | Modalità espansione 32 | 45 gradi 33 | Aggiungi action 34 | Colori custom 35 | Tema custom 36 | Rimuovi action 37 | Sostituisci action 38 | Sinistra 39 | Main action cliccato! 40 | Colore Main FAB 41 | Colore Main FAB chiuso 42 | Colore Main FAB aperto 43 | 90 gradi 44 | No label action cliccliccatoked! 45 | Nessuno 46 | 180 gradi 47 | Arancione 48 | Primary 49 | Viola 50 | Destra 51 | Angolo rotazione 52 | Test Snackbar 53 | Alto 54 | Setup minimo 55 | Bianco 56 | 0 gradi 57 | 58 | -------------------------------------------------------------------------------- /sample/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 36 | 37 | -------------------------------------------------------------------------------- /sample/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 21 | 64dp 22 | 23 | -------------------------------------------------------------------------------- /sample/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 16dp 20 | 16dp 21 | 16dp 22 | 200dp 23 | 24 | -------------------------------------------------------------------------------- /sample/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /sample/src/main/res/values/motion.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /sample/src/main/res/values/shape.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 45 | 46 | 47 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | Add action item 19 | Remove action item 20 | Show/hide FAB 21 | Show snackbar 22 | Toggle Day/Night mode 23 | Toggle list 24 | Toggle reverse animation on close 25 | Use cases 26 | FAB Speed Dial Sample 27 | FAB Speed Dial Sample Compose 28 | v%1$s 29 | Bottom 30 | Close Speed Dial menu 31 | Expansion mode 32 | 45 degrees 33 | Add action 34 | Custom colors 35 | Custom theme 36 | Remove action 37 | Replace action 38 | Left 39 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 40 | Main action clicked! 41 | Main FAB color 42 | Main FAB color close 43 | Main FAB color open 44 | 90 degrees 45 | No label action clicked!\nClosing with animation! 46 | None 47 | 180 degrees 48 | Orange 49 | Primary 50 | Purple 51 | Right 52 | Rotation angle 53 | Test snackbar 54 | Top 55 | Minimal setup 56 | White 57 | 0 degrees 58 | 59 | -------------------------------------------------------------------------------- /sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 33 | 34 | 37 | 38 | 39 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /sample/src/main/res/values/themes_compose.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 24 | 25 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /sample/src/main/res/values/type.xml: -------------------------------------------------------------------------------- 1 | 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 | 43 | 44 | 47 | 48 | 51 | 52 | 55 | 56 | 59 | 60 | 63 | 64 | 67 | 68 | 71 | 72 | 75 | 76 | 79 | 80 | 83 | 84 | 87 | 88 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /sample/versions/dependencies/debugAndroidTestRuntimeClasspathDependencies.txt: -------------------------------------------------------------------------------- 1 | 2 | ------------------------------------------------------------ 3 | Project ':sample' 4 | ------------------------------------------------------------ 5 | 6 | debugAndroidTestRuntimeClasspath - Runtime classpath of compilation 'debugAndroidTest' (target (androidJvm)). 7 | +--- androidx.test.espresso:espresso-core:3.3.0 8 | | +--- androidx.test:runner:1.3.0 -> 1.4.0 9 | | | +--- androidx.annotation:annotation:1.0.0 -> 1.3.0 10 | | | +--- androidx.test:monitor:1.4.0 11 | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.3.0 12 | | | +--- androidx.test.services:storage:1.4.0 13 | | | | +--- androidx.test:monitor:1.4.0 (*) 14 | | | | \--- com.google.code.findbugs:jsr305:2.0.1 15 | | | \--- junit:junit:4.12 16 | | | \--- org.hamcrest:hamcrest-core:1.3 17 | | +--- androidx.test.espresso:espresso-idling-resource:3.3.0 18 | | +--- com.squareup:javawriter:2.1.1 19 | | +--- javax.inject:javax.inject:1 20 | | +--- org.hamcrest:hamcrest-library:1.3 21 | | | \--- org.hamcrest:hamcrest-core:1.3 22 | | +--- org.hamcrest:hamcrest-integration:1.3 23 | | | \--- org.hamcrest:hamcrest-library:1.3 (*) 24 | | \--- com.google.code.findbugs:jsr305:2.0.1 25 | +--- androidx.test.ext:junit-ktx:1.1.3 26 | | +--- androidx.test.ext:junit:1.1.3 27 | | | +--- junit:junit:4.12 (*) 28 | | | +--- androidx.test:core:1.4.0 29 | | | | +--- androidx.annotation:annotation:1.0.0 -> 1.3.0 30 | | | | +--- androidx.test:monitor:1.4.0 (*) 31 | | | | \--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.4.0 32 | | | | \--- androidx.annotation:annotation:1.1.0 -> 1.3.0 33 | | | +--- androidx.test:monitor:1.4.0 (*) 34 | | | \--- androidx.annotation:annotation:1.0.0 -> 1.3.0 35 | | \--- androidx.lifecycle:lifecycle-common:2.0.0 -> 2.4.0 (*) 36 | +--- androidx.test:runner:1.4.0 (*) 37 | +--- androidx.lifecycle:lifecycle-common:{strictly 2.4.0} -> 2.4.0 (c) 38 | \--- androidx.annotation:annotation:{strictly 1.3.0} -> 1.3.0 (c) 39 | 40 | (c) - dependency constraint 41 | (*) - dependencies omitted (listed previously) 42 | 43 | A web-based, searchable dependency report is available by adding the --scan option. 44 | -------------------------------------------------------------------------------- /sample/versions/mergedManifests/release/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 25 | 26 | 34 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 56 | 60 | 63 | 64 | 68 | 71 | 74 | 77 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Roberto Leinardi. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // https://docs.gradle.org/7.0/userguide/declaring_dependencies.html#sec:type-safe-project-accessors 18 | enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") 19 | 20 | dependencyResolutionManagement { 21 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 22 | repositories { 23 | google() 24 | mavenCentral() 25 | } 26 | } 27 | 28 | rootProject.name = "FloatingActionButtonSpeedDial" 29 | 30 | includeBuild("build-conventions") 31 | 32 | include( 33 | // Libs 34 | ':library-compose', 35 | ':library-view', 36 | 37 | // Apps 38 | ':sample', 39 | ) 40 | --------------------------------------------------------------------------------