Showing preview only (704K chars total). Download the full file or copy to clipboard to get everything.
Repository: mikepenz/MaterialDrawer
Branch: develop
Commit: c6e3f78e0e0f
Files: 219
Total size: 639.4 KB
Directory structure:
gitextract_to5pn2i8/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE.md
│ ├── ci-gradle.properties
│ ├── config/
│ │ └── configuration.json
│ ├── dependabot.yml
│ └── workflows/
│ ├── ci.yml
│ └── gradle-dependency-submission.yml
├── .gitignore
├── Dangerfile
├── FAQ/
│ ├── accountheader_single_profile_without_dropdown.md
│ ├── howto_modify_add_custom_draweritems.md
│ ├── howto_use_different_sub_library_version.md
│ ├── opening-drawer-from-espresso.md
│ └── when_to_use_this_library.md
├── FAQ.md
├── Gemfile
├── LICENSE
├── MIGRATION.md
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── gradle.properties
│ ├── proguard-rules.pro
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── com/
│ │ └── mikepenz/
│ │ └── materialdrawer/
│ │ └── app/
│ │ ├── ActionBarActivity.kt
│ │ ├── AdvancedActivity.kt
│ │ ├── CollapsingToolbarActivity.kt
│ │ ├── CompactHeaderDrawerActivity.kt
│ │ ├── CrossfadeDrawerLayoutActvitiy.kt
│ │ ├── CustomApplication.kt
│ │ ├── DrawerActivity.kt
│ │ ├── EmbeddedDrawerActivity.kt
│ │ ├── FragmentActivity.kt
│ │ ├── FullscreenDrawerActivity.kt
│ │ ├── MenuDrawerActivity.kt
│ │ ├── MiniDrawerActivity.kt
│ │ ├── MultiDrawerActivity.kt
│ │ ├── NavControllerActivity.kt
│ │ ├── PersistentDrawerActivity.kt
│ │ ├── drawerItems/
│ │ │ ├── AccountDividerDrawerItem.kt
│ │ │ ├── CustomBaseViewHolder.kt
│ │ │ ├── CustomCenteredPrimaryDrawerItem.kt
│ │ │ ├── CustomPrimaryDrawerItem.kt
│ │ │ ├── CustomUrlBasePrimaryDrawerItem.kt
│ │ │ ├── CustomUrlPrimaryDrawerItem.kt
│ │ │ ├── GmailDrawerItem.kt
│ │ │ ├── IconDrawerItem.kt
│ │ │ └── OverflowMenuDrawerItem.kt
│ │ ├── fragment/
│ │ │ ├── DemoFragment.kt
│ │ │ ├── DemoMessageFragment.kt
│ │ │ ├── DrawerFragment.kt
│ │ │ └── SecondDrawerFragment.kt
│ │ ├── utils/
│ │ │ ├── CrossfadeWrapper.kt
│ │ │ ├── SystemUtils.kt
│ │ │ └── UIUtils.kt
│ │ └── widget/
│ │ └── CrossfadeDrawerLayout.kt
│ └── res/
│ ├── layout/
│ │ ├── activity_embedded.xml
│ │ ├── activity_mini_drawer.xml
│ │ ├── activity_multi_sample.xml
│ │ ├── activity_persistent_drawer.xml
│ │ ├── activity_sample.xml
│ │ ├── activity_sample_actionbar.xml
│ │ ├── activity_sample_collapsing_toolbar.xml
│ │ ├── activity_sample_crossfader.xml
│ │ ├── activity_sample_fragment.xml
│ │ ├── activity_sample_fullscreen.xml
│ │ ├── activity_sample_nav.xml
│ │ ├── footer.xml
│ │ ├── fragment_message_sample.xml
│ │ ├── fragment_sample.xml
│ │ ├── fragment_simple_sample.xml
│ │ ├── header.xml
│ │ ├── material_drawer_compact_persistent_header.xml
│ │ ├── material_drawer_item_icon_only.xml
│ │ ├── material_drawer_item_overflow_menu_primary.xml
│ │ └── material_drawer_item_primary_centered.xml
│ ├── menu/
│ │ ├── cab.xml
│ │ ├── embedded.xml
│ │ ├── example_menu.xml
│ │ ├── fragment_menu.xml
│ │ └── main.xml
│ ├── mipmap-anydpi-v26/
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ ├── navigation/
│ │ └── navigation.xml
│ └── values/
│ ├── colors.xml
│ ├── dimens.xml
│ ├── ic_launcher_background.xml
│ ├── ids.xml
│ ├── strings.xml
│ ├── styles.xml
│ └── themes.xml
├── build.gradle.kts
├── gradle/
│ ├── libs.versions.toml
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── materialdrawer/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── gradle.properties
│ ├── proguard-rules.txt
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── com/
│ │ └── mikepenz/
│ │ └── materialdrawer/
│ │ ├── holder/
│ │ │ ├── BadgeStyle.kt
│ │ │ ├── ColorHolder.kt
│ │ │ ├── DimenHolder.kt
│ │ │ ├── ImageHolder.kt
│ │ │ └── StringHolder.kt
│ │ ├── interfaces/
│ │ │ ├── ICrossfader.kt
│ │ │ ├── OnCheckedChangeListener.kt
│ │ │ └── OnPostBindViewListener.kt
│ │ ├── model/
│ │ │ ├── AbstractBadgeableDrawerItem.kt
│ │ │ ├── AbstractDrawerItem.kt
│ │ │ ├── AbstractSwitchableDrawerItem.kt
│ │ │ ├── AbstractToggleableDrawerItem.kt
│ │ │ ├── BaseDescribeableDrawerItem.kt
│ │ │ ├── BaseDrawerItem.kt
│ │ │ ├── BaseViewHolder.kt
│ │ │ ├── ContainerDrawerItem.kt
│ │ │ ├── DividerDrawerItem.kt
│ │ │ ├── ExpandableBadgeDrawerItem.kt
│ │ │ ├── ExpandableDrawerItem.kt
│ │ │ ├── MiniDrawerItem.kt
│ │ │ ├── MiniProfileDrawerItem.kt
│ │ │ ├── PrimaryDrawerItem.kt
│ │ │ ├── ProfileDrawerItem.kt
│ │ │ ├── ProfileSettingDrawerItem.kt
│ │ │ ├── SecondaryDrawerItem.kt
│ │ │ ├── SecondarySwitchDrawerItem.kt
│ │ │ ├── SecondaryToggleDrawerItem.kt
│ │ │ ├── SectionDrawerItem.kt
│ │ │ ├── SwitchDrawerItem.kt
│ │ │ ├── ToggleDrawerItem.kt
│ │ │ ├── interfaces/
│ │ │ │ ├── Badgeable.kt
│ │ │ │ ├── Checkable.kt
│ │ │ │ ├── ColorfulBadgeable.kt
│ │ │ │ ├── Describable.kt
│ │ │ │ ├── DescribableColor.kt
│ │ │ │ ├── IDrawerItem.kt
│ │ │ │ ├── IProfile.kt
│ │ │ │ ├── Iconable.kt
│ │ │ │ ├── Nameable.kt
│ │ │ │ ├── NameableColor.kt
│ │ │ │ ├── SelectIconable.kt
│ │ │ │ ├── Selectable.kt
│ │ │ │ ├── SelectableColor.kt
│ │ │ │ ├── Tagable.kt
│ │ │ │ └── Typefaceable.kt
│ │ │ └── utils/
│ │ │ ├── BadgeDrawableBuilder.kt
│ │ │ └── DrawerItemExtensions.kt
│ │ ├── util/
│ │ │ ├── AbstractDrawerImageLoader.kt
│ │ │ ├── DrawerImageLoader.kt
│ │ │ ├── DrawerItemViewHelper.kt
│ │ │ ├── DrawerUtils.kt
│ │ │ ├── Extensions.kt
│ │ │ ├── FixStateListDrawable.kt
│ │ │ ├── MaterialDrawerSliderViewExtensions.kt
│ │ │ ├── MenuDrawerUtils.kt
│ │ │ └── Utils.kt
│ │ ├── view/
│ │ │ └── BezelImageView.kt
│ │ └── widget/
│ │ ├── AccountHeaderView.kt
│ │ ├── MaterialDrawerSliderView.kt
│ │ └── MiniDrawerSliderView.kt
│ └── res/
│ ├── color/
│ │ └── color_drawer_item_text.xml
│ ├── drawable/
│ │ ├── material_drawer_badge.xml
│ │ ├── material_drawer_circle_mask.xml
│ │ ├── material_drawer_ico_account_layer.xml
│ │ ├── material_drawer_ico_chevron_down.xml
│ │ ├── material_drawer_ico_menu_down.xml
│ │ ├── material_drawer_rectangle_mask.xml
│ │ ├── material_drawer_shadow_bottom.xml
│ │ └── material_drawer_shadow_top.xml
│ ├── drawable-v21/
│ │ └── material_drawer_ico_account.xml
│ ├── layout/
│ │ ├── material_drawer.xml
│ │ ├── material_drawer_compact_header.xml
│ │ ├── material_drawer_fits_not.xml
│ │ ├── material_drawer_header.xml
│ │ ├── material_drawer_inner_shadow.xml
│ │ ├── material_drawer_item_container.xml
│ │ ├── material_drawer_item_divider.xml
│ │ ├── material_drawer_item_expandable.xml
│ │ ├── material_drawer_item_expandable_badge.xml
│ │ ├── material_drawer_item_mini.xml
│ │ ├── material_drawer_item_mini_profile.xml
│ │ ├── material_drawer_item_primary.xml
│ │ ├── material_drawer_item_profile.xml
│ │ ├── material_drawer_item_profile_setting.xml
│ │ ├── material_drawer_item_secondary.xml
│ │ ├── material_drawer_item_secondary_switch.xml
│ │ ├── material_drawer_item_secondary_toggle.xml
│ │ ├── material_drawer_item_section.xml
│ │ ├── material_drawer_item_switch.xml
│ │ ├── material_drawer_item_toggle.xml
│ │ └── material_drawer_recycler_view.xml
│ ├── values/
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ids.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── values-fr/
│ │ └── strings.xml
│ ├── values-pt/
│ │ └── strings.xml
│ └── values-sw600dp/
│ └── dimens.xml
├── materialdrawer-iconics/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── gradle.properties
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ └── java/
│ └── com/
│ └── mikepenz/
│ └── materialdrawer/
│ └── iconics/
│ ├── IconicsExtension.kt
│ └── IconicsImageHolder.kt
├── materialdrawer-nav/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── consumer-rules.pro
│ ├── gradle.properties
│ ├── proguard-rules.pro
│ ├── proguard-rules.txt
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ └── java/
│ └── com/
│ └── mikepenz/
│ └── materialdrawer/
│ ├── model/
│ │ └── NavigationDrawerItem.kt
│ └── util/
│ └── DrawerNavigationUI.kt
└── settings.gradle.kts
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [mikepenz]
================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
## About this issue
- Briefly describe the issue
- How can the issue be reproduced / sample code
## Details
- [ ] Used library version
- [ ] Used support library version
- [ ] Used gradle build tools version
- [ ] Used tooling / Android Studio version
- [ ] Other used libraries, potential conflicting libraries
## Checklist
- [ ] Searched for [similar issues](https://github.com/mikepenz/MaterialDrawer/issues)
- [ ] Checked out the [sample application](https://github.com/mikepenz/MaterialDrawer/tree/develop/app)
- [ ] Read the [README](https://github.com/mikepenz/MaterialDrawer/blob/develop/README.md)
- [ ] Checked out the [CHANGELOG](https://github.com/mikepenz/MaterialDrawer/releases)
- [ ] Read the [FAQ](https://github.com/mikepenz/MaterialDrawer/blob/develop/FAQ.md)
- [ ] Checked out the [MIGRATION GUIDE](https://github.com/mikepenz/MaterialDrawer/blob/develop/MIGRATION.md)
================================================
FILE: .github/ci-gradle.properties
================================================
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.workers.max=2
org.gradle.jvmargs=-Xmx6G
org.gradle.caching=true
org.gradle.configureondemand=true
# parallel kapt
kapt.use.worker.api=true
================================================
FILE: .github/config/configuration.json
================================================
{
"categories": [
{
"title": "## 🚀 Features",
"labels": [
"feature"
]
},
{
"title": "## 🐛 Fixes",
"labels": [
"fix"
]
},
{
"title": "## 🧪 Tests",
"labels": [
"test"
]
},
{
"title": "## 💬 Other",
"labels": [
"other",
"dependencies"
]
}
]
}
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
================================================
FILE: .github/workflows/ci.yml
================================================
# Thanks to https://github.com/coil-kt/coil/blob/master/.github/workflows/ci.yml
name: CI
on:
push:
tags:
- '*'
pull_request:
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 100
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: |
11
15
17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Validate gradle wrapper
uses: gradle/actions/wrapper-validation@v4
- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
- name: Build Debug
run: ./gradlew clean app:assembleDebug
- name: Run Lint
if: github.event_name == 'pull_request'
run: ./gradlew lintDebug
- name: Setup Ruby
if: github.event_name == 'pull_request'
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
- name: Run Danger
if: github.event_name == 'pull_request'
run: |
gem install danger
bundle exec danger --dangerfile=Dangerfile --danger_id=danger-pr
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare Keystore and Local.
if: startsWith(github.ref, 'refs/tags/')
run: |
echo "${{ secrets.KEYSTORE }}" > opensource.jks.asc
gpg -d --passphrase "${{ secrets.KEYSTORE_PASSPHRASE }}" --batch "opensource.jks.asc" > "app/opensource.jks"
- name: Build Release App
if: startsWith(github.ref, 'refs/tags/')
run: ./gradlew app:assembleRelease app:bundleRelease -P"com.mikepenz.android.signing.enabled"="true" -P"com.mikepenz.android.signing.storeFile"="opensource.jks" -P"com.mikepenz.android.signing.storePassword"="${{ secrets.STORE_PASSWORD }}" -P"com.mikepenz.android.signing.keyAlias"="${{ secrets.KEY_ALIAS }}" -P"com.mikepenz.android.signing.keyPassword"="${{ secrets.KEY_PASSWORD }}"
- name: Relase Sonatype
if: startsWith(github.ref, 'refs/tags/')
run: |
./gradlew build -x test -x lint
./gradlew materialdrawer:publishAllPublicationsToMavenCentralRepository -x test -x lint -Plibrary_only --no-configure-on-demand --no-parallel
./gradlew materialdrawer-nav:publishAllPublicationsToMavenCentralRepository -x test -x lint -Plibrary_nav_only --no-configure-on-demand --no-parallel
./gradlew materialdrawer-iconics:publishAllPublicationsToMavenCentralRepository -x test -x lint -Plibrary_iconics_only --no-configure-on-demand --no-parallel
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.NEXUS_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.NEXUS_PASSWORD }}
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_PRIVATE_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }}
- name: Collect artifacts
run: |
COLLECT_PWD=${PWD}
mkdir -p "artifacts"
find . -name "*.apk" -type f -exec cp {} "artifacts" \;
find . -name "*.aab" -type f -exec cp {} "artifacts" \;
- name: Archive Artifacts
uses: actions/upload-artifact@v7
with:
name: "App-Artifacts"
path: artifacts/*
- name: Build Changelog
id: github_release
uses: mikepenz/release-changelog-builder-action@v6
if: startsWith(github.ref, 'refs/tags/')
with:
configuration: ".github/config/configuration.json"
ignorePreReleases: ${{ !contains(github.ref, '-') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Release
uses: mikepenz/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
body: ${{steps.github_release.outputs.changelog}}
prerelease: ${{ contains(github.ref, '-rc') || contains(github.ref, '-b') || contains(github.ref, '-a') }}
files: artifacts/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/gradle-dependency-submission.yml
================================================
name: Gradle Dependency Submission
on:
push:
branches:
- develop
jobs:
gradle-dependency-detection:
runs-on: ubuntu-latest
# The Dependency Submission API requires write permission
permissions:
contents: write
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v6
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: |
11
15
17
- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
- name: Checkout Gradle Build Cache
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
!~/.gradle/wrapper/dists/**/gradle*.zip
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
gradle-${{ runner.os }}-
- name: Submit Dependency Graph
uses: mikepenz/gradle-dependency-submission@main
with:
gradle-build-module: :app
gradle-build-configuration: debugCompileClasspath
sub-module-mode: INDIVIDUAL_DEEP
================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
# Gradle files
.gradle/
build/
/*/build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
#IntelliJ files
*.iml
.idea/
functiongraphic.psd
/.kotlin
================================================
FILE: Dangerfile
================================================
github.dismiss_out_of_range_messages
# Make it more obvious that a PR is a work in progress and shouldn't be merged yet.
has_wip_label = github.pr_labels.any? { |label| label.include? "Engineers at work" }
has_wip_title = github.pr_title.include? "[WIP]"
if has_wip_label || has_wip_title
warn("PR is marked as Work in Progress")
end
# Ensure the PR is not marked as DO NOT MERGE
fail("PR specifies label DO NOT MERGE") if github.pr_labels.any? { |label| label.include? "DO NOT MERGE" }
# Warn when there is a big PR
warn("Big PR") if git.lines_of_code > 5000
File.open("settings.gradle.kts", "r") do |file_handle|
file_handle.each_line do |setting|
if setting.include? "include"
gradleModule = setting[10, setting.length-13]
# AndroidLint
androidLintFile = String.new(gradleModule + "/build/reports/lint-results.xml")
androidLintDebugFile = String.new(gradleModule + "/build/reports/lint-results-debug.xml")
if File.file?(androidLintFile) || File.file?(androidLintDebugFile)
android_lint.skip_gradle_task = true
android_lint.severity = "Warning"
if File.file?(androidLintFile)
android_lint.report_file = androidLintFile
else
android_lint.report_file = androidLintDebugFile
end
android_lint.filtering = true
android_lint.lint(inline_mode: true)
end
# Detekt
detektFile = String.new(gradleModule + "/build/reports/detekt.xml")
if File.file?(detektFile)
kotlin_detekt.report_file = detektFile
kotlin_detekt.skip_gradle_task = true
kotlin_detekt.severity = "warning"
kotlin_detekt.filtering = true
kotlin_detekt.detekt(inline_mode: true)
end
end
end
end
================================================
FILE: FAQ/accountheader_single_profile_without_dropdown.md
================================================
# How can i use the AccountHeader with just one profile and disable the dropdown?
This can be simply achieved by adding `headerView.selectionListEnabledForSingleProfile = false` to the
`Builder` of the `AccountHeader`. This will then disable the dropdown and hide the arrow from the
header.
## Sample code
```kotlin
headerView.selectionListEnabledForSingleProfile = false
```
## Links
* https://github.com/mikepenz/MaterialDrawer/issues/615
* https://github.com/mikepenz/MaterialDrawer/issues/454
* https://github.com/mikepenz/MaterialDrawer/issues/443
* https://github.com/mikepenz/MaterialDrawer/issues/350
================================================
FILE: FAQ/howto_modify_add_custom_draweritems.md
================================================
# How do I change existing or add my own CustomDrawerItems to the MaterialDrawer?
Please head over here on how to implement a proper CustomDrawerItem:
- http://stackoverflow.com/a/32543209/325479
- http://stackoverflow.com/a/32542999/325479
Or you check out custom drawer item implementations here:
- https://github.com/mikepenz/MaterialDrawer/tree/develop/app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems
You might also find some answers here:
- https://github.com/mikepenz/MaterialDrawer/issues?utf8=%E2%9C%93&q=CustomDrawerItem
================================================
FILE: FAQ/howto_use_different_sub_library_version.md
================================================
# How do I use different versions of the sub dependencies like the support libraries?
This can be really easy achieved by providing a resolutionStrategy to your build.
## Sample code
Simple add the following to your modules build.gradle. It allows you to define whatever version you need for the sub dependencies.
```xml
configurations.all {
resolutionStrategy.force "com.android.support:support-v4:${versions.androidX}"
resolutionStrategy.force "com.android.support:appcompat-v7:${versions.androidX}"
resolutionStrategy.force "com.android.support:cardview-v7:${versions.androidX}"
resolutionStrategy.force "com.android.support:recyclerview-v7:${versions.androidX}"
resolutionStrategy.force "com.android.support:design:${versions.androidX}"
resolutionStrategy.force "com.android.support:support-annotations:${versions.androidX}"
}
```
https://github.com/mikepenz/MaterialDrawer/blob/develop/app/build.gradle
================================================
FILE: FAQ/opening-drawer-from-espresso.md
================================================
### Q: How to open the drawer from an instrumental test written with Espresso?
### A:
First, you need a add `espresso-contrib` to your project. It has the needed `DrawerActions` class.
`androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2'`
Then, you need to open the drawer with his `openDrawer()` method and the drawer layout ID. The generated one is `R.id.material_drawer_layout`
`onView(withId(R.id.material_drawer_layout)).perform(DrawerActions.open());`
================================================
FILE: FAQ/when_to_use_this_library.md
================================================
### Developer:
Since there is MaterialDrawer in Support Library, could you give a couple of points why to use your library instead of from Support Library one?
### Author:
Well, that really depends on the use case of the drawer in this project, and which functionalities + which customizations are needed.
The MaterialDrawer was created long before Google came up with their drawer in the design support libraries.
Basically, the one of Google is definitely great and I recommend it to being used in all cases where it is enough. I am a fan of keeping
things as simple as possible, as it will have the great effect on the user experience. So if this project only needs a very minimal drawer
implementation, with just `Main` items, no `profile` functionality, and no great flexibility (no custom items, no custom styles, ... no advanced API for doing stuff programmatically) then you should definitely consider using the one from the design library.
If you have a more advanced use case, like using the profile switcher, the profile page, custom items like different sizes, or checkboxes, etc then you might want to stay with my library.
================================================
FILE: FAQ.md
================================================
# FAQ / WIKI
This is the official **MaterialDrawer** FAQ/Wiki. People can contribute to it through pull requests.
Each question and it's answer is hosted in a separate file within the FAQ folder.
## MaterialDrawer
* [Should I use this library or Material Drawer from the Support library?](FAQ/when_to_use_this_library.md)
* [How do I make the drawer appear underneath the Toolbar?](FAQ/howto_show_drawer_under_toolbar.md)
* [How do I create a Multi-pane layout with MaterialDrawer for tablets?](FAQ/howto_show_drawer_in_tablet_multipane.md)
* [Why is there whitespace where the status bar should be while my theme is set as fullscreen ?](FAQ/status_bar_whitespace.md)
* [How do I change existing or add my own CustomDrawerItems to the MaterialDrawer?](FAQ/howto_modify_add_custom_draweritems.md)
* [How to use different dependency library versions](FAQ/howto_use_different_sub_library_version.md)
## AccountHeader
* [How can I use the AccountHeader with just one profile and disable the dropdown?](FAQ/accountheader_single_profile_without_dropdown.md)
## Testing
* [How can I open the drawer from an instrumental test written with Espresso?](FAQ/opening-drawer-from-espresso.md)
## CustomDrawerItem's
* [A custom SecondaryDrawerItem that takes different name when its on disabled state](https://gist.github.com/AngleV/400377184386193c985d905bd97f2d40)
## Asked super frequently
### How can i create a drawer without a default selection
```kotlin
//just set the selection to -1
slider.setSelectionAtPosition(-1)
```
### Can I lock the Drawer
As the MaterialDrawer will just create a normal DrawerLayout (with some magic around it) everything a normal
DrawerLayout can do is also available in the MaterialDrawer.
```kotlin
drawerLayout.setDrawerLockMode(int lockMode); //or (int lockMode, int edgeGravity)
```
================================================
FILE: Gemfile
================================================
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'danger'
gem 'danger-android_lint'
gem 'danger-kotlin_detekt'
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2021 Mike Penz
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: MIGRATION.md
================================================
### Upgrade Notes
#### v8.0.0
- Ground up refactor of the way the `MaterialDrawer` is used and integrated into the app.
- Please consider carefully before upgrading to this version.
- Prior to v8 the `Drawer` would automatically inject the `DrawerLayout` into the layout hierarchy, apply window flags, and take over control of the `ActionBarDrawerToggle`.
- This may seem convenient for easy usecases, but created big problems for more advanced implementations where taking over window insets is expected
- v8 will no longer do any of this, and gives back all the control to the developer, no more unexpected layout flags, changes to the layout hierarchy or anything similar.
- The core principle behind v8 is to offer just the UI and give back all control to developers.
- Additionally v8 eliminates dependencies on `Materialize`, `Android-Iconics`
- v8 also now comes with better theming support and better dark mode support
- As v8 is ground up different in the way it is set up it is recommended to re-read the README and check out the sample again
- Basic upgrade procedure:
- Add `DrawerLayout` into your layout
- Add `MaterialDrawerSliderView` as child to the `DrawerLayout`
- Find the reference to the `MaterialDrawerSliderView` in your `Activity` / `Fragment`
- Use the `MaterialDrawerSliderView` to fill the list / do updates
- Basic upgrade prodedure for the `AccountHeader`:
- Create an instance of the `AccountHeaderView`
- Attach to the slider via `attachToSliderView(slider)`
- Additionally v8 is more optimized for Kotlin meaning all legacy `with(*)` methods were replaced (kept as extension functions as legacy support) with properties
##### Note
- Please report if additional upgrade notes are required
#### v7.0.0
Now library is kotlin-first.
* this release contains a big amount of changes, including many breaking API changes to make its implementation easier, and make the APIs better compatible with kotlin.
* please note that the interface for items changed in the `FastAdapter` as such migrating to the new version will require more effort.
* Update `FastAdapter` to v4 and make all relevant adjustments to the provided `DrawerItem`s
* Check the `FastAdapter` changelog and [migration guide](https://github.com/mikepenz/FastAdapter/blob/develop/MIGRATION.md)
* Update `Android-Iconics` to v4
* Ensure to update `Android-Iconics` for your project, and use the updated kotlin icon dependencies
* See the migration notes for `Android-Iconics` if you run into problems
* The general interfaces and everything stayed the same, and mainly everything was migrated to kotlin
If you have any issues during the migration, or any questions come up please open a github issue so we can improve the migration guide or the documentation.
#### v6.1.1
* Further adjustments for the theme to properly meet the new material 2 design guidelines.
```xml
<item name="material_drawer_header_selection_subtext">@color/material_drawer_header_selection_subtext</item> <!-- Defines the color of the subtext item in the header -->
```
#### v6.1.0-rc01.2
* With the introduction of the material 2 design behaviour, new theme attributes were added.
```xml
<item name="material_drawer_selected_legacy">@color/material_drawer_selected</item> <!-- Defines the color if legacy style (Material 1, is enabled) -->
<item name="material_drawer_legacy_style">true</item> <!-- Enables legacy Material 1 style -->
```
* Reworked the header views to be a lot more simple by using a `ConstraintLayout`
* Any previously custom headers require to be adjusted to the new structure. (The statusbar `Guideline` is required, for example)
* The viewHolder.item has no longer the item itself as tag directly. It is now defined with an id `R.id.material_drawer_item`. `ViewHolder.itemView.getTag(R.id.material_drawer_item)` will now return the `IDrawerItem`.
#### v6.1.0-rc01
* Final upgrade to the new shiny androidX dependencies :)
#### v6.0.3
**IMPORTANT IF YOU USE THE FASTADAPTER OR ABOUTLIBRARIES**
* You have to update your FastAdapter dependency to v3.2.1 with this release
* See the MIGRATION information of the FastAdapter https://github.com/mikepenz/FastAdapter/blob/develop/MIGRATION.md
#### v6.0.0
**IMPORTANT IF YOU USE THE FASTADAPTER OR ABOUTLIBRARIES**
* You have to update your FastAdapter dependency to v3.0.0 with this release
* See the MIGRATION information of the FastAdapter https://github.com/mikepenz/FastAdapter/blob/develop/MIGRATION.md
#### v5.9.0 & v5.9.2
**IMPORTANT IF YOU USE THE FASTADAPTER OR ABOUTLIBRARIES**
* You have to update your FastAdapter dependency to v2.5.0 with this release
* See the MIGRATION information of the FastAdapter https://github.com/mikepenz/FastAdapter/blob/develop/MIGRATION.md
#### v5.8.0
**IMPORTANT IF YOU USE THE FASTADAPTER OR ABOUTLIBRARIES**
* You have to update your FastAdapter dependency to v2.1.0 with this release
* See the MIGRATION information of the FastAdapter https://github.com/mikepenz/FastAdapter/blob/develop/MIGRATION.md
#### v5.7.0
**IMPORTANT IF YOU IMPLEMENT CUSTOM-DRAWER-ITEMS OR USE THE FASTADAPTER**
* You have to update your `FastAdapter` dependency to v2.0.0 with this release
* If you have `CustomDrawerItem`'s not based on the `AbstractDrawerITems` make sure you implement the `unbindView` method, and the new required methods
* See the MIGRATION information of the **FastAdapter** https://github.com/mikepenz/FastAdapter/blob/develop/MIGRATION.md
#### v5.6.0
**IMPORTANT IF YOU IMPLEMENT CUSTOM-DRAWER-ITEMS OR USE THE FASTADAPTER**
* This release brings a breaking interface change. Your items now have to implement `bindView(ViewHolder holder, List payloads)` instead of `bindView(VH holder)`.
* The additional payload can be used to implement a more performant view updating when only parts of the item have changed. Please also refer to the `DiffUtils` which may provide the payload.
#### v5.5.1
* add `void set(ImageView imageView, Uri uri, Drawable placeholder, String tag);` to `IDrawerImageLoader` interface, similar to the `tag` provided in the placeholder method
#### v5.5.0
* **Dropping support for API < 14. New MinSdkVersion is 14**
#### v5.3.3 -> 5.3.4
* If you use the `FastAdapter` please read the upgrade notes for v1.6.0 (https://github.com/mikepenz/FastAdapter/releases/tag/v1.6.0)
#### v5.3.1 -> v5.3.2
* the `withOnMiniDrawerItemClickListener` was renamed to `withOnMiniDrawerItemOnClickListener`
* added new separate `OnMiniDrawerItemClickListener` which allows to hook into the default behavior, and prevent it if necessary
* NOTE: this one now uses the `withOnMiniDrawerItemClickListener` method.
#### v5.2.0 -> v5.2.1
* the `SecondaryDrawerItem` is now a subclass of the `PrimaryDrawerItem` (extends `PrimaryDrawerItem`). If you have an `if` which checks for the type with `instanceOf` make sure you check for the `SecondaryDrawerItem` first. (`secondaryDrawerItem instanceOf PrimaryDrawerItem == true`)
#### v5.1.6 -> 5.1.8
* if you use the `FastAdapter` please check out the release notes of v1.4.0 (https://github.com/mikepenz/FastAdapter/releases/tag/v1.4.0)
#### v5.0.0 -> 5.0.5
* the `expanding` functionality is now handled by the `FastAdapter` so the toggling code is no longer needed. See the following diff for the change (just the `DrawerActivity`) https://github.com/mikepenz/MaterialDrawer/commit/88e9bdf8cccaac5aaf567ac6ffe682aeccba4f29
#### v4.6.0 -> v5.0.0
* the identifier was changed from `int` to `long` as the internal adapter (FastAdapter) uses `long` to identify items (as the `Adapter` does)
* v5.0.0 no longer sets the `FULL_SCREEN` flag to get the drawer below the `StatusBar` it now uses the `fitsSystemWindows` everywhere. This should improve compatiblity with a lot of things like the `CoordinatorLayout` and should also improve compatiblity with future Android updates
* removed the following methods:
* DrawerUIUtils.getScreenWidth -> moved to UIUtils from the `Materialize` library
* DrawerBuilder.withTranslucentStatusBarProgrammatically -> no longer necessary as we now depend on the `fitsSystemWindows` flag
* `StatusBarColor` can now be set via the `Drawer.getDrawerLayout().setStatusBarBackgroundColor(color)`
* DrawerBuilder.keyboardSupportEnabled -> `KeyboardUtil` should no longer be necessary
* `StatusBar` on **API < 21** is no longer colored, because of the changed way how we display the `Drawer` under the `StatusBar`
* `DrawerItems` changed. Please take a look at the `CustomDrawerItems` from the sample or the default ones, to add the changes to your `CustomDrawerItems`
* ...
#### v4.5.9 -> v4.6.0
* it is now possible to let the `Drawer` manage the `MiniDrawer`. Enable this via `withGenerateMiniDrawer(true)`. Afterwards remove the `MiniDrawer` calls inside the listeners, those are now done within the `Drawer`. You can get the `MiniDrawer` result object via `Drawer.getMiniDrawer();`
#### v4.3.7 -> v4.4.3
* added new method `withHeaderPadding` to the drawer and `withPaddingBelowHeader` to the header to control the padding separately from the `divider`which can be controlled via `withHeaderDivider`
#### v4.3.7
* depends on the latest `v23.1.0` **support libraries**. Those also require you to have `compileSDKVersion 23`
#### v4.2.0 -> v4.3.0
* new `placeholder(Context ctx, String tag)` to the `IDrawerImageLoader` interface
* new `AbstractDrawerImageLoader` to simplify the `DrawerImageLoader` usage. See the new implementation in the `CustomApplication`
* to keep the old behavior just change from `new DrawerImageLoader.IDrawerImageLoader() {` to `new AbstractDrawerImageLoader() {` for the `DrawerImageLoader.init`
* add new `tag` to the placeholder, to be able to define different placeholders for different targets
#### v4.2.0
* no more need to define an identifier for the items, they get one automatically. if you do not have logics which require you to do so, you are safe to forget about the identifier now.
#### v4.0.2 -> v4.0.7
* renamed `setDivider()` to `withDivider`
* remove `setTypeface()` use `withTypeface()` instead
#### v4.0.0 -> v4.0.2
* `getCurrentSelection()` will now return the `identifier` of the current selection or `null`
* `getCurrentSelectedPosition()` was added
* renamed all `*Footer*` methods to `*StickyFooter*` to prevent confusion
#### < v4.0.0
##### Common changes
* depends on the latest `v23` **support libraries**. Those also require you to have `compileSDKVersion 23`
* change the `onItemClick` listener to `onItemClick(View view, int i, IDrawerItem iDrawerItem)`
* modify the import of the `AccountHeader` and `AccountHeaderBuilder` to
```gradle
import com.mikepenz.materialdrawer.AccountHeader
import com.mikepenz.materialdrawer.AccountHeaderBuilder
```
* the `identifier` should now be set for the `DrawerItems` as it is used now as default for all update/modify/.. actions
* rename `withCheckable()` to `withSelectable()`
* rename `set*` methods of the `DrawerItems` to `with*` methods as those were renamed
* rename all methods like `setSelection`, `setFooterSelection`, `removeItem`, ... to `*ByPosition` (added the **ByPosition**)
* rename all methods like `setSelectionByIdentifier`, `setFooterSelectionByIdentifier`, ... to `setSelection`, `setFooterSelection` (removed the **ByIdentifier**)
* change `updateName`, `updateIcon`, `updateBadge` those methods take now an `identifier` and the specific `Holder` object
* all `get*` methods of the `DrawerItems` will now return a `Holder` object for the specific type, making it easier to work with types like `String`, `StringRes`, `Color`, `ColorRes`, `ColorInt`, ..
##### Android-Iconics (icon font)
* the MaterialDrawer now only includes the `core` of the Android-Iconics project
* add the fonts you use https://github.com/mikepenz/Android-Iconics#2-choose-your-desired-fonts
* pre MaterialDrawer v4.0.0 following fonts were included
```gradle
compile 'com.mikepenz:google-material-typeface:1.2.0.1@aar' //Google Material Design Icons
compile 'com.mikepenz:fontawesome-typeface:4.4.0.1@aar' //FontAwesome **NOTE:** the packagename changed for this font
```
##### Advanced usage changes
* changed the `ListView` to a `RecyclerView`
* rename methods with `*ListView*` to `*RecyclerView*`
* the `IDrawerItem` interface was extended to better reflect a `RecyclerView` and to improve performance
* added an `AbstractDrawerItem` to implement some common methods
* see the [SectionDrawerItem](https://github.com/mikepenz/MaterialDrawer/blob/feature/refactoring/library/src/main/java/com/mikepenz/materialdrawer/model/SectionDrawerItem.java) for an easy example
================================================
FILE: README.md
================================================
# MaterialDrawer
... the flexible, easy to use, all in one drawer library for your Android project.
-------
<p align="center">
<a href="#whats-included-">What's included 🚀</a> •
<a href="#setup">Setup 🛠️</a> •
<a href="MIGRATION.md">Migration Guide 🧬</a> •
<a href="FAQ.md">WIKI / FAQ 📖</a> •
<a href="#used-by">Used by</a> •
<a href="https://play.google.com/store/apps/details?id=com.mikepenz.materialdrawer.app">Sample App</a>
</p>
-------
### What's included 🚀
- **the easiest possible integration**
- **uses the androidX support libraries**
- compatible down to **API Level 16**
- includes an **AccountSwitcher**
- quick and simple api
- follows the **NEW Google Material Design Guidelines**
- use **vector** (.svg) icons and **icon fonts** via the [Android-Iconics](https://github.com/mikepenz/Android-Iconics) integration
- **Google Material Design Icons**, Google **Material Community** Design Icons, FontAwesome and more
- comes with various **themes** which help to get your own themes clean
- modify the colors on the go
- comes with multiple default drawer items
- based on a **RecyclerView**
- **RTL** support
- Gmail like **MiniDrawer**
- expandable items
- **badge** support
- define custom drawer items
- tested and **stable**
- sticky footer or headers
- **absolutely NO limits**
- NavController support by @petretiandrea
> If you upgrade from < 8.0.0 follow the [MIGRATION GUIDE](https://github.com/mikepenz/MaterialDrawer/blob/develop/MIGRATION.md)
# Preview
## Screenshots 🎉

# Setup
## Latest releases 🛠
- Kotlin && M3 && JVM
17 | [v10.0.0-b01](https://github.com/mikepenz/MaterialDrawer/tree/v10.0.0-b01)
- Kotlin && Material 3 | [v9.0.2](https://github.com/mikepenz/MaterialDrawer/tree/v9.0.2)
- Kotlin | [v8.4.5](https://github.com/mikepenz/MaterialDrawer/tree/v8.4.5) (Provided as-is only)
- Java && AndroidX | [v6.1.2](https://github.com/mikepenz/MaterialDrawer/tree/v6.1.2) (Provided as-is only)
- Java && AppCompat | [v6.0.9](https://github.com/mikepenz/MaterialDrawer/tree/v6.0.9) (Provided as-is only)
### 1. Provide the gradle dependency
The latest release is available
on [Maven Central](https://search.maven.org/artifact/com.mikepenz/materialdrawer/9.0.1/aar).
```gradle
implementation("com.mikepenz:materialdrawer:${latestRelease}")
```
```gradle
//required support lib modules
implementation "androidx.appcompat:appcompat:${versions.appcompat}"
implementation "androidx.recyclerview:recyclerview:${versions.recyclerView}"
implementation "androidx.annotation:annotation:${versions.annotation}"
implementation "com.google.android.material:material:1.5.0-alpha05" // requires at least 1.5.0-x
implementation "androidx.constraintlayout:constraintlayout:${versions.constraintLayout}"
```
[NavController Support @ Maven Central](https://search.maven.org/artifact/com.mikepenz/materialdrawer-nav/9.0.1/aar).
```gradle
// Add for NavController support
implementation "com.mikepenz:materialdrawer-nav:${lastestMaterialDrawerRelease}"
```
[Android-Iconics Support @ Maven Central](https://search.maven.org/artifact/com.mikepenz/materialdrawer-iconics/9.0.1/aar)
.
```gradle
// Add for Android-Iconics support
implementation "com.mikepenz:materialdrawer-iconics:${lastestMaterialDrawerRelease}"
```
### 2. Add the `Drawer` into the XML
The `MaterialDrawerSliderView` has to be provided as child of the `DrawerLayout` and will as such act as the slider
```kotlin
<androidx.drawerlayout.widget.DrawerLayout xmlns : android ="http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
android:id = "@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
... your content ...
<com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
android:id="@+id/slider"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true" />
</androidx.drawerlayout.widget.DrawerLayout>
```
### 3. Add the `DrawerStyle` to your theme
```xml
<style name="SampleApp.DayNight" parent="Theme.Material3.DayNight.NoActionBar">
...
<item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyle</item>
<item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyle</item>
...
</style>
```
Great. Your drawer is now ready to use.
### Note
> Using v9.x with Material 3 theming requires a `Material3` theme as base for the activity.
# Additional Setup
### Add items and adding some functionality
```kotlin
//if you want to update the items at a later time it is recommended to keep it in a variable
val item1 = PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_home; identifier = 1 }
val item2 = SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_settings; identifier = 2 }
// get the reference to the slider and add the items
slider.itemAdapter.add(
item1,
DividerDrawerItem(),
item2,
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_settings }
)
// specify a click listener
slider.onDrawerItemClickListener = { v, drawerItem, position ->
// do something with the clicked item :D
false
}
```
### Selecting an item
```kotlin
//set the selection to the item with the identifier 1
slider.setSelection(1)
//set the selection to the item with the identifier 2
slider.setSelection(item2)
//set the selection and also fire the `onItemClick`-listener
slider.setSelection(1, true)
```
By default, when a drawer item is clicked, it becomes the new selected item. If this isn't the expected behavior,
you can disable it for this item using `isSelectable = false`:
```kotlin
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_dialog; isSelectable = false }
```
### Modify items or the drawer
```kotlin
//modify an item of the drawer
item1.apply {
nameText = "A new name for this drawerItem"; badge = StringHolder("19")
badgeStyle = BadgeStyle().apply { textColor = ColorHolder.fromColor(Color.WHITE); color = ColorHolder.fromColorRes(R.color.md_red_700) }
}
//notify the drawer about the updated element. it will take care about everything else
slider.updateItem(item1)
//to update only the name, badge, icon you can also use one of the quick methods
slider.updateName(1, "A new name")
//the result object also allows you to add new items, remove items, add footer, sticky footer, ..
slider.addItem(DividerDrawerItem())
slider.addStickyFooterItem(PrimaryDrawerItem().apply { nameTest = "StickyFooter" })
//remove items with an identifier
slider.removeItem(2)
//open / close the drawer
slider.drawerLayout?.openDrawer(slider)
slider.drawerLayout?.closeDrawer(slider)
//get the reference to the `DrawerLayout` itself
slider.drawerLayout
```
### Add profiles and an AccountHeader
```kotlin
// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
attachToSliderView(slider) // attach to the slider
addProfiles(
ProfileDrawerItem().apply { nameText = "Mike Penz"; descriptionText = "mikepenz@gmail.com"; iconRes = R.drawable.profile; identifier = 102 }
)
onAccountHeaderListener = { view, profile, current ->
// react to profile changes
false
}
withSavedInstance(savedInstanceState)
}
```
### Android-Iconics support
The MaterialDrawer provides an extension for the [Android-Iconics](https://github.com/mikepenz/Android-Iconics) library. This allows you to create your `DrawerItems` with an icon from any font.
Choose the fonts you need. [Available Fonts](https://github.com/mikepenz/Android-Iconics#2-choose-your-desired-fonts)
```gradle
// Add for Android-Iconics support
implementation "com.mikepenz:materialdrawer-iconics:${lastestMaterialDrawerRelease}"
// fonts
implementation 'com.mikepenz:google-material-typeface:x.y.z@aar' //Google Material Icons
implementation 'com.mikepenz:fontawesome-typeface:x.y.z@aar' //FontAwesome
```
```kotlin
//now you can simply use any icon of the Google Material Icons font
PrimaryDrawerItem().apply { iconicsIcon = GoogleMaterial.Icon.gmd_wb_sunny }
//Or an icon from FontAwesome
SecondaryDrawerItem().apply { iconicsIcon = FontAwesomeBrand.Icon.fab_github }
```
# Advanced Setup
For advanced usecases. Please have a look at the provided sample activities.
## Load images via url
The MaterialDrawer supports fetching images from URLs and setting them for the Profile icons. As the MaterialDrawer does not contain an ImageLoading library
the dev can choose his own implementation (Picasso, Glide, ...). This has to be done, before the first image should be loaded via URL. (Should be done in the Application, but any other spot before loading the first image is working too)
* SAMPLE using [PICASSO](https://github.com/square/picasso)
* [SAMPLE](https://github.com/mikepenz/MaterialDrawer/blob/develop/app/src/main/java/com/mikepenz/materialdrawer/app/CustomApplication.kt) using [GLIDE](https://github.com/bumptech/glide)
```kotlin
//initialize and create the image loader logic
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable) {
Picasso.get().load(uri).placeholder(placeholder).into(imageView)
}
override fun cancel(imageView: ImageView) {
Picasso.get().cancelRequest(imageView)
}
/*
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
super.set(imageView, uri, placeholder, tag)
}
override fun placeholder(ctx: Context): Drawable {
return super.placeholder(ctx)
}
override fun placeholder(ctx: Context, tag: String?): Drawable {
return super.placeholder(ctx, tag)
}
*/
})
```
An implementation with [GLIDE v4](https://github.com/mikepenz/MaterialDrawer/blob/develop/app/src/main/java/com/mikepenz/materialdrawer/app/CustomApplication.kt) (See tag v6.1.1 for glide v3 sample) can be found in the sample application
## JVM Target 1.8
```
// Since 8.1.0 the drawer includes core ktx 1.3.0 which requires jvm 1.8
kotlinOptions {
jvmTarget = "1.8"
}
```
## Style the drawer 🖌️
### Custom style - styles.xml
Create your custom style. If you don't need a custom theme see the next section, how you can set the colors just by overwriting the original colors.
```xml
// define a custom drawer style
<style name="Widget.MaterialDrawerStyleCustom" parent="Widget.MaterialDrawerStyle">
<item name="materialDrawerInsetForeground">#4000</item>
<!-- MaterialDrawer specific values -->
<item name="materialDrawerBackground">?colorSurface</item>
<item name="materialDrawerPrimaryText">@color/color_drawer_item_text</item>
<item name="materialDrawerPrimaryIcon">@color/color_drawer_item_text</item>
<item name="materialDrawerSecondaryText">@color/color_drawer_item_text</item>
<item name="materialDrawerSecondaryIcon">@color/color_drawer_item_text</item>
<item name="materialDrawerDividerColor">?colorOutline</item>
<item name="materialDrawerSelectedBackgroundColor">?colorSecondaryContainer</item>
</style>
// define a custom header style
<style name="Widget.MaterialDrawerHeaderStyleCustom" parent="">
<item name="materialDrawerCompactStyle">true</item>
<item name="materialDrawerHeaderSelectionText">?colorOnSurface</item>
<item name="materialDrawerHeaderSelectionSubtext">?colorOnSurface</item>
</style>
// define the custom styles for the theme
<style name="SampleApp" parent="Theme.Material3.Light.NoActionBar">
...
<item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyleCustom</item>
<item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyleCustom</item>
...
</style>
```
### Adjust BezelImageView style
Overwrite the Style of the BezelImageView for the whole MaterialDrawer
```xml
<style name="BezelImageView">
<item name="biv_maskDrawable">@drawable/material_drawer_rectangle_mask</item>
<item name="biv_drawCircularShadow">false</item>
<item name="biv_selectorOnPress">@color/material_drawer_primary</item>
<item name="android:scaleType">centerInside</item>
</style>
```
# Used by
(feel free to send me new projects)
* [Screener](https://play.google.com/store/apps/details?id=de.toastcode.screener)
* [Meldmail](https://play.google.com/store/apps/details?id=com.meldmail)
* [Academic Schedule](https://play.google.com/store/apps/details?id=com.auebcsschedule.ppt)
* [Sprit Club](https://play.google.com/store/apps/details?id=at.idev.spritpreise)
* [StickyNotes](https://play.google.com/store/apps/details?id=com.jsvmsoft.stickynotes)
* [MLManager](https://github.com/javiersantos/MLManager)
* [Fimpl](https://play.google.com/store/apps/details?id=com.danielZET.fimpl)
* [Teacher Gradebook](https://play.google.com/store/apps/details?id=com.apolosoft.cuadernoprofesor)
* [AS Sales Management](https://play.google.com/store/apps/details?id=com.armsoft.mtrade)
* [Sporza Voetbal](http://play.google.com/store/apps/details?id=be.vrt.mobile.android.sporza.voetbal)
* [Atmosphere](https://play.google.com/store/apps/details?id=com.peakpocketstudios.atmosphere)
* [Fitness Challenge](https://play.google.com/store/apps/details?id=com.isidroid.fitchallenge)
* [I'm Reading Quran - Kur'an Okuyorum](https://play.google.com/store/apps/details?id=com.homemade.kuranokuma)
* [Makota Money Manager](https://play.google.com/store/apps/details?id=be.jatra.makota)
* [Companion for Band](https://github.com/adithya321/Companion-for-Band)
* [Recipedia](https://play.google.com/store/apps/details?id=com.md.recipedia)
* [Right Сourse - ruble course](https://play.google.com/store/apps/details?id=com.currency.work.currencychecker)
* [Gameru](https://play.google.com/store/apps/details?id=net.gameru)
* [Boost for reddit](https://play.google.com/store/apps/details?id=com.rubenmayayo.reddit)
* [Calendula](https://github.com/citiususc/calendula)
* [MyTimes](https://github.com/debo1994/MyTimes)
* [VoIP By Antisip](https://play.google.com/store/apps/details?id=com.antisip.vbyantisip)
* [MBox - One Place for Entertainment](https://play.google.com/store/apps/details?id=com.paperwrrk.android.mbox)
* [D Notes - Smart and Material Note Taking](https://play.google.com/store/apps/details?id=com.dvdb.bergnotes)
* [Moviebase](https://play.google.com/store/apps/details?id=com.moviebase)
* [MyFuelLog2](https://play.google.com/store/apps/details?id=com.acty.myfuellog2)
* [MECSol](https://play.google.com/store/apps/details?id=tk.rlta.mecsol)
* [3D Geeks: Thingiverse Browser for 3D Printing](https://play.google.com/store/apps/details?id=work.twob.threed)
* [Tusky: Mastodon Client for Android](https://github.com/tuskyapp/Tusky)
* [Tibia Live](https://tibia.space/)
* [Walkaholic](https://play.google.com/store/apps/details?id=com.walkaholic.hikeapp)
* [Pachli: Mastodon Client](https://pachli.app)
# Articles about the MaterialDrawer
* [java-help.ru - MaterialDrawer tutorial](http://java-help.ru/material-navigationdrawer/)
* [MaterialDrawer in multiple activities](https://android.jlelse.eu/android-using-navigation-drawer-across-multiple-activities-the-easiest-way-b011f152aebd)
# Credits
- Mirosław Stanek - [GitHub](https://github.com/frogermcs)
- For his InstaMaterial concept and the idea of inflating the drawerLayout [InstaMaterial Concept](http://frogermcs.github.io/InstaMaterial-concept-part-7-navigation-drawer/)
- Lunae Luman - [Behance](https://www.behance.net/gallery/18526001/Material-Wallpaper) for the Header Image
# Developed By
- Mike Penz
- [mikepenz.dev](https://mikepenz.dev) - [blog.mikepenz.dev](https://blog.mikepenz.dev) - <mikepenz@gmail.com>
- [paypal.me/mikepenz](http://paypal.me/mikepenz)
- [Automatic changelog generation action](https://github.com/marketplace/actions/release-changelog-builder)
# License
Copyright 2021 Mike Penz
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle.kts
================================================
plugins {
id("com.mikepenz.convention.android-application")
id("com.mikepenz.convention.kotlin")
id("com.mikepenz.aboutlibraries.plugin")
id("androidx.navigation.safeargs.kotlin")
}
android {
namespace = "com.mikepenz.materialdrawer.app"
defaultConfig {
multiDexEnabled = true
setProperty("archivesBaseName", "MaterialDrawer-v$versionName-c$versionCode")
}
productFlavors {
}
buildFeatures {
viewBinding = true
}
packaging {
resources {
excludes.add("META-INF/library-core_release.kotlin_module")
excludes.add("META-INF/library_release.kotlin_module")
}
}
}
dependencies {
implementation(project(":materialdrawer"))
implementation(project(":materialdrawer-iconics"))
implementation(project(":materialdrawer-nav"))
implementation(libs.google.material)
implementation(libs.androidx.cardView)
implementation(libs.androidx.recyclerView)
implementation(libs.androidx.navigation.fragment)
implementation(libs.androidx.navigation.ui)
// used to showcase how to load images
implementation("io.coil-kt:coil:2.7.0")
//used to provide different itemAnimators for the RecyclerView
//https://github.com/mikepenz/ItemAnimators
implementation(libs.itemAnimators.core)
// used to provide out of the box icon font support. simplifies development,
// and provides scalable icons. the core is very very light
// https://github.com/mikepenz/Android-Iconics
implementation(libs.iconics.core)
// used to generate the Open Source section
// https://github.com/mikepenz/AboutLibraries
implementation(baseLibs.aboutlibraries.view)
// used to provide the MiniDrawer to normal Drawer crossfade effect via a SlidingPane layout
// --> https://github.com/mikepenz/MaterialDrawer/blob/develop/app/src/main/java/com/mikepenz/materialdrawer/app/MiniDrawerActivity.java
// https://github.com/mikepenz/Crossfader
implementation("com.mikepenz:crossfader:1.6.0@aar")
// used to provide the two step crossfade DrawerLayout. Which allows to have a mini layout which transforms to a normal layout within the drawer
// --> https://github.com/mikepenz/MaterialDrawer/blob/develop/app/src/main/java/com/mikepenz/materialdrawer/app/CrossfadeDrawerLayoutActvitiy.java
// https://github.com/mikepenz/CrossfadeDrawerLayout
implementation("com.mikepenz:crossfadedrawerlayout:1.1.0@aar")
// icon fonts used inside the sample
// https://github.com/mikepenz/Android-Iconics
implementation("com.mikepenz:google-material-typeface:4.0.0.2-kotlin@aar")
implementation("com.mikepenz:fontawesome-typeface:5.13.3.0-kotlin@aar")
implementation("com.mikepenz:octicons-typeface:11.1.0.0-kotlin@aar")
implementation("androidx.multidex:multidex:2.0.1")
implementation("androidx.slidingpanelayout:slidingpanelayout:1.1.0") {
version {
strictly("1.1.0")
}
}
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
}
configurations.configureEach {
resolutionStrategy.force(libs.fastAdapter.core)
resolutionStrategy.force(libs.iconics.core)
}
================================================
FILE: app/gradle.properties
================================================
com.mikepenz.compose.enabled=false
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Entwicklung/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".CustomApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/SampleApp.DayNight"
tools:ignore="GoogleAppIndexingWarning">
<!-- android:supportsRtl="true" -->
<activity
android:name=".DrawerActivity"
android:label="@string/app_name"
android:exported="true"
android:theme="@style/SampleApp.DayNight">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".CompactHeaderDrawerActivity"
android:label="@string/app_name"
android:theme="@style/SampleApp.DayNight.Compact" />
<activity
android:name=".PersistentDrawerActivity"
android:label="@string/app_name"
android:theme="@style/SampleApp.DayNight.Persistent" />
<activity
android:name=".ActionBarActivity"
android:theme="@style/SampleApp.DayNight.DarkActionBar" />
<activity
android:name=".MenuDrawerActivity"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".MultiDrawerActivity"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".AdvancedActivity"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".EmbeddedDrawerActivity"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".MiniDrawerActivity"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".FullscreenDrawerActivity"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".FragmentActivity"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".CollapsingToolbarActivity"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".CrossfadeDrawerLayoutActvitiy"
android:theme="@style/SampleApp.DayNight" />
<activity
android:name=".NavControllerActivity"
android:label="NavControllerExample"
android:theme="@style/SampleApp.DayNight" />
</application>
</manifest>
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/ActionBarActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.os.Bundle
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleActionbarBinding
import com.mikepenz.materialdrawer.iconics.iconicsIcon
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.Nameable
import com.mikepenz.materialdrawer.model.interfaces.nameRes
class ActionBarActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleActionbarBinding
override fun onCreate(savedInstanceState: Bundle?) {
//supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.onCreate(savedInstanceState)
binding = ActivitySampleActionbarBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
setTitle(R.string.drawer_item_action_bar_drawer)
binding.slider.apply {
itemAdapter.add(
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_home
iconicsIcon = FontAwesome.Icon.faw_home
},
SecondaryDrawerItem().apply {
nameRes = R.string.drawer_item_settings
iconicsIcon = FontAwesome.Icon.faw_cog
}
)
onDrawerItemClickListener = { _, drawerItem, _ ->
if (drawerItem is Nameable) {
Toast.makeText(this@ActionBarActivity, (drawerItem as Nameable).name!!.getText(this@ActionBarActivity), Toast.LENGTH_SHORT).show()
}
false
}
setSavedInstance(savedInstanceState)
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(false)
}
override fun onSaveInstanceState(_outState: Bundle) {
//add the values which need to be saved from the drawer to the bundle
super.onSaveInstanceState(binding.slider.saveInstanceState(_outState))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (binding.root.isDrawerOpen(binding.slider)) {
binding.root.closeDrawer(binding.slider)
} else {
super.onBackPressed()
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/AdvancedActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.content.res.Configuration
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.actionBar
import com.mikepenz.iconics.utils.backgroundColorRes
import com.mikepenz.iconics.utils.paddingDp
import com.mikepenz.iconics.utils.sizeDp
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleBinding
import com.mikepenz.materialdrawer.app.drawerItems.CustomPrimaryDrawerItem
import com.mikepenz.materialdrawer.app.drawerItems.CustomUrlPrimaryDrawerItem
import com.mikepenz.materialdrawer.app.drawerItems.OverflowMenuDrawerItem
import com.mikepenz.materialdrawer.holder.ColorHolder
import com.mikepenz.materialdrawer.holder.ImageHolder
import com.mikepenz.materialdrawer.holder.StringHolder
import com.mikepenz.materialdrawer.iconics.iconicsIcon
import com.mikepenz.materialdrawer.model.*
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.util.addStickyDrawerItems
import com.mikepenz.materialdrawer.widget.AccountHeaderView
class AdvancedActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleBinding
private lateinit var headerView: AccountHeaderView
private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
private lateinit var profile: IProfile
private lateinit var profile2: IProfile
private lateinit var profile3: IProfile
private lateinit var profile4: IProfile
private lateinit var profile5: IProfile
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true)
supportActionBar?.setTitle(R.string.drawer_item_advanced_drawer)
actionBarDrawerToggle = ActionBarDrawerToggle(this, binding.root, binding.toolbar, com.mikepenz.materialdrawer.R.string.material_drawer_open, com.mikepenz.materialdrawer.R.string.material_drawer_close)
// Create a few sample profile
profile = ProfileDrawerItem().apply { nameText = "Mike Penz"; descriptionText = "mikepenz@gmail.com"; iconRes = R.drawable.profile }
profile2 = ProfileDrawerItem().apply { nameText = "Max Muster"; descriptionText = "max.mustermann@gmail.com"; iconRes = R.drawable.profile2; identifier = 2 }
profile3 = ProfileDrawerItem().apply { nameText = "Felix House"; descriptionText = "felix.house@gmail.com"; iconRes = R.drawable.profile3 }
profile4 = ProfileDrawerItem().apply { nameText = "Mr. X"; descriptionText = "mister.x.super@gmail.com"; iconRes = R.drawable.profile4; identifier = 4 }
profile5 = ProfileDrawerItem().apply { nameText = "Batman"; descriptionText = "batman@gmail.com"; iconRes = R.drawable.profile5 }
// Create the AccountHeader
buildHeader(false, savedInstanceState)
binding.slider.apply {
itemAdapter.add(
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_home; iconicsIcon = FontAwesome.Icon.faw_home },
//here we use a customPrimaryDrawerItem we defined in our sample app
//this custom DrawerItem extends the PrimaryDrawerItem so it just overwrites some methods
OverflowMenuDrawerItem().apply {
nameRes = R.string.drawer_item_menu_drawer_item; descriptionRes = R.string.drawer_item_menu_drawer_item_desc; menu = R.menu.fragment_menu
onMenuItemClickListener = PopupMenu.OnMenuItemClickListener { item ->
Toast.makeText(this@AdvancedActivity, item.title, Toast.LENGTH_SHORT).show()
false
}
iconicsIcon = GoogleMaterial.Icon.gmd_filter_center_focus
},
CustomPrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_free_play; iconicsIcon = FontAwesome.Icon.faw_gamepad; background =
ColorHolder.fromColorRes(R.color.colorAccent)
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_custom; descriptionText = "This is a description"; iconicsIcon = FontAwesome.Icon.faw_eye
},
CustomUrlPrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_fragment_drawer; description = StringHolder(R.string.drawer_item_fragment_drawer_desc); iconUrl =
"https://avatars3.githubusercontent.com/u/1476232?v=3&s=460"
},
SectionDrawerItem().apply { nameRes = R.string.drawer_item_section_header },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_settings; iconicsIcon = FontAwesome.Icon.faw_cart_plus },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_help; iconicsIcon = FontAwesome.Icon.faw_database; isEnabled = false },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_open_source; iconicsIcon = FontAwesomeBrand.Icon.fab_github },
SecondaryDrawerItem().apply {
nameRes = R.string.drawer_item_contact; tag = "Bullhorn"; iconDrawable =
IconicsDrawable(this@AdvancedActivity, GoogleMaterial.Icon.gmd_add).apply { actionBar(); paddingDp = 5 }; isIconTinted = true
},
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_help; iconicsIcon = FontAwesome.Icon.faw_question; isEnabled = false }
)
addStickyDrawerItems(
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_settings; iconicsIcon = FontAwesome.Icon.faw_cog; identifier = 10 },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_open_source; iconicsIcon = FontAwesomeBrand.Icon.fab_github }
)
onDrawerItemClickListener = { _, drawerItem, _ ->
if (drawerItem is Nameable) {
Toast.makeText(this@AdvancedActivity, drawerItem.name?.getText(this@AdvancedActivity), Toast.LENGTH_SHORT).show()
}
false
}
setSavedInstance(savedInstanceState)
}
}
/**
* small helper method to reuse the logic to build the AccountHeader
* this will be used to replace the header of the drawer with a compact/normal header
*
* @param compact
* @param savedInstanceState
*/
private fun buildHeader(compact: Boolean, savedInstanceState: Bundle?) {
// Create the AccountHeader
headerView = AccountHeaderView(this, compact = compact).apply {
attachToSliderView(binding.slider)
headerBackground = ImageHolder(R.drawable.header)
addProfiles(
profile,
profile2,
profile3,
profile4,
profile5,
//don't ask but google uses 14dp for the add account icon in gmail but 20dp for the normal icons (like manage account)
ProfileSettingDrawerItem().apply { nameText = "Add Account"; descriptionText = "Add new GitHub Account"; iconDrawable = IconicsDrawable(this@AdvancedActivity, GoogleMaterial.Icon.gmd_add).apply { actionBar(); paddingDp = 5 }; identifier = PROFILE_SETTING.toLong() },
ProfileSettingDrawerItem().apply { nameText = "Manage Account"; iconicsIcon = GoogleMaterial.Icon.gmd_settings }
)
onAccountHeaderListener = { _, profile, _ ->
//sample usage of the onProfileChanged listener
//if the clicked item has the identifier 1 add a new profile ;)
if (profile is IDrawerItem<*> && (profile as IDrawerItem<*>).identifier == PROFILE_SETTING.toLong()) {
val newProfile = ProfileDrawerItem().apply { nameText = "Batman"; descriptionText = "batman@gmail.com"; iconRes = R.drawable.profile5; isNameShown = true }
val profiles = headerView.profiles
if (profiles != null) {
//we know that there are 2 setting elements. set the new profile above them ;)
headerView.addProfile(newProfile, profiles.size - 2)
} else {
headerView.addProfiles(newProfile)
}
}
//false if you have not consumed the event and it should close the drawer
false
}
withSavedInstance(savedInstanceState)
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
actionBarDrawerToggle.onConfigurationChanged(newConfig)
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
actionBarDrawerToggle.syncState()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle item selection
when (item.itemId) {
R.id.menu_1 -> {
//update the profile2 and set a new image.
profile2.iconDrawable = IconicsDrawable(this, GoogleMaterial.Icon.gmd_android).apply { backgroundColorRes = R.color.colorAccent; paddingDp = 4; sizeDp = 48 }
headerView.updateProfile(profile2)
return true
}
R.id.menu_4 -> {
//we want to replace our current header with a compact header
//build the new compact header
buildHeader(true, null)
return true
}
R.id.menu_5 -> {
//we want to replace our current header with a normal header
//build the new compact header
buildHeader(false, null)
binding.slider.invalidate()
return true
}
else -> {
return actionBarDrawerToggle.onOptionsItemSelected(item)
}
}
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
//add the values which need to be saved from the accountHeader to the bundle
outState = headerView.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (binding.root.isDrawerOpen(binding.slider)) {
binding.root.closeDrawer(binding.slider)
} else {
super.onBackPressed()
}
}
companion object {
private const val PROFILE_SETTING = 1
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/CollapsingToolbarActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.graphics.Color
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import coil.load
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.actionBar
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleCollapsingToolbarBinding
import com.mikepenz.materialdrawer.app.utils.convertDpToPixel
import com.mikepenz.materialdrawer.holder.ImageHolder
import com.mikepenz.materialdrawer.iconics.iconicsIcon
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.SectionDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.nameRes
import com.mikepenz.materialdrawer.util.removeAllItems
import com.mikepenz.materialdrawer.widget.AccountHeaderView
import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
class CollapsingToolbarActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleCollapsingToolbarBinding
private lateinit var headerView: AccountHeaderView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleCollapsingToolbarBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
setSupportActionBar(binding.toolbar)
binding.collapsingToolbar.title = getString(R.string.drawer_item_collapsing_toolbar_drawer)
binding.materialDrawerSwipeRefresh.setProgressViewOffset(true, 0, convertDpToPixel(48f, this).toInt())
binding.materialDrawerSwipeRefresh.setOnRefreshListener {
binding.materialDrawerSwipeRefresh.postDelayed({
binding.slider.setDrawerItems()
binding.slider.setSelection(5, false)
binding.materialDrawerSwipeRefresh.isRefreshing = false
}, 3000)
}
// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
attachToSliderView(binding.slider)
headerBackground = ImageHolder(R.drawable.header)
withSavedInstance(savedInstanceState)
}
binding.slider.apply {
setDrawerItems()
setSelection(1, false)
setSavedInstance(savedInstanceState)
}
fillFab()
loadBackdrop()
}
private fun MaterialDrawerSliderView.setDrawerItems() {
removeAllItems()
itemAdapter.add(
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_home; iconicsIcon = FontAwesome.Icon.faw_home; identifier = 1 },
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_free_play; iconicsIcon = FontAwesome.Icon.faw_gamepad },
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_custom; iconicsIcon = FontAwesome.Icon.faw_eye; identifier = 5 },
SectionDrawerItem().apply { nameRes = R.string.drawer_item_section_header },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_settings; iconicsIcon = FontAwesome.Icon.faw_cog },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_help; iconicsIcon = FontAwesome.Icon.faw_question; isEnabled = false },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_open_source; iconicsIcon = FontAwesomeBrand.Icon.fab_github },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_contact; iconicsIcon = FontAwesome.Icon.faw_bullhorn }
)
}
private fun loadBackdrop() {
binding.backdrop.load("https://unsplash.it/600/300/?random")
}
private fun fillFab() {
binding.floatingActionButton.setImageDrawable(IconicsDrawable(this, GoogleMaterial.Icon.gmd_favorite).apply { actionBar(); colorInt = Color.WHITE })
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
//add the values which need to be saved from the accountHeader to the bundle
outState = headerView.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/CompactHeaderDrawerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.content.Context
import android.content.res.Configuration
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.TypedValue
import android.view.Menu
import android.view.MenuItem
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.actionBar
import com.mikepenz.iconics.utils.paddingDp
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleBinding
import com.mikepenz.materialdrawer.holder.BadgeStyle
import com.mikepenz.materialdrawer.holder.ColorHolder
import com.mikepenz.materialdrawer.iconics.iconicsIcon
import com.mikepenz.materialdrawer.iconics.withIcon
import com.mikepenz.materialdrawer.model.*
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.widget.AccountHeaderView
class CompactHeaderDrawerActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleBinding
//save our header or result
private lateinit var headerView: AccountHeaderView
private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
supportActionBar?.setTitle(R.string.drawer_item_compact_header)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true)
actionBarDrawerToggle = ActionBarDrawerToggle(this, binding.root, binding.toolbar, com.mikepenz.materialdrawer.R.string.material_drawer_open, com.mikepenz.materialdrawer.R.string.material_drawer_close)
// Create a few sample profile
val profile = ProfileDrawerItem().apply {
nameText = "Mike Penz"; descriptionText = "mikepenz@gmail.com"; iconRes = R.drawable.profile; badgeText = "123"
badgeStyle = BadgeStyle().apply {
textColor = ColorHolder.fromColor(Color.WHITE)
color = ColorHolder.fromColorRes(R.color.colorAccent)
}
}
val profile2 = ProfileDrawerItem().apply { nameText = "Max Muster"; descriptionText = "max.mustermann@gmail.com"; iconRes = R.drawable.profile2 }
val profile3 = ProfileDrawerItem().apply { nameText = "Felix House"; descriptionText = "felix.house@gmail.com"; iconRes = R.drawable.profile3 }
val profile4 = ProfileDrawerItem().apply { nameText = "Mr. X"; descriptionText = "mister.x.super@gmail.com"; iconRes = R.drawable.profile4 }
val profile5 = ProfileDrawerItem().apply { nameText = "Batman"; descriptionText = "batman@gmail.com"; iconRes = R.drawable.profile5 }
// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
attachToSliderView(binding.slider)
addProfiles(
profile,
profile2,
profile3,
profile4,
profile5,
//don't ask but google uses 14dp for the add account icon in gmail but 20dp for the normal icons (like manage account)
ProfileSettingDrawerItem().withName("Add Account").withDescription("Add new GitHub Account").withIcon(IconicsDrawable(context, GoogleMaterial.Icon.gmd_add).apply { actionBar(); paddingDp = 5 }).withIconTinted(true).withIdentifier(PROFILE_SETTING.toLong()),
ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(100001)
)
withSavedInstance(savedInstanceState)
}
binding.slider.apply {
itemAdapter.add(
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_home; iconicsIcon = FontAwesome.Icon.faw_home; identifier = 1 },
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_free_play; iconicsIcon = FontAwesome.Icon.faw_gamepad },
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_custom; iconicsIcon = FontAwesome.Icon.faw_eye; identifier = 5 },
SectionDrawerItem().apply { nameRes = R.string.drawer_item_section_header },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_settings; iconicsIcon = FontAwesome.Icon.faw_cog },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_help; iconicsIcon = FontAwesome.Icon.faw_question; isEnabled = false },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_open_source; iconicsIcon = FontAwesomeBrand.Icon.fab_github },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_contact; iconicsIcon = FontAwesome.Icon.faw_bullhorn }
)
onDrawerItemClickListener = { _, drawerItem, _ ->
if (drawerItem.identifier == 1L) {
startSupportActionMode(ActionBarCallBack())
}
if (drawerItem is Nameable) {
binding.toolbar.title = drawerItem.name?.getText(this@CompactHeaderDrawerActivity)
}
false
}
setSavedInstance(savedInstanceState)
}
// set the selection to the item with the identifier 5
if (savedInstanceState == null) {
binding.slider.setSelection(5, false)
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
actionBarDrawerToggle.onConfigurationChanged(newConfig)
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
actionBarDrawerToggle.syncState()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true
}
return super.onOptionsItemSelected(item)
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
//add the values which need to be saved from the accountHeader to the bundle
outState = headerView.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (binding.root.isDrawerOpen(binding.slider)) {
binding.root.closeDrawer(binding.slider)
} else {
super.onBackPressed()
}
}
internal inner class ActionBarCallBack : ActionMode.Callback {
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
return false
}
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor =
getThemeColor(android.R.attr.colorPrimaryDark, ContextCompat.getColor(this@CompactHeaderDrawerActivity, R.color.colorPrimaryDark))
}
mode.menuInflater.inflate(R.menu.cab, menu)
return true
}
override fun onDestroyActionMode(mode: ActionMode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor = Color.TRANSPARENT
}
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
return false
}
private fun Context.getThemeColor(@AttrRes attr: Int, @ColorInt def: Int = 0): Int {
val tv = TypedValue()
return if (theme.resolveAttribute(attr, tv, true)) {
if (tv.resourceId != 0) ResourcesCompat.getColor(resources, tv.resourceId, theme) else tv.data
} else def
}
}
companion object {
private const val PROFILE_SETTING = 1
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/CrossfadeDrawerLayoutActvitiy.kt
================================================
package com.mikepenz.materialdrawer.app
import android.content.res.Configuration
import android.os.Bundle
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleCrossfaderBinding
import com.mikepenz.materialdrawer.iconics.iconicsIcon
import com.mikepenz.materialdrawer.interfaces.ICrossfader
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.SectionDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.util.getOptimalDrawerWidth
import com.mikepenz.materialdrawer.widget.AccountHeaderView
class CrossfadeDrawerLayoutActvitiy : AppCompatActivity() {
private lateinit var binding: ActivitySampleCrossfaderBinding
private lateinit var headerView: AccountHeaderView
private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleCrossfaderBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
//set the back arrow in the toolbars
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true)
supportActionBar?.setTitle(R.string.drawer_item_crossfade_drawer_layout_drawer)
actionBarDrawerToggle = ActionBarDrawerToggle(this, binding.root, binding.toolbar, com.mikepenz.materialdrawer.R.string.material_drawer_open, com.mikepenz.materialdrawer.R.string.material_drawer_close)
// Create a few sample profile
val profile = ProfileDrawerItem().apply { nameText = "Mike Penz"; descriptionText = "mikepenz@gmail.com"; iconRes = R.drawable.profile }
val profile2 = ProfileDrawerItem().apply { nameText = "Max Muster"; descriptionText = "max.mustermann@gmail.com"; iconRes = R.drawable.profile2 }
val profile3 = ProfileDrawerItem().apply { nameText = "Felix House"; descriptionText = "felix.house@gmail.com"; iconRes = R.drawable.profile3 }
val profile4 = ProfileDrawerItem().apply { nameText = "Mr. X"; descriptionText = "mister.x.super@gmail.com"; iconRes = R.drawable.profile4 }
val profile5 = ProfileDrawerItem().apply { nameText = "Batman"; descriptionText = "batman@gmail.com"; iconRes = R.drawable.profile5 }
// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
attachToSliderView(binding.crossFadeLargeView)
addProfiles(
profile,
profile2,
profile3,
profile4,
profile5
)
withSavedInstance(savedInstanceState)
}
binding.crossFadeLargeView.apply {
itemAdapter.add(
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_home; iconicsIcon = FontAwesome.Icon.faw_home; identifier = 1 },
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_free_play; iconicsIcon = FontAwesome.Icon.faw_gamepad },
PrimaryDrawerItem().apply { nameRes = R.string.drawer_item_custom; iconicsIcon = FontAwesome.Icon.faw_eye; identifier = 5 },
SectionDrawerItem().apply { nameRes = R.string.drawer_item_section_header },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_settings; iconicsIcon = FontAwesome.Icon.faw_cog },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_help; iconicsIcon = FontAwesome.Icon.faw_question; isEnabled = false },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_open_source; iconicsIcon = FontAwesomeBrand.Icon.fab_github },
SecondaryDrawerItem().apply { nameRes = R.string.drawer_item_contact; iconicsIcon = FontAwesome.Icon.faw_bullhorn }
)
onDrawerItemClickListener = { v, drawerItem, position ->
if (drawerItem is Nameable) {
Toast.makeText(this@CrossfadeDrawerLayoutActvitiy, drawerItem.name?.getText(this@CrossfadeDrawerLayoutActvitiy), Toast.LENGTH_SHORT).show()
}
false
}
setSavedInstance(savedInstanceState)
}
binding.crossFadeSmallView.drawer = binding.crossFadeLargeView
//define maxDrawerWidth
binding.root.maxWidthPx = getOptimalDrawerWidth(this)
binding.crossFadeSmallView.background = binding.crossFadeLargeView.background
//define the crossfader to be used with the miniDrawer. This is required to be able to automatically toggle open / close
binding.crossFadeSmallView.crossFader = object : ICrossfader {
override val isCrossfaded: Boolean
get() = binding.root.isCrossfaded
override fun crossfade() {
val isFaded = isCrossfaded
binding.root.crossfade(400)
//only close the drawer if we were already faded and want to close it now
if (isFaded) {
binding.root.closeDrawer(GravityCompat.START)
}
}
}
// set the selection to the item with the identifier 5
if (savedInstanceState == null) {
binding.crossFadeLargeView.setSelection(5, false)
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
actionBarDrawerToggle.onConfigurationChanged(newConfig)
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
actionBarDrawerToggle.syncState()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true
}
return super.onOptionsItemSelected(item)
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.crossFadeLargeView.saveInstanceState(outState)
//add the values which need to be saved from the accountHeader to the bundle
outState = headerView.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (binding.root.isDrawerOpen(binding.crossFadeSlider)) {
binding.root.closeDrawer(binding.crossFadeSlider)
} else {
super.onBackPressed()
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/CustomApplication.kt
================================================
package com.mikepenz.materialdrawer.app
import android.content.Context
import android.graphics.drawable.Drawable
import android.net.Uri
import android.widget.ImageView
import androidx.multidex.MultiDexApplication
import coil.dispose
import coil.load
import com.google.android.material.color.DynamicColors
import com.mikepenz.iconics.Iconics
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.utils.backgroundColorRes
import com.mikepenz.iconics.utils.sizeDp
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader
import com.mikepenz.materialdrawer.util.getPlaceHolder
/**
* Created by mikepenz on 27.03.15.
*/
class CustomApplication : MultiDexApplication() {
override fun onCreate() {
super.onCreate()
Iconics.init(this)
DynamicColors.applyToActivitiesIfAvailable(this)
//initialize and create the image loader logic
/*
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable) {
Picasso.get().load(uri).placeholder(placeholder).into(imageView)
}
override fun cancel(imageView: ImageView) {
Picasso.get().cancelRequest(imageView)
}
})
*/
//initialize and create the image loader logic
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
imageView.load(uri) {
allowHardware(false)
placeholder(placeholder)
}
}
override fun cancel(imageView: ImageView) {
imageView.dispose()
}
override fun placeholder(ctx: Context, tag: String?): Drawable {
//define different placeholders for different imageView targets
//default tags are accessible via the DrawerImageLoader.Tags
//custom ones can be checked via string. see the CustomUrlBasePrimaryDrawerItem LINE 111
return when (tag) {
DrawerImageLoader.Tags.PROFILE.name -> getPlaceHolder(ctx)
DrawerImageLoader.Tags.ACCOUNT_HEADER.name -> IconicsDrawable(ctx, " ").apply { backgroundColorRes = R.color.colorPrimary; sizeDp = 56 }
"customUrlItem" -> IconicsDrawable(ctx, " ").apply { backgroundColorRes = R.color.colorAccent; sizeDp = 56 }
//we use the default one for
//DrawerImageLoader.Tags.PROFILE_DRAWER_ITEM.name()
else -> super.placeholder(ctx, tag)
}
}
})
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/DrawerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Color
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import com.mikepenz.aboutlibraries.LibsBuilder
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.actionBar
import com.mikepenz.iconics.utils.paddingDp
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleBinding
import com.mikepenz.materialdrawer.holder.BadgeStyle
import com.mikepenz.materialdrawer.holder.ColorHolder
import com.mikepenz.materialdrawer.holder.StringHolder
import com.mikepenz.materialdrawer.iconics.iconicsIcon
import com.mikepenz.materialdrawer.model.*
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.util.addItems
import com.mikepenz.materialdrawer.util.updateBadge
import com.mikepenz.materialdrawer.widget.AccountHeaderView
class DrawerActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleBinding
private lateinit var headerView: AccountHeaderView
private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(false)
supportActionBar?.setHomeButtonEnabled(true)
actionBarDrawerToggle = ActionBarDrawerToggle(
this,
binding.root,
binding.toolbar,
com.mikepenz.materialdrawer.R.string.material_drawer_open,
com.mikepenz.materialdrawer.R.string.material_drawer_close
)
binding.root.addDrawerListener(actionBarDrawerToggle)
// Create a few sample profile
// NOTE you have to define the loader logic too. See the CustomApplication for more details
val profile = ProfileDrawerItem().apply {
nameText = "Mike Penz"; descriptionText = "mikepenz@gmail.com"; iconUrl = "https://avatars3.githubusercontent.com/u/1476232?v=3&s=460"; identifier =
100
}
val profile2 = ProfileDrawerItem().apply {
nameText = "Demo User"; descriptionText = "demo@github.com"; iconUrl = "https://avatars2.githubusercontent.com/u/3597376?v=3&s=460"; identifier =
101
}
val profile3 =
ProfileDrawerItem().apply { nameText = "Max Muster"; descriptionText = "max.mustermann@gmail.com"; iconRes = R.drawable.profile2; identifier = 102 }
val profile4 =
ProfileDrawerItem().apply { nameText = "Felix House"; descriptionText = "felix.house@gmail.com"; iconRes = R.drawable.profile3; identifier = 103 }
val profile5 =
ProfileDrawerItem().apply { nameText = "Mr. X"; descriptionText = "mister.x.super@gmail.com"; iconRes = R.drawable.profile4; identifier = 104 }
val profile6 = ProfileDrawerItem().apply {
nameText = "Batman"; descriptionText = "batman@gmail.com"; iconRes = R.drawable.profile5; identifier = 105; badgeText = "123"
badgeStyle = BadgeStyle().apply {
textColor = ColorHolder.fromColor(Color.BLACK)
color = ColorHolder.fromColor(Color.WHITE)
}
}
// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
attachToSliderView(binding.slider)
addProfiles(
profile,
profile2,
profile3,
profile4,
profile5,
profile6,
//don't ask but google uses 14dp for the add account icon in gmail but 20dp for the normal icons (like manage account)
ProfileSettingDrawerItem().apply {
nameText = "Add Account"; descriptionText = "Add new GitHub Account"; iconDrawable =
IconicsDrawable(context, GoogleMaterial.Icon.gmd_add).apply { actionBar(); paddingDp = 5 }.mutate(); isIconTinted = true; identifier =
PROFILE_SETTING.toLong()
},
ProfileSettingDrawerItem().apply { nameText = "Manage Account"; iconicsIcon = GoogleMaterial.Icon.gmd_settings; identifier = 100001 }
)
onAccountHeaderListener = { view, profile, current ->
//sample usage of the onProfileChanged listener
//if the clicked item has the identifier 1 add a new profile ;)
if (profile is IDrawerItem<*> && profile.identifier == PROFILE_SETTING.toLong()) {
val count = 100 + (profiles?.size ?: 0) + 1
val newProfile =
ProfileDrawerItem().withNameShown(true).withName("Batman$count").withEmail("batman$count@gmail.com").withIcon(R.drawable.profile5)
.withIdentifier(count.toLong())
profiles?.let {
//we know that there are 2 setting elements. set the new profile above them ;)
addProfile(newProfile, it.size - 2)
} ?: addProfiles(newProfile)
}
//false if you have not consumed the event and it should close the drawer
false
}
withSavedInstance(savedInstanceState)
}
binding.slider.apply {
addItems(
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_compact_header; descriptionRes = R.string.drawer_item_compact_header_desc; iconicsIcon =
GoogleMaterial.Icon.gmd_brightness_5; isSelectable = false; identifier = 1
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_action_bar_drawer; descriptionRes = R.string.drawer_item_action_bar_drawer_desc; iconicsIcon =
FontAwesome.Icon.faw_home; isSelectable = false; identifier = 2
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_multi_drawer; descriptionRes = R.string.drawer_item_multi_drawer_desc; iconicsIcon =
FontAwesome.Icon.faw_gamepad; isSelectable = false; identifier = 3
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_advanced_drawer; descriptionRes = R.string.drawer_item_advanced_drawer_desc; iconicsIcon =
GoogleMaterial.Icon.gmd_adb; isSelectable = false; identifier = 5
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_embedded_drawer; descriptionRes = R.string.drawer_item_embedded_drawer_desc; iconicsIcon =
GoogleMaterial.Icon.gmd_battery_full; isSelectable = false; identifier = 7
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_fullscreen_drawer; descriptionRes = R.string.drawer_item_fullscreen_drawer_desc; iconicsIcon =
GoogleMaterial.Icon.gmd_label; isSelectable = false; identifier = 8
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_menu_drawer; descriptionRes = R.string.drawer_item_menu_drawer_desc; iconicsIcon =
GoogleMaterial.Icon.gmd_filter_list; isSelectable = false; identifier = 10
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_mini_drawer; descriptionRes = R.string.drawer_item_mini_drawer_desc; iconicsIcon =
GoogleMaterial.Icon.gmd_battery_charging_full; isSelectable = false; identifier = 11
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_fragment_drawer; descriptionRes = R.string.drawer_item_fragment_drawer_desc; iconicsIcon =
GoogleMaterial.Icon.gmd_disc_full; isSelectable = false; identifier = 12
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_collapsing_toolbar_drawer; descriptionRes =
R.string.drawer_item_collapsing_toolbar_drawer_desc; iconicsIcon = GoogleMaterial.Icon.gmd_camera_rear; isSelectable = false; identifier =
13
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_persistent_compact_header; descriptionRes =
R.string.drawer_item_persistent_compact_header_desc; iconicsIcon = GoogleMaterial.Icon.gmd_brightness_5; isSelectable = false; identifier =
14
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_crossfade_drawer_layout_drawer; descriptionRes =
R.string.drawer_item_crossfade_drawer_layout_drawer_desc; iconicsIcon = GoogleMaterial.Icon.gmd_format_bold; isSelectable =
false; identifier = 15
},
PrimaryDrawerItem().apply {
nameRes = R.string.drawer_item_navigation_drawer; descriptionRes = R.string.drawer_item_navigation_drawer_desc; iconicsIcon =
GoogleMaterial.Icon.gmd_navigation; isSelectable = false; identifier = 1305
},
ExpandableBadgeDrawerItem().apply {
nameText = "Collapsable Badge"; iconicsIcon = GoogleMaterial.Icon.gmd_format_bold; identifier = 18; isSelectable = false; badge =
StringHolder("100")
badgeStyle = BadgeStyle().apply { textColor = ColorHolder.fromColor(Color.WHITE); color = ColorHolder.fromColorRes(R.color.colorAccent) }
subItems = mutableListOf(
SecondaryDrawerItem().apply {
nameText = "CollapsableItem"; level = 2; iconicsIcon = GoogleMaterial.Icon.gmd_format_bold; identifier = 2000
},
SecondaryDrawerItem().apply {
nameText = "CollapsableItem 2"; level = 2; iconicsIcon = GoogleMaterial.Icon.gmd_format_bold; identifier = 2001
}
)
},
ExpandableDrawerItem().apply {
nameText = "Collapsable"; iconicsIcon = GoogleMaterial.Icon.gmd_filter_list; identifier = 19; isSelectable = false
subItems = mutableListOf(
SecondaryDrawerItem().apply {
nameText = "CollapsableItem"; level = 2; iconicsIcon = GoogleMaterial.Icon.gmd_filter_list; identifier = 2002
},
SecondaryDrawerItem().apply {
nameText = "CollapsableItem 2"; level = 2; iconicsIcon = GoogleMaterial.Icon.gmd_filter_list; identifier = 2003
}
)
},
SectionDrawerItem().apply { nameRes = R.string.drawer_item_section_header },
SecondaryDrawerItem().apply {
nameRes = R.string.drawer_item_open_source; iconicsIcon = FontAwesomeBrand.Icon.fab_github; identifier = 20; isSelectable = false
},
SecondaryDrawerItem().apply {
nameRes = R.string.drawer_item_contact; iconicsIcon = GoogleMaterial.Icon.gmd_format_color_fill; identifier = 21; isSelectable = false
}
/*,
DividerDrawerItem ()
SwitchDrawerItem ().withName("Switch").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener)
SwitchDrawerItem ().withName("Switch2").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener).withSelectable(false)
ToggleDrawerItem ().withName("Toggle").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener)
DividerDrawerItem ()
SecondarySwitchDrawerItem ().withName("Secondary switch").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener)
SecondarySwitchDrawerItem ().withName("Secondary Switch2").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener).withSelectable(false)
SecondaryToggleDrawerItem ().withName("Secondary toggle").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener)
*/
)
onDrawerItemClickListener = { _, drawerItem, _ ->
//check if the drawerItem is set.
//there are different reasons for the drawerItem to be null
//--> click on the header
//--> click on the footer
//those items don't contain a drawerItem
var intent: Intent? = null
when {
drawerItem.identifier == 1L -> intent = Intent(this@DrawerActivity, CompactHeaderDrawerActivity::class.java)
drawerItem.identifier == 2L -> intent = Intent(this@DrawerActivity, ActionBarActivity::class.java)
drawerItem.identifier == 3L -> intent = Intent(this@DrawerActivity, MultiDrawerActivity::class.java)
drawerItem.identifier == 5L -> intent = Intent(this@DrawerActivity, AdvancedActivity::class.java)
drawerItem.identifier == 7L -> intent = Intent(this@DrawerActivity, EmbeddedDrawerActivity::class.java)
drawerItem.identifier == 8L -> intent = Intent(this@DrawerActivity, FullscreenDrawerActivity::class.java)
drawerItem.identifier == 10L -> intent = Intent(this@DrawerActivity, MenuDrawerActivity::class.java)
drawerItem.identifier == 11L -> intent = Intent(this@DrawerActivity, MiniDrawerActivity::class.java)
drawerItem.identifier == 12L -> intent = Intent(this@DrawerActivity, FragmentActivity::class.java)
drawerItem.identifier == 13L -> intent = Intent(this@DrawerActivity, CollapsingToolbarActivity::class.java)
drawerItem.identifier == 14L -> intent = Intent(this@DrawerActivity, PersistentDrawerActivity::class.java)
drawerItem.identifier == 15L -> intent = Intent(this@DrawerActivity, CrossfadeDrawerLayoutActvitiy::class.java)
drawerItem.identifier == 1305L -> intent = Intent(this@DrawerActivity, NavControllerActivity::class.java)
drawerItem.identifier == 20L -> intent = LibsBuilder().intent(this@DrawerActivity)
}
if (intent != null) {
this@DrawerActivity.startActivity(intent)
}
false
}
setSavedInstance(savedInstanceState)
}
//slider.withStickyHeader(R.layout.header)
//slider.addStickyDrawerItems(
// SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog).withIdentifier(10),
// SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesomeBrand.Icon.fab_github)
//)
//only set the active selection or active profile if we do not recreate the activity
if (savedInstanceState == null) {
// set the selection to the item with the identifier 11
binding.slider.setSelection(21, false)
//set the active profile
headerView.activeProfile = profile3
}
binding.slider.updateBadge(4, StringHolder(10.toString() + ""))
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
actionBarDrawerToggle.onConfigurationChanged(newConfig)
}
override fun onResume() {
super.onResume()
actionBarDrawerToggle.syncState()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true
}
return super.onOptionsItemSelected(item)
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
//add the values which need to be saved from the accountHeader to the bundle
outState = headerView.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (binding.root.isDrawerOpen(binding.slider)) {
binding.root.closeDrawer(binding.slider)
} else {
super.onBackPressed()
}
}
companion object {
private const val PROFILE_SETTING = 100000
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/EmbeddedDrawerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.view.ViewGroup
import android.widget.CompoundButton
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.actionBar
import com.mikepenz.iconics.utils.paddingDp
import com.mikepenz.materialdrawer.app.databinding.ActivityEmbeddedBinding
import com.mikepenz.materialdrawer.holder.BadgeStyle
import com.mikepenz.materialdrawer.iconics.withIcon
import com.mikepenz.materialdrawer.interfaces.OnCheckedChangeListener
import com.mikepenz.materialdrawer.model.*
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.widget.AccountHeaderView
class EmbeddedDrawerActivity : AppCompatActivity() {
private lateinit var binding: ActivityEmbeddedBinding
private lateinit var headerView: AccountHeaderView
private val onCheckedChangeListener = object : OnCheckedChangeListener {
override fun onCheckedChanged(drawerItem: IDrawerItem<*>, buttonView: CompoundButton, isChecked: Boolean) {
if (drawerItem is Nameable) {
Log.i("material-drawer", "DrawerItem: " + (drawerItem as Nameable).name + " - toggleChecked: " + isChecked)
} else {
Log.i("material-drawer", "toggleChecked: $isChecked")
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityEmbeddedBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
//set the back arrow in the toolbar
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setTitle(R.string.drawer_item_embedded_drawer)
// Create a few sample profile
// NOTE you have to define the loader logic too. See the CustomApplication for more details
val profile = ProfileDrawerItem().withName("Mike Penz").withEmail("mikepenz@gmail.com").withIcon("https://avatars3.githubusercontent.com/u/1476232?v=3&s=460")
val profile2 = ProfileDrawerItem().withName("Bernat Borras").withEmail("alorma@github.com").withIcon(Uri.parse("https://avatars3.githubusercontent.com/u/887462?v=3&s=460"))
val profile3 = ProfileDrawerItem().withName("Max Muster").withEmail("max.mustermann@gmail.com").withIcon(resources.getDrawable(R.drawable.profile2))
val profile4 = ProfileDrawerItem().withName("Felix House").withEmail("felix.house@gmail.com").withIcon(resources.getDrawable(R.drawable.profile3))
val profile5 = ProfileDrawerItem().withName("Mr. X").withEmail("mister.x.super@gmail.com").withIcon(resources.getDrawable(R.drawable.profile4)).withIdentifier(4)
val profile6 = ProfileDrawerItem().withName("Batman").withEmail("batman@gmail.com").withIcon(resources.getDrawable(R.drawable.profile5))
// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
attachToSliderView(binding.slider)
addProfiles(
profile,
profile2,
profile3,
profile4,
profile5,
profile6,
//don't ask but google uses 14dp for the add account icon in gmail but 20dp for the normal icons (like manage account)
ProfileSettingDrawerItem().withName("Add Account").withDescription("Add new GitHub Account").withIcon(IconicsDrawable(context, GoogleMaterial.Icon.gmd_add).apply { actionBar(); paddingDp = 5 }).withIconTinted(true).withIdentifier(PROFILE_SETTING.toLong()),
ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(100001)
)
onAccountHeaderListener = { view, profile, current ->
//sample usage of the onProfileChanged listener
//if the clicked item has the identifier 1 add a new profile ;)
if (profile is IDrawerItem<*> && (profile as IDrawerItem<*>).identifier == PROFILE_SETTING.toLong()) {
val newProfile = ProfileDrawerItem().withNameShown(true).withName("Batman").withEmail("batman@gmail.com").withIcon(resources.getDrawable(R.drawable.profile5))
headerView.profiles?.let {
//we know that there are 2 setting elements. set the new profile above them ;)
headerView.addProfile(newProfile, it.size - 2)
} ?: headerView.addProfiles(newProfile)
}
//false if you have not consumed the event and it should close the drawer
false
}
withSavedInstance(savedInstanceState)
}
binding.slider.apply {
customWidth = ViewGroup.LayoutParams.MATCH_PARENT
itemAdapter.add(
PrimaryDrawerItem().withName(R.string.drawer_item_compact_header).withIcon(GoogleMaterial.Icon.gmd_brightness_5).withIdentifier(1),
PrimaryDrawerItem().withName(R.string.drawer_item_action_bar_drawer).withIcon(FontAwesome.Icon.faw_home).withBadge("22")
.withBadgeStyle(BadgeStyle(Color.RED, Color.RED)).withIdentifier(2),
PrimaryDrawerItem().withName(R.string.drawer_item_multi_drawer).withIcon(FontAwesome.Icon.faw_gamepad).withIdentifier(3),
PrimaryDrawerItem().withName(R.string.drawer_item_non_translucent_status_drawer).withIcon(FontAwesome.Icon.faw_eye).withIdentifier(4),
PrimaryDrawerItem().withDescription("A more complex sample").withName(R.string.drawer_item_advanced_drawer)
.withIcon(GoogleMaterial.Icon.gmd_adb).withIdentifier(5),
SectionDrawerItem().withName(R.string.drawer_item_section_header),
SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesomeBrand.Icon.fab_github),
SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(GoogleMaterial.Icon.gmd_format_color_fill).withTag("Bullhorn"),
DividerDrawerItem(),
SwitchDrawerItem().withName("Switch").withIcon(GoogleMaterial.Icon.gmd_pan_tool).withChecked(true)
.withOnCheckedChangeListener(onCheckedChangeListener),
ToggleDrawerItem().withName("Toggle").withIcon(GoogleMaterial.Icon.gmd_pan_tool).withChecked(true)
.withOnCheckedChangeListener(onCheckedChangeListener)
)
onDrawerItemClickListener = { v, drawerItem, position ->
if (drawerItem is Nameable) {
Toast.makeText(this@EmbeddedDrawerActivity, drawerItem.name?.getText(this@EmbeddedDrawerActivity), Toast.LENGTH_SHORT).show()
}
false
}
setSavedInstance(savedInstanceState)
}
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
//add the values which need to be saved from the accountHeader to the bundle
outState = headerView.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//handle the click on the back arrow click
return when (item.itemId) {
android.R.id.home -> {
onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
companion object {
private const val PROFILE_SETTING = 1
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/FragmentActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleFragmentBinding
import com.mikepenz.materialdrawer.app.fragment.DrawerFragment
import com.mikepenz.materialdrawer.app.fragment.SecondDrawerFragment
class FragmentActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleFragmentBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleFragmentBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
supportActionBar?.setTitle(R.string.drawer_item_fragment_drawer)
//ignore the DemoFragment and it's layout it's just to showcase the handle with an keyboard
if (savedInstanceState == null) {
val f = DrawerFragment.newInstance("Demo")
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, f).commit()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.fragment_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//handle the click on the back arrow click
when (item.itemId) {
R.id.menu_1 -> {
val f = DrawerFragment.newInstance("Demo")
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, f).commit()
return true
}
R.id.menu_2 -> {
val f2 = SecondDrawerFragment.newInstance("Demo 2")
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, f2).commit()
return true
}
android.R.id.home -> {
onBackPressed()
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/FullscreenDrawerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.content.res.Configuration
import android.graphics.Color
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.updatePadding
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleFullscreenBinding
import com.mikepenz.materialdrawer.iconics.withIcon
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.SectionDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.withEnabled
import com.mikepenz.materialdrawer.model.interfaces.withIdentifier
import com.mikepenz.materialdrawer.model.interfaces.withName
class FullscreenDrawerActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleFullscreenBinding
private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleFullscreenBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
binding.toolbar.setBackgroundColor(Color.BLACK)
binding.toolbar.background.alpha = 90
supportActionBar?.setTitle(R.string.drawer_item_fullscreen_drawer)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true)
actionBarDrawerToggle = ActionBarDrawerToggle(this, binding.root, binding.toolbar, com.mikepenz.materialdrawer.R.string.material_drawer_open, com.mikepenz.materialdrawer.R.string.material_drawer_close)
binding.slider.apply {
itemAdapter.add(
PrimaryDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home).withIdentifier(1),
PrimaryDrawerItem().withName(R.string.drawer_item_free_play).withIcon(FontAwesome.Icon.faw_gamepad),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
//add some more items to get a scrolling list
SectionDrawerItem().withName(R.string.drawer_item_section_header),
SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog),
SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_question).withEnabled(false),
SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesomeBrand.Icon.fab_github),
SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(FontAwesome.Icon.faw_bullhorn),
SectionDrawerItem().withName(R.string.drawer_item_section_header),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye)
)
setSavedInstance(savedInstanceState)
}
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
binding.toolbar.updatePadding(top = insets.systemWindowInsetTop)
insets
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
actionBarDrawerToggle.onConfigurationChanged(newConfig)
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
actionBarDrawerToggle.syncState()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true
}
return super.onOptionsItemSelected(item)
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (binding.root.isDrawerOpen(binding.slider)) {
binding.root.closeDrawer(binding.slider)
} else {
super.onBackPressed()
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/MenuDrawerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.content.res.Configuration
import android.os.Bundle
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleBinding
import com.mikepenz.materialdrawer.model.interfaces.Nameable
import com.mikepenz.materialdrawer.util.inflateMenu
class MenuDrawerActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleBinding
private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
supportActionBar?.setTitle(R.string.drawer_item_menu_drawer)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true)
actionBarDrawerToggle = ActionBarDrawerToggle(this, binding.root, binding.toolbar, com.mikepenz.materialdrawer.R.string.material_drawer_open, com.mikepenz.materialdrawer.R.string.material_drawer_close)
binding.slider.apply {
inflateMenu(R.menu.example_menu)
onDrawerItemClickListener = { v, drawerItem, position ->
if (drawerItem is Nameable) {
Toast.makeText(this@MenuDrawerActivity, (drawerItem as Nameable).name!!.getText(this@MenuDrawerActivity), Toast.LENGTH_SHORT).show()
}
false
}
setSavedInstance(savedInstanceState)
}
// set the selection to the item with the identifier 5
if (savedInstanceState == null) {
binding.slider.setSelection(5, false)
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
actionBarDrawerToggle.onConfigurationChanged(newConfig)
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
actionBarDrawerToggle.syncState()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true
}
return super.onOptionsItemSelected(item)
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (binding.root.isDrawerOpen(binding.slider)) {
binding.root.closeDrawer(binding.slider)
} else {
super.onBackPressed()
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/MiniDrawerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.content.res.Configuration
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.CompoundButton
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.mikepenz.crossfader.Crossfader
import com.mikepenz.crossfader.util.UIUtils
import com.mikepenz.crossfader.view.CrossFadeSlidingPaneLayout
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.actionBar
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.materialdrawer.app.databinding.ActivityMiniDrawerBinding
import com.mikepenz.materialdrawer.app.utils.CrossfadeWrapper
import com.mikepenz.materialdrawer.app.utils.SystemUtils
import com.mikepenz.materialdrawer.holder.BadgeStyle
import com.mikepenz.materialdrawer.iconics.withIcon
import com.mikepenz.materialdrawer.interfaces.OnCheckedChangeListener
import com.mikepenz.materialdrawer.model.*
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.model.utils.withIsHiddenInMiniDrawer
import com.mikepenz.materialdrawer.widget.AccountHeaderView
import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
import com.mikepenz.materialdrawer.widget.MiniDrawerSliderView
class MiniDrawerActivity : AppCompatActivity() {
private lateinit var binding: ActivityMiniDrawerBinding
//save our header or result
private lateinit var headerView: AccountHeaderView
private lateinit var miniSliderView: MiniDrawerSliderView
private lateinit var sliderView: MaterialDrawerSliderView
private lateinit var crossFader: Crossfader<*>
private val onCheckedChangeListener = object : OnCheckedChangeListener {
override fun onCheckedChanged(drawerItem: IDrawerItem<*>, buttonView: CompoundButton, isChecked: Boolean) {
if (drawerItem is Nameable) {
Log.i("material-drawer", "DrawerItem: " + (drawerItem as Nameable).name + " - toggleChecked: " + isChecked)
} else {
Log.i("material-drawer", "toggleChecked: $isChecked")
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMiniDrawerBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
//set the back arrow in the toolbar
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setTitle(R.string.drawer_item_mini_drawer)
// Create a few sample profile
// NOTE you have to define the loader logic too. See the CustomApplication for more details
val profile = ProfileDrawerItem().withName("Mike Penz").withEmail("mikepenz@gmail.com").withIcon("https://avatars3.githubusercontent.com/u/1476232?v=3&s=460")
val profile2 = ProfileDrawerItem().withName("Bernat Borras").withEmail("alorma@github.com").withIcon(Uri.parse("https://avatars3.githubusercontent.com/u/887462?v=3&s=460"))
val profile3 = ProfileDrawerItem().withName("Max Muster").withEmail("max.mustermann@gmail.com").withIcon(resources.getDrawable(R.drawable.profile2))
val profile4 = ProfileDrawerItem().withName("Felix House").withEmail("felix.house@gmail.com").withIcon(resources.getDrawable(R.drawable.profile3))
val profile5 = ProfileDrawerItem().withName("Mr. X").withEmail("mister.x.super@gmail.com").withIcon(resources.getDrawable(R.drawable.profile4)).withIdentifier(4)
val profile6 = ProfileDrawerItem().withName("Batman").withEmail("batman@gmail.com").withIcon(resources.getDrawable(R.drawable.profile5))
// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
addProfiles(
profile,
profile2,
profile3,
profile4,
profile5,
profile6,
//don't ask but google uses 14dp for the add account icon in gmail but 20dp for the normal icons (like manage account)
ProfileSettingDrawerItem().withName("Add Account").withDescription("Add new GitHub Account").withIcon(GoogleMaterial.Icon.gmd_add).withIdentifier(PROFILE_SETTING.toLong()),
ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings)
)
onAccountHeaderListener = { view, profile, current ->
//sample usage of the onProfileChanged listener
//if the clicked item has the identifier 1 add a new profile ;)
if (profile is IDrawerItem<*> && (profile as IDrawerItem<*>).identifier == PROFILE_SETTING.toLong()) {
val newProfile = ProfileDrawerItem().withNameShown(true).withName("Batman").withEmail("batman@gmail.com").withIcon(resources.getDrawable(R.drawable.profile5))
headerView.profiles?.let {
//we know that there are 2 setting elements. set the new profile above them ;)
headerView.addProfile(newProfile, it.size - 2)
} ?: headerView.addProfiles(newProfile)
}
//false if you have not consumed the event and it should close the drawer
false
}
withSavedInstance(savedInstanceState)
}
sliderView = MaterialDrawerSliderView(this).apply {
accountHeader = this@MiniDrawerActivity.headerView
customWidth = MATCH_PARENT
itemAdapter.add(
PrimaryDrawerItem().withName(R.string.drawer_item_compact_header).withIcon(GoogleMaterial.Icon.gmd_brightness_5).withIdentifier(1),
PrimaryDrawerItem().withName("Item NOT in mini drawer").withIcon(GoogleMaterial.Icon.gmd_bluetooth).withIdentifier(100)
.withIsHiddenInMiniDrawer(true),
PrimaryDrawerItem().withName(R.string.drawer_item_action_bar_drawer).withIcon(FontAwesome.Icon.faw_home).withBadge("22")
.withBadgeStyle(BadgeStyle(Color.RED, Color.RED)).withIdentifier(2).withSelectable(false),
PrimaryDrawerItem().withName(R.string.drawer_item_multi_drawer).withIcon(FontAwesome.Icon.faw_gamepad).withIdentifier(3),
PrimaryDrawerItem().withName(R.string.drawer_item_non_translucent_status_drawer).withIcon(FontAwesome.Icon.faw_eye).withIdentifier(4),
PrimaryDrawerItem().withDescription("A more complex sample").withName(R.string.drawer_item_advanced_drawer)
.withIcon(GoogleMaterial.Icon.gmd_adb).withIdentifier(5),
SectionDrawerItem().withName(R.string.drawer_item_section_header),
SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesomeBrand.Icon.fab_github),
SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(GoogleMaterial.Icon.gmd_format_color_fill).withTag("Bullhorn"),
DividerDrawerItem(),
SwitchDrawerItem().withName("Switch").withIcon(GoogleMaterial.Icon.gmd_pan_tool).withChecked(true)
.withOnCheckedChangeListener(onCheckedChangeListener),
ToggleDrawerItem().withName("Toggle").withIcon(GoogleMaterial.Icon.gmd_pan_tool).withChecked(true)
.withOnCheckedChangeListener(onCheckedChangeListener)
)
onDrawerItemClickListener = { v, item, position ->
if (item is Nameable) {
Toast.makeText(this@MiniDrawerActivity, item.name?.getText(this@MiniDrawerActivity), Toast.LENGTH_SHORT).show()
}
false
}
}
miniSliderView = MiniDrawerSliderView(this).apply {
drawer = sliderView
}
//get the widths in px for the first and second panel
val firstWidth = UIUtils.convertDpToPixel(300f, this).toInt()
val secondWidth = UIUtils.convertDpToPixel(72f, this).toInt()
//create and build our crossfader (see the MiniDrawer is also builded in here, as the build method returns the view to be used in the crossfader)
//the crossfader library can be found here: https://github.com/mikepenz/Crossfader
crossFader = Crossfader<CrossFadeSlidingPaneLayout>()
.withContent(findViewById<View>(R.id.crossfade_content))
.withFirst(sliderView, firstWidth)
.withSecond(miniSliderView, secondWidth)
.withSavedInstance(savedInstanceState)
.build()
//define the crossfader to be used with the miniDrawer. This is required to be able to automatically toggle open / close
miniSliderView.crossFader = CrossfadeWrapper(crossFader)
//define a shadow (this is only for normal LTR layouts if you have a RTL app you need to define the other one
crossFader.getCrossFadeSlidingPaneLayout().setShadowResourceLeft(com.mikepenz.materialdrawer.R.drawable.material_drawer_shadow_left)
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values, which need to be saved from the drawer to the bundle
if (::sliderView.isInitialized) {
outState = sliderView.saveInstanceState(outState)
}
//add the values, which need to be saved from the accountHeader to the bundle
if (::headerView.isInitialized) {
outState = headerView.saveInstanceState(outState)
}
//add the values, which need to be saved from the crossFader to the bundle
if (::crossFader.isInitialized) {
outState = crossFader.saveInstanceState(outState)
}
super.onSaveInstanceState(outState)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
if (SystemUtils.screenOrientation == Configuration.ORIENTATION_LANDSCAPE) {
inflater.inflate(R.menu.embedded, menu)
menu.findItem(R.id.menu_1).icon = IconicsDrawable(this, GoogleMaterial.Icon.gmd_sort).apply { actionBar(); colorInt = Color.WHITE }
}
return true
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (crossFader.isCrossFaded) {
crossFader.crossFade()
} else {
super.onBackPressed()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//handle the click on the back arrow click
return when (item.itemId) {
R.id.menu_1 -> {
crossFader.crossFade()
true
}
android.R.id.home -> {
onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
companion object {
private const val PROFILE_SETTING = 1
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/MultiDrawerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.os.Bundle
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.materialdrawer.app.databinding.ActivityMultiSampleBinding
import com.mikepenz.materialdrawer.app.drawerItems.GmailDrawerItem
import com.mikepenz.materialdrawer.iconics.withIcon
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.SectionDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.util.updateItem
class MultiDrawerActivity : AppCompatActivity() {
private lateinit var binding: ActivityMultiSampleBinding
override fun onCreate(savedInstanceState: Bundle?) {
//supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.onCreate(savedInstanceState)
binding = ActivityMultiSampleBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
// Handle Toolbar
setSupportActionBar(binding.toolbar)
supportActionBar?.setTitle(R.string.drawer_item_multi_drawer)
binding.slider.apply {
itemAdapter.add(
GmailDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home).withIdentifier(1),
GmailDrawerItem().withName(R.string.drawer_item_free_play).withIcon(FontAwesome.Icon.faw_gamepad),
GmailDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye).withIdentifier(5),
SectionDrawerItem().withName(R.string.drawer_item_section_header),
SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog),
SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_question).withEnabled(false),
SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesomeBrand.Icon.fab_github),
SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(FontAwesome.Icon.faw_bullhorn)
)
adapter.onClickListener = { v, adapter, drawerItem, position ->
if (drawerItem is Badgeable) {
if (drawerItem.badge != null) {
//note don't do this if your badge contains a "+"
//only use toString() if you set the test as String
val badge = Integer.valueOf(drawerItem.badge?.toString() ?: "0")
if (badge > 0) {
drawerItem.withBadge((badge - 1).toString())
binding.slider.updateItem(drawerItem)
}
}
}
if (drawerItem is Nameable) {
Toast.makeText(this@MultiDrawerActivity, drawerItem.name?.getText(this@MultiDrawerActivity), Toast.LENGTH_SHORT).show()
}
false
}
setSavedInstance(savedInstanceState)
setSelectionAtPosition(0)
}
binding.sliderEnd.apply {
stickyHeaderView = layoutInflater.inflate(R.layout.header, null)
itemAdapter.add(
PrimaryDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home).withIdentifier(1),
PrimaryDrawerItem().withName(R.string.drawer_item_free_play).withIcon(FontAwesome.Icon.faw_gamepad),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye).withIdentifier(5),
SectionDrawerItem().withName(R.string.drawer_item_section_header),
SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog),
SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_question).withEnabled(false),
SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesomeBrand.Icon.fab_github),
SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(FontAwesome.Icon.faw_bullhorn)
)
adapter.onClickListener = { v, adapter, drawerItem, position ->
if (drawerItem is Nameable) {
Toast.makeText(this@MultiDrawerActivity, drawerItem.name?.getText(this@MultiDrawerActivity), Toast.LENGTH_SHORT).show()
}
false
}
savedInstanceKey = "end"
setSavedInstance(savedInstanceState)
}
//set the back arrow in the toolbar
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(false)
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
//add the values which need to be saved from the drawer to the bundle
outState = binding.sliderEnd.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
when {
binding.root.isDrawerOpen(binding.slider) -> binding.root.closeDrawer(binding.slider)
binding.root.isDrawerOpen(binding.sliderEnd) -> binding.root.closeDrawer(binding.sliderEnd)
else -> super.onBackPressed()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//handle the click on the back arrow click
return when (item.itemId) {
android.R.id.home -> {
onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/NavControllerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.os.bundleOf
import androidx.navigation.findNavController
import com.mikepenz.aboutlibraries.LibsBuilder
import com.mikepenz.materialdrawer.app.databinding.ActivitySampleNavBinding
import com.mikepenz.materialdrawer.model.DividerDrawerItem
import com.mikepenz.materialdrawer.model.NavigationDrawerItem
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.withName
import com.mikepenz.materialdrawer.util.addItems
import com.mikepenz.materialdrawer.util.addStickyDrawerItems
import com.mikepenz.materialdrawer.util.setupWithNavController
import java.io.Serializable
class NavControllerActivity : AppCompatActivity() {
private lateinit var binding: ActivitySampleNavBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleNavBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val navController = findNavController(R.id.nav_host_fragment)
binding.slider.apply {
addItems(
NavigationDrawerItem(R.id.action_global_fragmentHome, PrimaryDrawerItem().withName("Home"), null, null),
DividerDrawerItem(),
NavigationDrawerItem(R.id.messageFragment1, PrimaryDrawerItem().withName("Fragment1")),
NavigationDrawerItem(R.id.messageFragment2, PrimaryDrawerItem().withName("Fragment2"))
)
addStickyDrawerItems(
NavigationDrawerItem(R.id.messageFragment3, PrimaryDrawerItem().withName("Fragment3")),
NavigationDrawerItem(R.id.about_libraries, PrimaryDrawerItem().withName("AboutLibs"), bundleOf("data" to (LibsBuilder() as Serializable)))
)
}
// setup the drawer with navigation controller
binding.slider.setupWithNavController(navController)
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/PersistentDrawerActivity.kt
================================================
package com.mikepenz.materialdrawer.app
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.updatePadding
import com.mikepenz.crossfader.Crossfader
import com.mikepenz.crossfader.util.UIUtils
import com.mikepenz.crossfader.view.CrossFadeSlidingPaneLayout
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import com.mikepenz.materialdrawer.app.databinding.ActivityPersistentDrawerBinding
import com.mikepenz.materialdrawer.app.utils.CrossfadeWrapper
import com.mikepenz.materialdrawer.holder.ImageHolder
import com.mikepenz.materialdrawer.iconics.withIcon
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.SectionDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.widget.AccountHeaderView
import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
import com.mikepenz.materialdrawer.widget.MiniDrawerSliderView
class PersistentDrawerActivity : AppCompatActivity() {
private lateinit var binding: ActivityPersistentDrawerBinding
//save our header or result
private lateinit var headerView: AccountHeaderView
private lateinit var miniSliderView: MiniDrawerSliderView
private lateinit var sliderView: MaterialDrawerSliderView
private lateinit var crossFader: Crossfader<*>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityPersistentDrawerBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
//Remove line to test RTL support
// getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
//example how to implement a persistentDrawer as shown in the google material design guidelines
//https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0Bx4BSt6jniD7YVdKQlF3TEo2S3M/patterns_navdrawer_behavior_persistent2.png
//https://www.google.com/design/spec/patterns/navigation-drawer.html#navigation-drawer-behavior
// Handle Toolbar
setSupportActionBar(binding.toolbar)
supportActionBar?.setTitle(R.string.drawer_item_persistent_compact_header)
// Create a few sample profile
val profile = ProfileDrawerItem().withName("Mike Penz").withEmail("mikepenz@gmail.com").withIcon(R.drawable.profile)
val profile2 = ProfileDrawerItem().withName("Max Muster").withEmail("max.mustermann@gmail.com").withIcon(R.drawable.profile2)
val profile3 = ProfileDrawerItem().withName("Felix House").withEmail("felix.house@gmail.com").withIcon(R.drawable.profile3)
val profile4 = ProfileDrawerItem().withName("Mr. X").withEmail("mister.x.super@gmail.com").withIcon(R.drawable.profile4)
val profile5 = ProfileDrawerItem().withName("Batman").withEmail("batman@gmail.com").withIcon(R.drawable.profile5)
// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
addProfiles(
profile,
profile2,
profile3,
profile4,
profile5
)
headerBackground = ImageHolder(ColorDrawable(Color.parseColor("#FDFDFD")))
}
// UIUtils.getActionBarHeight(this))
//.withAccountHeader(R.layout.material_drawer_compact_persistent_header)
//Create the drawer
sliderView = MaterialDrawerSliderView(this).apply {
accountHeader = this@PersistentDrawerActivity.headerView
customWidth = ViewGroup.LayoutParams.MATCH_PARENT
itemAdapter.add(
PrimaryDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home).withIdentifier(1),
PrimaryDrawerItem().withName(R.string.drawer_item_free_play).withIcon(FontAwesome.Icon.faw_gamepad),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
SectionDrawerItem().withName(R.string.drawer_item_section_header),
SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog),
SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_question).withEnabled(false),
SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesomeBrand.Icon.fab_github),
SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(FontAwesome.Icon.faw_bullhorn)
)
}
// create the MiniDrawer and define the drawer and header to be used (it will automatically use the items from them)
miniSliderView = MiniDrawerSliderView(this).apply {
includeSecondaryDrawerItems = true
drawer = sliderView
}
//set the back arrow in the toolbar
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(false)
//get the widths in px for the first and second panel
val firstWidth = UIUtils.convertDpToPixel(300f, this).toInt()
val secondWidth = UIUtils.convertDpToPixel(72f, this).toInt()
//create and build our crossfader (see the MiniDrawer is also builded in here, as the build method returns the view to be used in the crossfader)
crossFader = Crossfader<CrossFadeSlidingPaneLayout>()
.withContent(findViewById<View>(R.id.crossfade_content))
.withFirst(sliderView as View, firstWidth)
.withSecond(miniSliderView, secondWidth)
.withSavedInstance(savedInstanceState)
.build()
//define the crossfader to be used with the miniDrawer. This is required to be able to automatically toggle open / close
miniSliderView.crossFader = CrossfadeWrapper(crossFader)
//define and create the arrow ;)
val toggle = headerView.findViewById<ImageView>(R.id.material_drawer_account_header_toggle)
//for RTL you would have to define the other arrow
toggle.setImageDrawable(IconicsDrawable(this, GoogleMaterial.Icon.gmd_chevron_left).apply { sizeDp = 16; colorInt = Color.BLACK })
toggle.setOnClickListener { crossFader.crossFade() }
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
binding.toolbar.updatePadding(top = insets.systemWindowInsetTop)
insets
}
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values, which need to be saved from the drawer to the bundle
if (::sliderView.isInitialized) {
outState = sliderView.saveInstanceState(outState)
}
//add the values, which need to be saved from the accountHeader to the bundle
if (::headerView.isInitialized) {
outState = headerView.saveInstanceState(outState)
}
//add the values, which need to be saved from the crossFader to the bundle
if (::crossFader.isInitialized) {
outState = crossFader.saveInstanceState(outState)
}
super.onSaveInstanceState(outState)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//handle the click on the back arrow click
return when (item.itemId) {
android.R.id.home -> {
onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
override fun onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (crossFader.isCrossFaded) {
crossFader.crossFade()
} else {
super.onBackPressed()
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/AccountDividerDrawerItem.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import android.content.res.ColorStateList
import android.view.View
import androidx.annotation.LayoutRes
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.holder.ImageHolder
import com.mikepenz.materialdrawer.holder.StringHolder
import com.mikepenz.materialdrawer.model.AbstractDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IProfile
import com.mikepenz.materialdrawer.util.getDividerColor
class AccountDividerDrawerItem : AbstractDrawerItem<AccountDividerDrawerItem, AccountDividerDrawerItem.ViewHolder>(), IProfile {
override val type: Int
get() = R.id.material_drawer_profile_item_divider
override val layoutRes: Int
@LayoutRes
get() = com.mikepenz.materialdrawer.R.layout.material_drawer_item_divider
override var name: StringHolder? = null
override var description: StringHolder? = null
override var icon: ImageHolder? = null
override var iconColor: ColorStateList? = null
override fun bindView(holder: ViewHolder, payloads: List<Any>) {
super.bindView(holder, payloads)
val ctx = holder.itemView.context
//set the identifier from the drawerItem here. It can be used to run tests
holder.itemView.id = hashCode()
//define how the divider should look like
holder.view.isClickable = false
holder.view.isEnabled = false
holder.view.minimumHeight = 1
ViewCompat.setImportantForAccessibility(holder.view,
ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO)
//set the color for the divider
holder.divider.setBackgroundColor(ctx.getDividerColor())
//call the onPostBindView method to trigger post bind view actions (like the listener to modify the item if required)
onPostBindView(this, holder.itemView)
}
override fun getViewHolder(v: View): ViewHolder {
return ViewHolder(v)
}
class ViewHolder internal constructor(internal val view: View) : RecyclerView.ViewHolder(view) {
internal val divider: View = view.findViewById(com.mikepenz.materialdrawer.R.id.material_drawer_divider)
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomBaseViewHolder.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mikepenz.materialdrawer.app.R
open class CustomBaseViewHolder(var view: View) : RecyclerView.ViewHolder(view) {
var icon: ImageView = view.findViewById<ImageView>(R.id.material_drawer_icon)
var name: TextView = view.findViewById<TextView>(R.id.material_drawer_name)
var description: TextView = view.findViewById<TextView>(R.id.material_drawer_description)
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomCenteredPrimaryDrawerItem.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
class CustomCenteredPrimaryDrawerItem : PrimaryDrawerItem() {
override val layoutRes: Int
get() = R.layout.material_drawer_item_primary_centered
override val type: Int
get() = R.id.material_drawer_item_centered_primary
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomPrimaryDrawerItem.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import com.mikepenz.materialdrawer.holder.ColorHolder
import com.mikepenz.materialdrawer.model.AbstractBadgeableDrawerItem
class CustomPrimaryDrawerItem : AbstractBadgeableDrawerItem<CustomPrimaryDrawerItem>() {
var background: ColorHolder? = null
fun withBackgroundColor(backgroundColor: Int): CustomPrimaryDrawerItem {
this.background = ColorHolder.fromColor(backgroundColor)
return this
}
fun withBackgroundRes(backgroundRes: Int): CustomPrimaryDrawerItem {
this.background = ColorHolder.fromColorRes(backgroundRes)
return this
}
override fun bindView(holder: AbstractBadgeableDrawerItem.ViewHolder, payloads: List<Any>) {
super.bindView(holder, payloads)
background?.applyToBackground(holder.itemView)
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomUrlBasePrimaryDrawerItem.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import android.net.Uri
import androidx.annotation.StringRes
import androidx.recyclerview.widget.RecyclerView
import com.mikepenz.materialdrawer.holder.ColorHolder
import com.mikepenz.materialdrawer.holder.ImageHolder
import com.mikepenz.materialdrawer.holder.StringHolder
import com.mikepenz.materialdrawer.model.BaseDrawerItem
import com.mikepenz.materialdrawer.util.DrawerImageLoader
import com.mikepenz.materialdrawer.util.setDrawerVerticalPadding
import com.mikepenz.materialdrawer.util.themeDrawerItem
/**
* Created by mikepenz on 03.02.15.
*/
abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> : BaseDrawerItem<T, VH>() {
var description: StringHolder? = null
var descriptionTextColor: ColorHolder? = null
fun withIcon(url: String): T {
this.icon = ImageHolder(url)
return this as T
}
fun withIcon(uri: Uri): T {
this.icon = ImageHolder(uri)
return this as T
}
fun withDescription(description: String): T {
this.description = StringHolder(description)
return this as T
}
fun withDescription(@StringRes descriptionRes: Int): T {
this.description = StringHolder(descriptionRes)
return this as T
}
/**
* a helper method to have the logic for all secondaryDrawerItems only once
*
* @param viewHolder
*/
protected fun bindViewHelper(viewHolder: CustomBaseViewHolder) {
val ctx = viewHolder.itemView.context
//set the identifier from the drawerItem here. It can be used to run tests
viewHolder.itemView.id = hashCode()
//get the correct color for the background
val selectedColor = getSelectedColor(ctx)
//get the correct color for the text
val color = getColor(ctx)
val shapeAppearanceModel = getShapeAppearanceModel(ctx)
//set the background for the item
themeDrawerItem(ctx, viewHolder.view, selectedColor, isSelectedBackgroundAnimated, shapeAppearanceModel, isSelected = isSelected)
//set the text for the name
StringHolder.applyTo(this.name, viewHolder.name)
//set the text for the description or hide
StringHolder.applyToOrHide(this.description, viewHolder.description)
//set the colors for textViews
viewHolder.name.setTextColor(color)
//set the description text color
descriptionTextColor?.applyToOr(viewHolder.description, color)
//define the typeface for our textViews
if (typeface != null) {
viewHolder.name.typeface = typeface
viewHolder.description.typeface = typeface
}
//we make sure we reset the image first before setting the new one in case there is an empty one
DrawerImageLoader.instance.cancelImage(viewHolder.icon)
viewHolder.icon.setImageBitmap(null)
//get the drawables for our icon and set it
icon?.applyTo(viewHolder.icon, "customUrlItem")
//for android API 17 --> Padding not applied via xml
setDrawerVerticalPadding(viewHolder.view)
//set the item selected if it is
viewHolder.itemView.isSelected = isSelected
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomUrlPrimaryDrawerItem.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import android.view.View
import android.widget.TextView
import androidx.annotation.LayoutRes
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.holder.BadgeStyle
import com.mikepenz.materialdrawer.holder.StringHolder
import com.mikepenz.materialdrawer.model.interfaces.ColorfulBadgeable
/**
* Created by mikepenz on 03.02.15.
*/
class CustomUrlPrimaryDrawerItem : CustomUrlBasePrimaryDrawerItem<CustomUrlPrimaryDrawerItem, CustomUrlPrimaryDrawerItem.ViewHolder>(), ColorfulBadgeable {
override var badge: StringHolder? = null
override var badgeStyle: BadgeStyle? = BadgeStyle()
override val type: Int
get() = R.id.material_drawer_item_custom_url_item
override val layoutRes: Int
@LayoutRes
get() = com.mikepenz.materialdrawer.R.layout.material_drawer_item_primary
override fun bindView(holder: ViewHolder, payloads: List<Any>) {
super.bindView(holder, payloads)
val ctx = holder.itemView.context
//bind the basic view parts
bindViewHelper(holder)
//set the text for the badge or hide
val badgeVisible = StringHolder.applyToOrHide(badge, holder.badge)
//style the badge if it is visible
if (badgeVisible) {
badgeStyle!!.style(holder.badge, getColor(ctx))
holder.badge.visibility = View.VISIBLE
} else {
holder.badge.visibility = View.GONE
}
//define the typeface for our textViews
if (typeface != null) {
holder.badge.typeface = typeface
}
//call the onPostBindView method to trigger post bind view actions (like the listener to modify the item if required)
onPostBindView(this, holder.itemView)
}
override fun getViewHolder(v: View): ViewHolder {
return ViewHolder(v)
}
class ViewHolder(view: View) : CustomBaseViewHolder(view) {
internal val badge: TextView = view.findViewById(R.id.material_drawer_badge)
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/GmailDrawerItem.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import android.content.Context
import android.view.View
import com.google.android.material.shape.CornerFamily
import com.google.android.material.shape.ShapeAppearanceModel
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
import com.mikepenz.materialdrawer.util.themeDrawerItem
/**
* Describes the main [IDrawerItem] bing used as primary item, following the guidelines
*/
open class GmailDrawerItem : PrimaryDrawerItem() {
override val type: Int
get() = R.id.material_drawer_item_gmail_item
override fun applyDrawerItemTheme(ctx: Context, view: View, selected_color: Int, animate: Boolean, shapeAppearanceModel: ShapeAppearanceModel) {
themeDrawerItem(ctx, view, selected_color, animate, shapeAppearanceModel, R.dimen.gmail_material_drawer_item_background_padding_top_bottom, R.dimen.gmail_material_drawer_item_background_padding_start, R.dimen.gmail_material_drawer_item_background_padding_end, isSelected = isSelected)
}
override fun getShapeAppearanceModel(ctx: Context): ShapeAppearanceModel {
val cornerRadius = ctx.resources.getDimensionPixelSize(R.dimen.gmail_material_drawer_item_corner_radius)
return ShapeAppearanceModel.builder()
.setTopRightCorner(CornerFamily.ROUNDED, cornerRadius.toFloat())
.setBottomRightCorner(CornerFamily.ROUNDED, cornerRadius.toFloat())
.build()
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/IconDrawerItem.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import android.content.Context
import android.content.res.ColorStateList
import android.view.View
import android.widget.ImageView
import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.RecyclerView
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.holder.ImageHolder
import com.mikepenz.materialdrawer.model.AbstractDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.Iconable
import com.mikepenz.materialdrawer.model.interfaces.SelectIconable
import com.mikepenz.materialdrawer.util.createDrawerItemColorStateList
/**
* Created by mikepenz on 03.02.15.
*/
class IconDrawerItem : AbstractDrawerItem<IconDrawerItem, IconDrawerItem.ViewHolder>(), Iconable, SelectIconable {
override var icon: ImageHolder? = null
override var iconColor: ColorStateList? = null
override var selectedIcon: ImageHolder? = null
override var isIconTinted = false
override val type: Int
get() = R.id.material_drawer_item_icon_only
override val layoutRes: Int
@LayoutRes
get() = R.layout.material_drawer_item_icon_only
override fun bindView(holder: ViewHolder, payloads: List<Any>) {
super.bindView(holder, payloads)
val ctx = holder.itemView.context
//set the identifier from the drawerItem here. It can be used to run tests
holder.itemView.id = hashCode()
//get the correct color for the icon
val iconColor = this.iconColor ?: ctx.getPrimaryDrawerIconColor()
//get the drawables for our icon and set it)
val icon = ImageHolder.decideIcon(icon, ctx, iconColor, isIconTinted, 1)
val selectedIcon = ImageHolder.decideIcon(selectedIcon, ctx, iconColor, isIconTinted, 1)
ImageHolder.applyMultiIconTo(icon, selectedIcon, iconColor, isIconTinted, holder.icon)
//call the onPostBindView method to trigger post bind view actions (like the listener to modify the item if required)
onPostBindView(this, holder.itemView)
}
override fun getViewHolder(v: View): ViewHolder {
return ViewHolder(v)
}
class ViewHolder internal constructor(private val view: View) : RecyclerView.ViewHolder(view) {
var icon: ImageView = view.findViewById<ImageView>(R.id.material_drawer_icon)
}
}
internal fun Context.getPrimaryDrawerIconColor(): ColorStateList {
return createDrawerItemColorStateList(this, com.mikepenz.materialdrawer.R.styleable.MaterialDrawerSliderView_materialDrawerPrimaryIcon)!!
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/OverflowMenuDrawerItem.kt
================================================
package com.mikepenz.materialdrawer.app.drawerItems
import android.view.View
import android.widget.ImageButton
import androidx.annotation.LayoutRes
import androidx.appcompat.widget.PopupMenu
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.sizeDp
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.model.BaseDescribeableDrawerItem
import com.mikepenz.materialdrawer.model.BaseViewHolder
/**
* Created by mikepenz on 03.02.15.
*/
class OverflowMenuDrawerItem : BaseDescribeableDrawerItem<OverflowMenuDrawerItem, OverflowMenuDrawerItem.ViewHolder>() {
var menu: Int = 0
var onMenuItemClickListener: PopupMenu.OnMenuItemClickListener? = null
var onDismissListener: PopupMenu.OnDismissListener? = null
override val type: Int
get() = R.id.material_drawer_item_overflow_menu
override val layoutRes: Int
@LayoutRes
get() = R.layout.material_drawer_item_overflow_menu_primary
@Deprecated("Use property setter instead")
fun withMenu(menu: Int): OverflowMenuDrawerItem {
this.menu = menu
return this
}
@Deprecated("Use property setter instead")
fun withOnMenuItemClickListener(onMenuItemClickListener: PopupMenu.OnMenuItemClickListener): OverflowMenuDrawerItem {
this.onMenuItemClickListener = onMenuItemClickListener
return this
}
@Deprecated("Use property setter instead")
fun withOnDismissListener(onDismissListener: PopupMenu.OnDismissListener): OverflowMenuDrawerItem {
this.onDismissListener = onDismissListener
return this
}
override fun bindView(holder: ViewHolder, payloads: List<Any>) {
super.bindView(holder, payloads)
val ctx = holder.itemView.context
//bind the basic view parts
bindViewHelper(holder)
//handle menu click
holder.menu.setOnClickListener { view ->
val popup = PopupMenu(view.context, view)
val inflater = popup.menuInflater
inflater.inflate(menu, popup.menu)
popup.setOnMenuItemClickListener(onMenuItemClickListener)
popup.setOnDismissListener(onDismissListener)
popup.show()
}
//handle image
holder.menu.setImageDrawable(IconicsDrawable(ctx, GoogleMaterial.Icon.gmd_more_vert).apply { sizeDp = 12; colorList = getIconColor(ctx) })
//call the onPostBindView method to trigger post bind view actions (like the listener to modify the item if required)
onPostBindView(this, holder.itemView)
}
override fun getViewHolder(v: View): ViewHolder {
return ViewHolder(v)
}
class ViewHolder(view: View) : BaseViewHolder(view) {
internal val menu: ImageButton = view.findViewById<ImageButton>(R.id.material_drawer_menu_overflow)
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/fragment/DemoFragment.kt
================================================
package com.mikepenz.materialdrawer.app.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.mikepenz.materialdrawer.app.databinding.FragmentSampleBinding
/**
* A simple [Fragment] subclass.
* This is just a demo fragment with a long scrollable view of editTexts. Don't see this as a reference for anything
*/
class DemoFragment : Fragment() {
private var _binding: FragmentSampleBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
// don't look at this layout it's just a listView to show how to handle the keyboard
_binding = FragmentSampleBinding.inflate(inflater, container, false)
binding.title.text = arguments?.getString(KEY_TITLE)
return binding.root
}
companion object {
private val KEY_TITLE = "title"
fun newInstance(title: String): DemoFragment {
return DemoFragment().apply {
arguments = Bundle().apply { putString(KEY_TITLE, title) }
}
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/fragment/DemoMessageFragment.kt
================================================
package com.mikepenz.materialdrawer.app.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.app.databinding.FragmentMessageSampleBinding
class DemoMessageFragment : Fragment() {
private var _binding: FragmentMessageSampleBinding? = null
private val binding get() = _binding!!
private var message: String? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
message = arguments?.let { DemoMessageFragmentArgs.fromBundle(it).message }
_binding = FragmentMessageSampleBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.messageTextView.text = "$message"
binding.btnFragmentHome.setOnClickListener { navigateTo(R.id.fragmentHome) }
binding.btnFragment1.setOnClickListener { navigateTo(R.id.messageFragment1) }
binding.btnFragment2.setOnClickListener { navigateTo(R.id.messageFragment2) }
binding.btnFragment3.setOnClickListener { navigateTo(R.id.messageFragment3) }
binding.btnPopup.setOnClickListener { navigateTo(R.id.action_global_fragmentHome) }
}
private fun navigateTo(destination: Int) {
findNavController().navigate(destination)
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/fragment/DrawerFragment.kt
================================================
package com.mikepenz.materialdrawer.app.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesomeBrand
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.app.databinding.FragmentSimpleSampleBinding
import com.mikepenz.materialdrawer.iconics.withIcon
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.SectionDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.withEnabled
import com.mikepenz.materialdrawer.model.interfaces.withIdentifier
import com.mikepenz.materialdrawer.model.interfaces.withName
/**
* A simple [Fragment] subclass.
* This is just a demo fragment with a long scrollable view of editTexts. Don't see this as a reference for anything
*/
class DrawerFragment : Fragment() {
private var _binding: FragmentSimpleSampleBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
// don't look at this layout it's just a listView to show how to handle the keyboard
_binding = FragmentSimpleSampleBinding.inflate(inflater, container, false)
binding.title.text = arguments?.getString(KEY_TITLE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.slider.apply {
itemAdapter.add(
PrimaryDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home).withIdentifier(1),
PrimaryDrawerItem().withName(R.string.drawer_item_free_play).withIcon(FontAwesome.Icon.faw_gamepad),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye),
SectionDrawerItem().withName(R.string.drawer_item_section_header),
SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog),
SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_question).withEnabled(false),
SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesomeBrand.Icon.fab_github),
SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(FontAwesome.Icon.faw_bullhorn)
)
setSelection(1)
setSavedInstance(savedInstanceState)
}
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
companion object {
private const val KEY_TITLE = "title"
fun newInstance(title: String): DrawerFragment {
return DrawerFragment().apply {
arguments = Bundle().apply { putString(KEY_TITLE, title) }
}
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/fragment/SecondDrawerFragment.kt
================================================
package com.mikepenz.materialdrawer.app.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome
import com.mikepenz.materialdrawer.app.R
import com.mikepenz.materialdrawer.app.databinding.FragmentSimpleSampleBinding
import com.mikepenz.materialdrawer.iconics.withIcon
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.withIdentifier
import com.mikepenz.materialdrawer.model.interfaces.withName
/**
* A simple [Fragment] subclass.
* This is just a demo fragment with a long scrollable view of editTexts. Don't see this as a reference for anything
*/
class SecondDrawerFragment : Fragment() {
private var _binding: FragmentSimpleSampleBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
// don't look at this layout it's just a listView to show how to handle the keyboard
_binding = FragmentSimpleSampleBinding.inflate(inflater, container, false)
binding.title.text = arguments?.getString(KEY_TITLE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.slider.apply {
itemAdapter.add(
PrimaryDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home).withIdentifier(1),
PrimaryDrawerItem().withName(R.string.drawer_item_free_play).withIcon(FontAwesome.Icon.faw_gamepad),
PrimaryDrawerItem().withName(R.string.drawer_item_custom).withIcon(FontAwesome.Icon.faw_eye)
)
setSavedInstance(savedInstanceState)
setSelection(1)
}
}
override fun onSaveInstanceState(_outState: Bundle) {
var outState = _outState
//add the values which need to be saved from the drawer to the bundle
outState = binding.slider.saveInstanceState(outState)
super.onSaveInstanceState(outState)
}
companion object {
private val KEY_TITLE = "title"
fun newInstance(title: String): SecondDrawerFragment {
return SecondDrawerFragment().apply {
arguments = Bundle().apply { putString(KEY_TITLE, title) }
}
}
}
}
================================================
FILE: app/src/main/java/com/mikepenz/materialdrawer/app/utils/CrossfadeWrapper.kt
================================================
package com.mikepenz.materialdrawer.app.utils
import com.mikepenz.crossfader.Crossfader
import com.mikepenz.materialdrawer.interfaces.ICrossfader
/**
* Created by mikepenz on 18.07.15.
*/
class CrossfadeWrapper(private val crossfader: Crossfader<*>) : ICrossfader {
override val isCrossfaded: Boolean
get() = crossfader.isCrossFaded()
override fun crossfade(
gitextract_to5pn2i8/ ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE.md │ ├── ci-gradle.properties │ ├── config/ │ │ └── configuration.json │ ├── dependabot.yml │ └── workflows/ │ ├── ci.yml │ └── gradle-dependency-submission.yml ├── .gitignore ├── Dangerfile ├── FAQ/ │ ├── accountheader_single_profile_without_dropdown.md │ ├── howto_modify_add_custom_draweritems.md │ ├── howto_use_different_sub_library_version.md │ ├── opening-drawer-from-espresso.md │ └── when_to_use_this_library.md ├── FAQ.md ├── Gemfile ├── LICENSE ├── MIGRATION.md ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle.kts │ ├── gradle.properties │ ├── proguard-rules.pro │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ └── com/ │ │ └── mikepenz/ │ │ └── materialdrawer/ │ │ └── app/ │ │ ├── ActionBarActivity.kt │ │ ├── AdvancedActivity.kt │ │ ├── CollapsingToolbarActivity.kt │ │ ├── CompactHeaderDrawerActivity.kt │ │ ├── CrossfadeDrawerLayoutActvitiy.kt │ │ ├── CustomApplication.kt │ │ ├── DrawerActivity.kt │ │ ├── EmbeddedDrawerActivity.kt │ │ ├── FragmentActivity.kt │ │ ├── FullscreenDrawerActivity.kt │ │ ├── MenuDrawerActivity.kt │ │ ├── MiniDrawerActivity.kt │ │ ├── MultiDrawerActivity.kt │ │ ├── NavControllerActivity.kt │ │ ├── PersistentDrawerActivity.kt │ │ ├── drawerItems/ │ │ │ ├── AccountDividerDrawerItem.kt │ │ │ ├── CustomBaseViewHolder.kt │ │ │ ├── CustomCenteredPrimaryDrawerItem.kt │ │ │ ├── CustomPrimaryDrawerItem.kt │ │ │ ├── CustomUrlBasePrimaryDrawerItem.kt │ │ │ ├── CustomUrlPrimaryDrawerItem.kt │ │ │ ├── GmailDrawerItem.kt │ │ │ ├── IconDrawerItem.kt │ │ │ └── OverflowMenuDrawerItem.kt │ │ ├── fragment/ │ │ │ ├── DemoFragment.kt │ │ │ ├── DemoMessageFragment.kt │ │ │ ├── DrawerFragment.kt │ │ │ └── SecondDrawerFragment.kt │ │ ├── utils/ │ │ │ ├── CrossfadeWrapper.kt │ │ │ ├── SystemUtils.kt │ │ │ └── UIUtils.kt │ │ └── widget/ │ │ └── CrossfadeDrawerLayout.kt │ └── res/ │ ├── layout/ │ │ ├── activity_embedded.xml │ │ ├── activity_mini_drawer.xml │ │ ├── activity_multi_sample.xml │ │ ├── activity_persistent_drawer.xml │ │ ├── activity_sample.xml │ │ ├── activity_sample_actionbar.xml │ │ ├── activity_sample_collapsing_toolbar.xml │ │ ├── activity_sample_crossfader.xml │ │ ├── activity_sample_fragment.xml │ │ ├── activity_sample_fullscreen.xml │ │ ├── activity_sample_nav.xml │ │ ├── footer.xml │ │ ├── fragment_message_sample.xml │ │ ├── fragment_sample.xml │ │ ├── fragment_simple_sample.xml │ │ ├── header.xml │ │ ├── material_drawer_compact_persistent_header.xml │ │ ├── material_drawer_item_icon_only.xml │ │ ├── material_drawer_item_overflow_menu_primary.xml │ │ └── material_drawer_item_primary_centered.xml │ ├── menu/ │ │ ├── cab.xml │ │ ├── embedded.xml │ │ ├── example_menu.xml │ │ ├── fragment_menu.xml │ │ └── main.xml │ ├── mipmap-anydpi-v26/ │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ ├── navigation/ │ │ └── navigation.xml │ └── values/ │ ├── colors.xml │ ├── dimens.xml │ ├── ic_launcher_background.xml │ ├── ids.xml │ ├── strings.xml │ ├── styles.xml │ └── themes.xml ├── build.gradle.kts ├── gradle/ │ ├── libs.versions.toml │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── materialdrawer/ │ ├── .gitignore │ ├── build.gradle.kts │ ├── gradle.properties │ ├── proguard-rules.txt │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ └── com/ │ │ └── mikepenz/ │ │ └── materialdrawer/ │ │ ├── holder/ │ │ │ ├── BadgeStyle.kt │ │ │ ├── ColorHolder.kt │ │ │ ├── DimenHolder.kt │ │ │ ├── ImageHolder.kt │ │ │ └── StringHolder.kt │ │ ├── interfaces/ │ │ │ ├── ICrossfader.kt │ │ │ ├── OnCheckedChangeListener.kt │ │ │ └── OnPostBindViewListener.kt │ │ ├── model/ │ │ │ ├── AbstractBadgeableDrawerItem.kt │ │ │ ├── AbstractDrawerItem.kt │ │ │ ├── AbstractSwitchableDrawerItem.kt │ │ │ ├── AbstractToggleableDrawerItem.kt │ │ │ ├── BaseDescribeableDrawerItem.kt │ │ │ ├── BaseDrawerItem.kt │ │ │ ├── BaseViewHolder.kt │ │ │ ├── ContainerDrawerItem.kt │ │ │ ├── DividerDrawerItem.kt │ │ │ ├── ExpandableBadgeDrawerItem.kt │ │ │ ├── ExpandableDrawerItem.kt │ │ │ ├── MiniDrawerItem.kt │ │ │ ├── MiniProfileDrawerItem.kt │ │ │ ├── PrimaryDrawerItem.kt │ │ │ ├── ProfileDrawerItem.kt │ │ │ ├── ProfileSettingDrawerItem.kt │ │ │ ├── SecondaryDrawerItem.kt │ │ │ ├── SecondarySwitchDrawerItem.kt │ │ │ ├── SecondaryToggleDrawerItem.kt │ │ │ ├── SectionDrawerItem.kt │ │ │ ├── SwitchDrawerItem.kt │ │ │ ├── ToggleDrawerItem.kt │ │ │ ├── interfaces/ │ │ │ │ ├── Badgeable.kt │ │ │ │ ├── Checkable.kt │ │ │ │ ├── ColorfulBadgeable.kt │ │ │ │ ├── Describable.kt │ │ │ │ ├── DescribableColor.kt │ │ │ │ ├── IDrawerItem.kt │ │ │ │ ├── IProfile.kt │ │ │ │ ├── Iconable.kt │ │ │ │ ├── Nameable.kt │ │ │ │ ├── NameableColor.kt │ │ │ │ ├── SelectIconable.kt │ │ │ │ ├── Selectable.kt │ │ │ │ ├── SelectableColor.kt │ │ │ │ ├── Tagable.kt │ │ │ │ └── Typefaceable.kt │ │ │ └── utils/ │ │ │ ├── BadgeDrawableBuilder.kt │ │ │ └── DrawerItemExtensions.kt │ │ ├── util/ │ │ │ ├── AbstractDrawerImageLoader.kt │ │ │ ├── DrawerImageLoader.kt │ │ │ ├── DrawerItemViewHelper.kt │ │ │ ├── DrawerUtils.kt │ │ │ ├── Extensions.kt │ │ │ ├── FixStateListDrawable.kt │ │ │ ├── MaterialDrawerSliderViewExtensions.kt │ │ │ ├── MenuDrawerUtils.kt │ │ │ └── Utils.kt │ │ ├── view/ │ │ │ └── BezelImageView.kt │ │ └── widget/ │ │ ├── AccountHeaderView.kt │ │ ├── MaterialDrawerSliderView.kt │ │ └── MiniDrawerSliderView.kt │ └── res/ │ ├── color/ │ │ └── color_drawer_item_text.xml │ ├── drawable/ │ │ ├── material_drawer_badge.xml │ │ ├── material_drawer_circle_mask.xml │ │ ├── material_drawer_ico_account_layer.xml │ │ ├── material_drawer_ico_chevron_down.xml │ │ ├── material_drawer_ico_menu_down.xml │ │ ├── material_drawer_rectangle_mask.xml │ │ ├── material_drawer_shadow_bottom.xml │ │ └── material_drawer_shadow_top.xml │ ├── drawable-v21/ │ │ └── material_drawer_ico_account.xml │ ├── layout/ │ │ ├── material_drawer.xml │ │ ├── material_drawer_compact_header.xml │ │ ├── material_drawer_fits_not.xml │ │ ├── material_drawer_header.xml │ │ ├── material_drawer_inner_shadow.xml │ │ ├── material_drawer_item_container.xml │ │ ├── material_drawer_item_divider.xml │ │ ├── material_drawer_item_expandable.xml │ │ ├── material_drawer_item_expandable_badge.xml │ │ ├── material_drawer_item_mini.xml │ │ ├── material_drawer_item_mini_profile.xml │ │ ├── material_drawer_item_primary.xml │ │ ├── material_drawer_item_profile.xml │ │ ├── material_drawer_item_profile_setting.xml │ │ ├── material_drawer_item_secondary.xml │ │ ├── material_drawer_item_secondary_switch.xml │ │ ├── material_drawer_item_secondary_toggle.xml │ │ ├── material_drawer_item_section.xml │ │ ├── material_drawer_item_switch.xml │ │ ├── material_drawer_item_toggle.xml │ │ └── material_drawer_recycler_view.xml │ ├── values/ │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── values-fr/ │ │ └── strings.xml │ ├── values-pt/ │ │ └── strings.xml │ └── values-sw600dp/ │ └── dimens.xml ├── materialdrawer-iconics/ │ ├── .gitignore │ ├── build.gradle.kts │ ├── gradle.properties │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ └── java/ │ └── com/ │ └── mikepenz/ │ └── materialdrawer/ │ └── iconics/ │ ├── IconicsExtension.kt │ └── IconicsImageHolder.kt ├── materialdrawer-nav/ │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ ├── gradle.properties │ ├── proguard-rules.pro │ ├── proguard-rules.txt │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ └── java/ │ └── com/ │ └── mikepenz/ │ └── materialdrawer/ │ ├── model/ │ │ └── NavigationDrawerItem.kt │ └── util/ │ └── DrawerNavigationUI.kt └── settings.gradle.kts
Condensed preview — 219 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (697K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 66,
"preview": "# These are supported funding model platforms\n\ngithub: [mikepenz]\n"
},
{
"path": ".github/ISSUE_TEMPLATE.md",
"chars": 893,
"preview": "## About this issue\n\n- Briefly describe the issue\n- How can the issue be reproduced / sample code\n\n## Details\n- [ ] Used"
},
{
"path": ".github/ci-gradle.properties",
"chars": 198,
"preview": "org.gradle.daemon=true\norg.gradle.parallel=true\norg.gradle.workers.max=2\norg.gradle.jvmargs=-Xmx6G\norg.gradle.caching=tr"
},
{
"path": ".github/config/configuration.json",
"chars": 386,
"preview": "{\n \"categories\": [\n {\n \"title\": \"## 🚀 Features\",\n \"labels\": [\n \"feature\"\n ]\n },\n {\n "
},
{
"path": ".github/dependabot.yml",
"chars": 117,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n interval: \"weekly\""
},
{
"path": ".github/workflows/ci.yml",
"chars": 4359,
"preview": "# Thanks to https://github.com/coil-kt/coil/blob/master/.github/workflows/ci.yml\nname: CI\n\non:\n push:\n tags:\n -"
},
{
"path": ".github/workflows/gradle-dependency-submission.yml",
"chars": 1212,
"preview": "name: Gradle Dependency Submission\non:\n push:\n branches:\n - develop\n\njobs:\n gradle-dependency-detection:\n r"
},
{
"path": ".gitignore",
"chars": 359,
"preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbi"
},
{
"path": "Dangerfile",
"chars": 1826,
"preview": "github.dismiss_out_of_range_messages\n\n# Make it more obvious that a PR is a work in progress and shouldn't be merged yet"
},
{
"path": "FAQ/accountheader_single_profile_without_dropdown.md",
"chars": 618,
"preview": "# How can i use the AccountHeader with just one profile and disable the dropdown?\n\nThis can be simply achieved by adding"
},
{
"path": "FAQ/howto_modify_add_custom_draweritems.md",
"chars": 547,
"preview": "# How do I change existing or add my own CustomDrawerItems to the MaterialDrawer?\n\nPlease head over here on how to imple"
},
{
"path": "FAQ/howto_use_different_sub_library_version.md",
"chars": 938,
"preview": "# How do I use different versions of the sub dependencies like the support libraries?\n\nThis can be really easy achieved "
},
{
"path": "FAQ/opening-drawer-from-espresso.md",
"chars": 489,
"preview": "### Q: How to open the drawer from an instrumental test written with Espresso?\n### A: \n\nFirst, you need a add `espresso-"
},
{
"path": "FAQ/when_to_use_this_library.md",
"chars": 1144,
"preview": "### Developer:\nSince there is MaterialDrawer in Support Library, could you give a couple of points why to use your libra"
},
{
"path": "FAQ.md",
"chars": 1820,
"preview": "# FAQ / WIKI\n\nThis is the official **MaterialDrawer** FAQ/Wiki. People can contribute to it through pull requests.\nEach "
},
{
"path": "Gemfile",
"chars": 197,
"preview": "# frozen_string_literal: true\n\nsource \"https://rubygems.org\"\n\ngit_source(:github) {|repo_name| \"https://github.com/#{rep"
},
{
"path": "LICENSE",
"chars": 11339,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "MIGRATION.md",
"chars": 12580,
"preview": "### Upgrade Notes\n\n#### v8.0.0\n\n- Ground up refactor of the way the `MaterialDrawer` is used and integrated into the app"
},
{
"path": "README.md",
"chars": 16549,
"preview": "# MaterialDrawer\n\n... the flexible, easy to use, all in one drawer library for your Android project.\n\n-------\n\n<p align="
},
{
"path": "app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "app/build.gradle.kts",
"chars": 3210,
"preview": "plugins {\n id(\"com.mikepenz.convention.android-application\")\n id(\"com.mikepenz.convention.kotlin\")\n id(\"com.mik"
},
{
"path": "app/gradle.properties",
"chars": 34,
"preview": "com.mikepenz.compose.enabled=false"
},
{
"path": "app/proguard-rules.pro",
"chars": 655,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /E"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 2862,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xm"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/ActionBarActivity.kt",
"chars": 2871,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.os.Bundle\nimport android.view.MenuItem\nimport android.widget.Toa"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/AdvancedActivity.kt",
"chars": 11770,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.content.res.Configuration\nimport android.os.Bundle\nimport androi"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/CollapsingToolbarActivity.kt",
"chars": 4639,
"preview": "package com.mikepenz.materialdrawer.app\r\n\r\nimport android.graphics.Color\r\nimport android.os.Bundle\r\nimport androidx.appc"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/CompactHeaderDrawerActivity.kt",
"chars": 8753,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.content.Context\nimport android.content.res.Configuration\nimport "
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/CrossfadeDrawerLayoutActvitiy.kt",
"chars": 7206,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.content.res.Configuration\nimport android.os.Bundle\nimport androi"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/CustomApplication.kt",
"chars": 2820,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.content.Context\nimport android.graphics.drawable.Drawable\nimport"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/DrawerActivity.kt",
"chars": 17696,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.content.Intent\nimport android.content.res.Configuration\nimport a"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/EmbeddedDrawerActivity.kt",
"chars": 8193,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.graphics.Color\nimport android.net.Uri\nimport android.os.Bundle\ni"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/FragmentActivity.kt",
"chars": 2164,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\n"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/FullscreenDrawerActivity.kt",
"chars": 5770,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.content.res.Configuration\nimport android.graphics.Color\nimport a"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/MenuDrawerActivity.kt",
"chars": 3104,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.content.res.Configuration\nimport android.os.Bundle\nimport androi"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/MiniDrawerActivity.kt",
"chars": 11471,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.content.res.Configuration\nimport android.graphics.Color\nimport a"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/MultiDrawerActivity.kt",
"chars": 6208,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.os.Bundle\nimport android.view.MenuItem\nimport android.widget.Toa"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/NavControllerActivity.kt",
"chars": 2196,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\nimport"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/PersistentDrawerActivity.kt",
"chars": 8522,
"preview": "package com.mikepenz.materialdrawer.app\n\nimport android.graphics.Color\nimport android.graphics.drawable.ColorDrawable\nim"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/AccountDividerDrawerItem.kt",
"chars": 2271,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport android.content.res.ColorStateList\nimport android.view.View\n"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomBaseViewHolder.kt",
"chars": 571,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport android.view.View\nimport android.widget.ImageView\nimport and"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomCenteredPrimaryDrawerItem.kt",
"chars": 401,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport com.mikepenz.materialdrawer.app.R\nimport com.mikepenz.materi"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomPrimaryDrawerItem.kt",
"chars": 844,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport com.mikepenz.materialdrawer.holder.ColorHolder\nimport com.mi"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomUrlBasePrimaryDrawerItem.kt",
"chars": 3240,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport android.net.Uri\nimport androidx.annotation.StringRes\nimport "
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomUrlPrimaryDrawerItem.kt",
"chars": 2050,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport android.view.View\nimport android.widget.TextView\nimport andr"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/GmailDrawerItem.kt",
"chars": 1560,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport android.content.Context\nimport android.view.View\nimport com."
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/IconDrawerItem.kt",
"chars": 2554,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport android.content.Context\nimport android.content.res.ColorStat"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/OverflowMenuDrawerItem.kt",
"chars": 2915,
"preview": "package com.mikepenz.materialdrawer.app.drawerItems\n\nimport android.view.View\nimport android.widget.ImageButton\nimport a"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/fragment/DemoFragment.kt",
"chars": 1269,
"preview": "package com.mikepenz.materialdrawer.app.fragment\n\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport an"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/fragment/DemoMessageFragment.kt",
"chars": 1613,
"preview": "package com.mikepenz.materialdrawer.app.fragment\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport and"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/fragment/DrawerFragment.kt",
"chars": 3414,
"preview": "package com.mikepenz.materialdrawer.app.fragment\n\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport an"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/fragment/SecondDrawerFragment.kt",
"chars": 2604,
"preview": "package com.mikepenz.materialdrawer.app.fragment\n\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport an"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/utils/CrossfadeWrapper.kt",
"chars": 423,
"preview": "package com.mikepenz.materialdrawer.app.utils\n\nimport com.mikepenz.crossfader.Crossfader\nimport com.mikepenz.materialdra"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/utils/SystemUtils.kt",
"chars": 211,
"preview": "package com.mikepenz.materialdrawer.app.utils\r\n\r\nimport android.content.res.Resources\r\n\r\nobject SystemUtils {\r\n val s"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/utils/UIUtils.kt",
"chars": 728,
"preview": "package com.mikepenz.materialdrawer.app.utils\n\nimport android.content.Context\nimport android.content.res.Resources\nimpor"
},
{
"path": "app/src/main/java/com/mikepenz/materialdrawer/app/widget/CrossfadeDrawerLayout.kt",
"chars": 10256,
"preview": "package com.mikepenz.materialdrawer.app.widget\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport a"
},
{
"path": "app/src/main/res/layout/activity_embedded.xml",
"chars": 1406,
"preview": "<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "app/src/main/res/layout/activity_mini_drawer.xml",
"chars": 1014,
"preview": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:layout_width=\"match_parent\"\n a"
},
{
"path": "app/src/main/res/layout/activity_multi_sample.xml",
"chars": 2387,
"preview": "<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"htt"
},
{
"path": "app/src/main/res/layout/activity_persistent_drawer.xml",
"chars": 1295,
"preview": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk"
},
{
"path": "app/src/main/res/layout/activity_sample.xml",
"chars": 1942,
"preview": "<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"htt"
},
{
"path": "app/src/main/res/layout/activity_sample_actionbar.xml",
"chars": 1002,
"preview": "<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:id=\"@+"
},
{
"path": "app/src/main/res/layout/activity_sample_collapsing_toolbar.xml",
"chars": 8879,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\r\n ~ Copyright (C) 2015 The Android Open Source Project\r\n ~\r\n ~ Licensed un"
},
{
"path": "app/src/main/res/layout/activity_sample_crossfader.xml",
"chars": 2915,
"preview": "<com.mikepenz.materialdrawer.app.widget.CrossfadeDrawerLayout xmlns:android=\"http://schemas.android.com/apk/res/android\""
},
{
"path": "app/src/main/res/layout/activity_sample_fragment.xml",
"chars": 695,
"preview": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:layout_width=\"match_parent\"\n a"
},
{
"path": "app/src/main/res/layout/activity_sample_fullscreen.xml",
"chars": 2093,
"preview": "<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"htt"
},
{
"path": "app/src/main/res/layout/activity_sample_nav.xml",
"chars": 1840,
"preview": "<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"htt"
},
{
"path": "app/src/main/res/layout/footer.xml",
"chars": 342,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ImageView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android"
},
{
"path": "app/src/main/res/layout/fragment_message_sample.xml",
"chars": 3755,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "app/src/main/res/layout/fragment_sample.xml",
"chars": 3446,
"preview": "<ScrollView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:layout_width=\"match_parent\"\n andro"
},
{
"path": "app/src/main/res/layout/fragment_simple_sample.xml",
"chars": 1344,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android."
},
{
"path": "app/src/main/res/layout/header.xml",
"chars": 342,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ImageView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android"
},
{
"path": "app/src/main/res/layout/material_drawer_compact_persistent_header.xml",
"chars": 7031,
"preview": "<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/res-auto"
},
{
"path": "app/src/main/res/layout/material_drawer_item_icon_only.xml",
"chars": 1015,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "app/src/main/res/layout/material_drawer_item_overflow_menu_primary.xml",
"chars": 2984,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "app/src/main/res/layout/material_drawer_item_primary_centered.xml",
"chars": 3237,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "app/src/main/res/menu/cab.xml",
"chars": 396,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "app/src/main/res/menu/embedded.xml",
"chars": 289,
"preview": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/res-auto\""
},
{
"path": "app/src/main/res/menu/example_menu.xml",
"chars": 1927,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "app/src/main/res/menu/fragment_menu.xml",
"chars": 431,
"preview": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/res-auto\""
},
{
"path": "app/src/main/res/menu/main.xml",
"chars": 590,
"preview": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/res-auto\""
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
"chars": 267,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
"chars": 267,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "app/src/main/res/navigation/navigation.xml",
"chars": 2602,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<navigation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "app/src/main/res/values/colors.xml",
"chars": 680,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!--\n Just set custom primary and accent color.\n Looks best"
},
{
"path": "app/src/main/res/values/dimens.xml",
"chars": 579,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <dimen name=\"material_drawer_padding_half\">4dp</dimen>\n <dimen"
},
{
"path": "app/src/main/res/values/ic_launcher_background.xml",
"chars": 120,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"ic_launcher_background\">#3F51B5</color>\n</resources>"
},
{
"path": "app/src/main/res/values/ids.xml",
"chars": 645,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<resources>\n <item name=\"material_drawer_item_gmail_item\" type=\"id\" />\n <i"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 3927,
"preview": "<resources>\n <string name=\"app_name\">MaterialDrawer</string>\n\n <!-- Sample menu -->\n <string name=\"action_setti"
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 1717,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <style name=\"Widget.MaterialDrawerStyleCustom\" parent=\"Widget.Ma"
},
{
"path": "app/src/main/res/values/themes.xml",
"chars": 1467,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <!-- LIGHT -->\n <style name=\"SampleApp.DayNight\" parent=\"Them"
},
{
"path": "build.gradle.kts",
"chars": 417,
"preview": "plugins {\n alias(baseLibs.plugins.conventionPlugin)\n\n alias(baseLibs.plugins.kotlinAndroid) apply false\n alias("
},
{
"path": "gradle/libs.versions.toml",
"chars": 1805,
"preview": "[versions]\n# androidx\nappcompat = \"1.7.0\"\ncardview = \"1.0.0\"\nconstraintLayout = \"2.2.0\"\ncore = \"1.15.0\"\ndrawerlayout = \""
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 251,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "gradle.properties",
"chars": 1044,
"preview": "# Maven stuff\nGROUP=com.mikepenz\nVERSION_NAME=10.0.0-b01\nVERSION_CODE=10000\n\nPOM_URL=https://github.com/mikepenz/Materia"
},
{
"path": "gradlew",
"chars": 8740,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "gradlew.bat",
"chars": 2966,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "materialdrawer/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "materialdrawer/build.gradle.kts",
"chars": 822,
"preview": "plugins {\n id(\"com.mikepenz.convention.android-library\")\n id(\"com.mikepenz.convention.kotlin\")\n id(\"com.mikepen"
},
{
"path": "materialdrawer/gradle.properties",
"chars": 175,
"preview": "POM_NAME=MaterialDrawer Library\nPOM_DESCRIPTION=The flexible, easy to use, all in one drawer library for your Android pr"
},
{
"path": "materialdrawer/proguard-rules.txt",
"chars": 662,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /E"
},
{
"path": "materialdrawer/src/main/AndroidManifest.xml",
"chars": 51,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest/>\n"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/holder/BadgeStyle.kt",
"chars": 4166,
"preview": "package com.mikepenz.materialdrawer.holder\n\nimport android.content.res.ColorStateList\nimport android.graphics.drawable.D"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/holder/ColorHolder.kt",
"chars": 5795,
"preview": "package com.mikepenz.materialdrawer.holder\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimp"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/holder/DimenHolder.kt",
"chars": 2304,
"preview": "package com.mikepenz.materialdrawer.holder\n\nimport android.content.Context\nimport android.content.res.Resources\nimport a"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/holder/ImageHolder.kt",
"chars": 7397,
"preview": "package com.mikepenz.materialdrawer.holder\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimp"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/holder/StringHolder.kt",
"chars": 2513,
"preview": "package com.mikepenz.materialdrawer.holder\n\nimport android.content.Context\nimport android.view.View\nimport android.widge"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/interfaces/ICrossfader.kt",
"chars": 362,
"preview": "package com.mikepenz.materialdrawer.interfaces\n\n/**\n * Helper interface to allow providing crossfade functionality with "
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/interfaces/OnCheckedChangeListener.kt",
"chars": 493,
"preview": "package com.mikepenz.materialdrawer.interfaces\n\nimport android.widget.CompoundButton\n\nimport com.mikepenz.materialdrawer"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/interfaces/OnPostBindViewListener.kt",
"chars": 392,
"preview": "package com.mikepenz.materialdrawer.interfaces\n\nimport android.view.View\nimport com.mikepenz.materialdrawer.model.interf"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/AbstractBadgeableDrawerItem.kt",
"chars": 2158,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.view.View\nimport android.widget.TextView\nimport androidx.annot"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/AbstractDrawerItem.kt",
"chars": 10621,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimpo"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/AbstractSwitchableDrawerItem.kt",
"chars": 3327,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.view.View\nimport android.widget.CompoundButton\nimport androidx"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/AbstractToggleableDrawerItem.kt",
"chars": 3288,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.view.View\nimport android.widget.CompoundButton\nimport android."
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/BaseDescribeableDrawerItem.kt",
"chars": 5201,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimpo"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/BaseDrawerItem.kt",
"chars": 1399,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimpo"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/BaseViewHolder.kt",
"chars": 617,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.view.View\nimport android.widget.ImageView\nimport android.widge"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/ContainerDrawerItem.kt",
"chars": 4398,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget."
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/DividerDrawerItem.kt",
"chars": 1739,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.view.View\nimport androidx.annotation.LayoutRes\nimport androidx"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/ExpandableBadgeDrawerItem.kt",
"chars": 5116,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.res.ColorStateList\nimport android.os.Build\nimport andr"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/ExpandableDrawerItem.kt",
"chars": 5022,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.res.ColorStateList\nimport android.os.Build\nimport andr"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/MiniDrawerItem.kt",
"chars": 7247,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.view.View\nimport android.widget.ImageView\nimport android.widge"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/MiniProfileDrawerItem.kt",
"chars": 3773,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.res.ColorStateList\nimport android.view.View\nimport and"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/PrimaryDrawerItem.kt",
"chars": 284,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport com.mikepenz.materialdrawer.model.interfaces.IDrawerItem\n\n/**\n * Descr"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/ProfileDrawerItem.kt",
"chars": 6055,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.res.ColorStateList\nimport android.view.View\nimport and"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/ProfileSettingDrawerItem.kt",
"chars": 5164,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.res.ColorStateList\nimport android.view.View\nimport and"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/SecondaryDrawerItem.kt",
"chars": 1015,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimpo"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/SecondarySwitchDrawerItem.kt",
"chars": 1011,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimpo"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/SecondaryToggleDrawerItem.kt",
"chars": 1011,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimpo"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/SectionDrawerItem.kt",
"chars": 3168,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport android.content.res.ColorStateList\nimport android.view.View\nimport and"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/SwitchDrawerItem.kt",
"chars": 277,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport com.mikepenz.materialdrawer.model.interfaces.IDrawerItem\n\n/**\n * Descr"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/ToggleDrawerItem.kt",
"chars": 277,
"preview": "package com.mikepenz.materialdrawer.model\n\nimport com.mikepenz.materialdrawer.model.interfaces.IDrawerItem\n\n/**\n * Descr"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/Badgeable.kt",
"chars": 1367,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport com.mikepenz.materialdrawer.holder.StringHolder\n\n/**\n * Def"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/Checkable.kt",
"chars": 553,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\n/**\n * Defines a [IDrawerItem] with support for being selected\n */"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/ColorfulBadgeable.kt",
"chars": 512,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport com.mikepenz.materialdrawer.holder.BadgeStyle\n\n/**\n * Defin"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/Describable.kt",
"chars": 1335,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport androidx.annotation.StringRes\nimport com.mikepenz.materiald"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/DescribableColor.kt",
"chars": 1323,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport android.content.res.ColorStateList\nimport androidx.annotati"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/IDrawerItem.kt",
"chars": 1630,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport android.content.Context\nimport android.view.View\nimport and"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/IProfile.kt",
"chars": 860,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport androidx.annotation.StringRes\nimport com.mikepenz.fastadapt"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/Iconable.kt",
"chars": 2895,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport android.content.res.ColorStateList\nimport android.graphics."
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/Nameable.kt",
"chars": 1372,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport androidx.annotation.StringRes\nimport com.mikepenz.materiald"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/NameableColor.kt",
"chars": 1252,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport android.content.res.ColorStateList\nimport androidx.annotati"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/SelectIconable.kt",
"chars": 2662,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Dr"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/Selectable.kt",
"chars": 405,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\n/**\n * Defines a [IDrawerItem] with support for being selected\n */"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/SelectableColor.kt",
"chars": 1540,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport androidx.annotation.ColorInt\nimport androidx.annotation.Col"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/Tagable.kt",
"chars": 392,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\n/**\n * Defines a [IDrawerItem] with support for being tagged\n */\ni"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/interfaces/Typefaceable.kt",
"chars": 444,
"preview": "package com.mikepenz.materialdrawer.model.interfaces\n\nimport android.graphics.Typeface\n\n/**\n * Defines a [IDrawerItem] w"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/utils/BadgeDrawableBuilder.kt",
"chars": 1529,
"preview": "package com.mikepenz.materialdrawer.model.utils\n\nimport android.content.Context\nimport android.graphics.drawable.Gradien"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/model/utils/DrawerItemExtensions.kt",
"chars": 666,
"preview": "package com.mikepenz.materialdrawer.model.utils\n\nimport com.mikepenz.materialdrawer.model.interfaces.IDrawerItem\n\n/** De"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/AbstractDrawerImageLoader.kt",
"chars": 1504,
"preview": "package com.mikepenz.materialdrawer.util\n\nimport android.content.Context\nimport android.graphics.drawable.Drawable\nimpor"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/DrawerImageLoader.kt",
"chars": 2902,
"preview": "package com.mikepenz.materialdrawer.util\n\nimport android.content.Context\nimport android.graphics.drawable.Drawable\nimpor"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/DrawerItemViewHelper.kt",
"chars": 1997,
"preview": "package com.mikepenz.materialdrawer.util\n\nimport android.content.Context\nimport android.view.View\nimport android.view.Vi"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/DrawerUtils.kt",
"chars": 19539,
"preview": "@file:JvmName(\"DrawerUtils\")\n\npackage com.mikepenz.materialdrawer.util\n\nimport android.annotation.SuppressLint\nimport an"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/Extensions.kt",
"chars": 3696,
"preview": "package com.mikepenz.materialdrawer.util\n\nimport android.os.Build\nimport android.view.View\nimport android.widget.LinearL"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/FixStateListDrawable.kt",
"chars": 1607,
"preview": "package com.mikepenz.materialdrawer.util\n\nimport android.R\nimport android.annotation.SuppressLint\nimport android.content"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/MaterialDrawerSliderViewExtensions.kt",
"chars": 7312,
"preview": "package com.mikepenz.materialdrawer.util\n\nimport com.mikepenz.materialdrawer.holder.ImageHolder\nimport com.mikepenz.mate"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/MenuDrawerUtils.kt",
"chars": 2728,
"preview": "package com.mikepenz.materialdrawer.util\n\nimport android.annotation.SuppressLint\nimport android.view.Menu\nimport android"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/util/Utils.kt",
"chars": 7803,
"preview": "package com.mikepenz.materialdrawer.util\n\nimport android.content.Context\nimport android.content.res.ColorStateList\nimpor"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/view/BezelImageView.kt",
"chars": 9984,
"preview": "/*\n * Copyright 2014 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/widget/AccountHeaderView.kt",
"chars": 44964,
"preview": "package com.mikepenz.materialdrawer.widget\n\nimport android.content.Context\nimport android.graphics.Typeface\nimport andro"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/widget/MaterialDrawerSliderView.kt",
"chars": 34400,
"preview": "package com.mikepenz.materialdrawer.widget\n\nimport android.content.Context\nimport android.graphics.Canvas\nimport android"
},
{
"path": "materialdrawer/src/main/java/com/mikepenz/materialdrawer/widget/MiniDrawerSliderView.kt",
"chars": 13810,
"preview": "package com.mikepenz.materialdrawer.widget\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport andro"
},
{
"path": "materialdrawer/src/main/res/color/color_drawer_item_text.xml",
"chars": 258,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item a"
},
{
"path": "materialdrawer/src/main/res/drawable/material_drawer_badge.xml",
"chars": 202,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <corners a"
},
{
"path": "materialdrawer/src/main/res/drawable/material_drawer_circle_mask.xml",
"chars": 747,
"preview": "<!--\n Copyright 2014 Google Inc. All rights reserved.\n \n Licensed under the Apache License, Version 2.0 (the \"License"
},
{
"path": "materialdrawer/src/main/res/drawable/material_drawer_ico_account_layer.xml",
"chars": 384,
"preview": "<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item android:id=\"@+id/background\">\n "
},
{
"path": "materialdrawer/src/main/res/drawable/material_drawer_ico_chevron_down.xml",
"chars": 509,
"preview": "<!-- drawable/chevron_down.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width="
},
{
"path": "materialdrawer/src/main/res/drawable/material_drawer_ico_menu_down.xml",
"chars": 469,
"preview": "<!-- drawable/menu_down.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24"
},
{
"path": "materialdrawer/src/main/res/drawable/material_drawer_rectangle_mask.xml",
"chars": 140,
"preview": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:shape=\"rectangle\">\n <solid android:colo"
},
{
"path": "materialdrawer/src/main/res/drawable/material_drawer_shadow_bottom.xml",
"chars": 242,
"preview": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:shape=\"rectangle\">\n <gradient\n a"
},
{
"path": "materialdrawer/src/main/res/drawable/material_drawer_shadow_top.xml",
"chars": 243,
"preview": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:shape=\"rectangle\">\n <gradient\n a"
},
{
"path": "materialdrawer/src/main/res/drawable-v21/material_drawer_ico_account.xml",
"chars": 421,
"preview": "<!-- drawable/account.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp"
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer.xml",
"chars": 306,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_compact_header.xml",
"chars": 7161,
"preview": "<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/res-auto"
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_fits_not.xml",
"chars": 327,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.drawerlayout.widget.DrawerLayout xmlns:android=\"http://schemas.android."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_header.xml",
"chars": 10967,
"preview": "<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/res-auto"
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_inner_shadow.xml",
"chars": 502,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<View xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:id=\""
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_container.xml",
"chars": 246,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_divider.xml",
"chars": 507,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<View xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:id=\""
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_expandable.xml",
"chars": 4142,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_expandable_badge.xml",
"chars": 5150,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_mini.xml",
"chars": 1660,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns"
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_mini_profile.xml",
"chars": 1203,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_primary.xml",
"chars": 4608,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_profile.xml",
"chars": 5516,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_profile_setting.xml",
"chars": 4596,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_secondary.xml",
"chars": 4375,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_secondary_switch.xml",
"chars": 3984,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_secondary_toggle.xml",
"chars": 3908,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_section.xml",
"chars": 1203,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_switch.xml",
"chars": 3951,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_item_toggle.xml",
"chars": 3951,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "materialdrawer/src/main/res/layout/material_drawer_recycler_view.xml",
"chars": 539,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.recyclerview.widget.RecyclerView xmlns:android=\"http://schemas.android."
},
{
"path": "materialdrawer/src/main/res/values/attrs.xml",
"chars": 1700,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <declare-styleable name=\"MaterialDrawerTheme\">\n <attr name"
},
{
"path": "materialdrawer/src/main/res/values/colors.xml",
"chars": 291,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- MaterialDrawer DEFAULT text / items colors -->\n <color na"
},
{
"path": "materialdrawer/src/main/res/values/dimens.xml",
"chars": 6095,
"preview": "<resources>\n <!-- ********************** -->\n <!-- Material Drawer Dimens -->\n <!-- ********************** -->\n"
},
{
"path": "materialdrawer/src/main/res/values/ids.xml",
"chars": 1421,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<resources>\n <item name=\"material_drawer_item\" type=\"id\" />\n <item name=\"m"
},
{
"path": "materialdrawer/src/main/res/values/strings.xml",
"chars": 259,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <string name=\"material_drawer_open\">Open</string>\n <string nam"
},
{
"path": "materialdrawer/src/main/res/values/styles.xml",
"chars": 1511,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <style name=\"Widget.MaterialDrawerStyle\" parent=\"\">\n <ite"
},
{
"path": "materialdrawer/src/main/res/values-fr/strings.xml",
"chars": 262,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <string name=\"material_drawer_open\">Ouvrir</string>\n <string n"
}
]
// ... and 19 more files (download for full content)
About this extraction
This page contains the full source code of the mikepenz/MaterialDrawer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 219 files (639.4 KB), approximately 151.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.