The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .gitignore
├── LICENSE
├── README.md
├── art
    ├── sample.gif
    └── sample_arsenal.jpg
├── build.gradle
├── gradle.properties
├── gradle
    └── wrapper
    │   ├── gradle-wrapper.jar
    │   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
    ├── .gitignore
    ├── build.gradle
    ├── proguard-rules.pro
    └── src
    │   └── main
    │       ├── AndroidManifest.xml
    │       ├── java
    │           └── com
    │           │   └── yarolegovich
    │           │       └── slidingrootnav
    │           │           ├── SlideGravity.java
    │           │           ├── SlidingRootNav.java
    │           │           ├── SlidingRootNavBuilder.java
    │           │           ├── SlidingRootNavLayout.java
    │           │           ├── callback
    │           │               ├── DragListener.java
    │           │               └── DragStateListener.java
    │           │           ├── transform
    │           │               ├── CompositeTransformation.java
    │           │               ├── ElevationTransformation.java
    │           │               ├── RootTransformation.java
    │           │               ├── ScaleTransformation.java
    │           │               └── YTranslationTransformation.java
    │           │           └── util
    │           │               ├── ActionBarToggleAdapter.java
    │           │               ├── DrawerListenerAdapter.java
    │           │               ├── HiddenMenuClickConsumer.java
    │           │               └── SideNavUtils.java
    │       └── res
    │           └── values
    │               ├── ids.xml
    │               └── strings.xml
├── release-bintray.gradle
├── sample
    ├── .gitignore
    ├── build.gradle
    ├── proguard-rules.pro
    └── src
    │   └── main
    │       ├── AndroidManifest.xml
    │       ├── java
    │           └── com
    │           │   └── yarolegovich
    │           │       └── slidingrootnav
    │           │           └── sample
    │           │               ├── SampleActivity.java
    │           │               ├── fragment
    │           │                   └── CenteredTextFragment.java
    │           │               └── menu
    │           │                   ├── DrawerAdapter.java
    │           │                   ├── DrawerItem.java
    │           │                   ├── SimpleItem.java
    │           │                   └── SpaceItem.java
    │       └── res
    │           ├── drawable-hdpi
    │               ├── ic_account_outline_grey600_24dp.png
    │               ├── ic_cart_outline_grey600_24dp.png
    │               ├── ic_email_outline_grey600_24dp.png
    │               ├── ic_home_outline_grey600_24dp.png
    │               └── ic_logout_grey600_24dp.png
    │           ├── drawable-mdpi
    │               ├── ic_account_outline_grey600_24dp.png
    │               ├── ic_cart_outline_grey600_24dp.png
    │               ├── ic_email_outline_grey600_24dp.png
    │               ├── ic_home_outline_grey600_24dp.png
    │               └── ic_logout_grey600_24dp.png
    │           ├── drawable-xhdpi
    │               ├── ic_account_outline_grey600_24dp.png
    │               ├── ic_cart_outline_grey600_24dp.png
    │               ├── ic_email_outline_grey600_24dp.png
    │               ├── ic_home_outline_grey600_24dp.png
    │               └── ic_logout_grey600_24dp.png
    │           ├── drawable-xxhdpi
    │               ├── ic_account_outline_grey600_24dp.png
    │               ├── ic_cart_outline_grey600_24dp.png
    │               ├── ic_email_outline_grey600_24dp.png
    │               ├── ic_home_outline_grey600_24dp.png
    │               └── ic_logout_grey600_24dp.png
    │           ├── drawable-xxxhdpi
    │               ├── ic_account_outline_grey600_24dp.png
    │               ├── ic_cart_outline_grey600_24dp.png
    │               ├── ic_email_outline_grey600_24dp.png
    │               ├── ic_home_outline_grey600_24dp.png
    │               └── ic_logout_grey600_24dp.png
    │           ├── drawable
    │               └── jdashboard.jpg
    │           ├── layout
    │               ├── activity_main.xml
    │               ├── fragment_text.xml
    │               ├── item_option.xml
    │               └── menu_left_drawer.xml
    │           ├── mipmap-hdpi
    │               └── ic_launcher.png
    │           ├── mipmap-mdpi
    │               └── ic_launcher.png
    │           ├── mipmap-xhdpi
    │               └── ic_launcher.png
    │           ├── mipmap-xxhdpi
    │               └── ic_launcher.png
    │           ├── mipmap-xxxhdpi
    │               └── ic_launcher.png
    │           └── values
    │               ├── arrays.xml
    │               ├── colors.xml
    │               ├── strings.xml
    │               └── styles.xml
└── settings.gradle


/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/*
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
  1 |                                  Apache License
  2 |                            Version 2.0, January 2004
  3 |                         http://www.apache.org/licenses/
  4 | 
  5 |    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
  6 | 
  7 |    1. Definitions.
  8 | 
  9 |       "License" shall mean the terms and conditions for use, reproduction,
 10 |       and distribution as defined by Sections 1 through 9 of this document.
 11 | 
 12 |       "Licensor" shall mean the copyright owner or entity authorized by
 13 |       the copyright owner that is granting the License.
 14 | 
 15 |       "Legal Entity" shall mean the union of the acting entity and all
 16 |       other entities that control, are controlled by, or are under common
 17 |       control with that entity. For the purposes of this definition,
 18 |       "control" means (i) the power, direct or indirect, to cause the
 19 |       direction or management of such entity, whether by contract or
 20 |       otherwise, or (ii) ownership of fifty percent (50%) or more of the
 21 |       outstanding shares, or (iii) beneficial ownership of such entity.
 22 | 
 23 |       "You" (or "Your") shall mean an individual or Legal Entity
 24 |       exercising permissions granted by this License.
 25 | 
 26 |       "Source" form shall mean the preferred form for making modifications,
 27 |       including but not limited to software source code, documentation
 28 |       source, and configuration files.
 29 | 
 30 |       "Object" form shall mean any form resulting from mechanical
 31 |       transformation or translation of a Source form, including but
 32 |       not limited to compiled object code, generated documentation,
 33 |       and conversions to other media types.
 34 | 
 35 |       "Work" shall mean the work of authorship, whether in Source or
 36 |       Object form, made available under the License, as indicated by a
 37 |       copyright notice that is included in or attached to the work
 38 |       (an example is provided in the Appendix below).
 39 | 
 40 |       "Derivative Works" shall mean any work, whether in Source or Object
 41 |       form, that is based on (or derived from) the Work and for which the
 42 |       editorial revisions, annotations, elaborations, or other modifications
 43 |       represent, as a whole, an original work of authorship. For the purposes
 44 |       of this License, Derivative Works shall not include works that remain
 45 |       separable from, or merely link (or bind by name) to the interfaces of,
 46 |       the Work and Derivative Works thereof.
 47 | 
 48 |       "Contribution" shall mean any work of authorship, including
 49 |       the original version of the Work and any modifications or additions
 50 |       to that Work or Derivative Works thereof, that is intentionally
 51 |       submitted to Licensor for inclusion in the Work by the copyright owner
 52 |       or by an individual or Legal Entity authorized to submit on behalf of
 53 |       the copyright owner. For the purposes of this definition, "submitted"
 54 |       means any form of electronic, verbal, or written communication sent
 55 |       to the Licensor or its representatives, including but not limited to
 56 |       communication on electronic mailing lists, source code control systems,
 57 |       and issue tracking systems that are managed by, or on behalf of, the
 58 |       Licensor for the purpose of discussing and improving the Work, but
 59 |       excluding communication that is conspicuously marked or otherwise
 60 |       designated in writing by the copyright owner as "Not a Contribution."
 61 | 
 62 |       "Contributor" shall mean Licensor and any individual or Legal Entity
 63 |       on behalf of whom a Contribution has been received by Licensor and
 64 |       subsequently incorporated within the Work.
 65 | 
 66 |    2. Grant of Copyright License. Subject to the terms and conditions of
 67 |       this License, each Contributor hereby grants to You a perpetual,
 68 |       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 69 |       copyright license to reproduce, prepare Derivative Works of,
 70 |       publicly display, publicly perform, sublicense, and distribute the
 71 |       Work and such Derivative Works in Source or Object form.
 72 | 
 73 |    3. Grant of Patent License. Subject to the terms and conditions of
 74 |       this License, each Contributor hereby grants to You a perpetual,
 75 |       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 76 |       (except as stated in this section) patent license to make, have made,
 77 |       use, offer to sell, sell, import, and otherwise transfer the Work,
 78 |       where such license applies only to those patent claims licensable
 79 |       by such Contributor that are necessarily infringed by their
 80 |       Contribution(s) alone or by combination of their Contribution(s)
 81 |       with the Work to which such Contribution(s) was submitted. If You
 82 |       institute patent litigation against any entity (including a
 83 |       cross-claim or counterclaim in a lawsuit) alleging that the Work
 84 |       or a Contribution incorporated within the Work constitutes direct
 85 |       or contributory patent infringement, then any patent licenses
 86 |       granted to You under this License for that Work shall terminate
 87 |       as of the date such litigation is filed.
 88 | 
 89 |    4. Redistribution. You may reproduce and distribute copies of the
 90 |       Work or Derivative Works thereof in any medium, with or without
 91 |       modifications, and in Source or Object form, provided that You
 92 |       meet the following conditions:
 93 | 
 94 |       (a) You must give any other recipients of the Work or
 95 |           Derivative Works a copy of this License; and
 96 | 
 97 |       (b) You must cause any modified files to carry prominent notices
 98 |           stating that You changed the files; and
 99 | 
100 |       (c) You must retain, in the Source form of any Derivative Works
101 |           that You distribute, all copyright, patent, trademark, and
102 |           attribution notices from the Source form of the Work,
103 |           excluding those notices that do not pertain to any part of
104 |           the Derivative Works; and
105 | 
106 |       (d) If the Work includes a "NOTICE" text file as part of its
107 |           distribution, then any Derivative Works that You distribute must
108 |           include a readable copy of the attribution notices contained
109 |           within such NOTICE file, excluding those notices that do not
110 |           pertain to any part of the Derivative Works, in at least one
111 |           of the following places: within a NOTICE text file distributed
112 |           as part of the Derivative Works; within the Source form or
113 |           documentation, if provided along with the Derivative Works; or,
114 |           within a display generated by the Derivative Works, if and
115 |           wherever such third-party notices normally appear. The contents
116 |           of the NOTICE file are for informational purposes only and
117 |           do not modify the License. You may add Your own attribution
118 |           notices within Derivative Works that You distribute, alongside
119 |           or as an addendum to the NOTICE text from the Work, provided
120 |           that such additional attribution notices cannot be construed
121 |           as modifying the License.
122 | 
123 |       You may add Your own copyright statement to Your modifications and
124 |       may provide additional or different license terms and conditions
125 |       for use, reproduction, or distribution of Your modifications, or
126 |       for any such Derivative Works as a whole, provided Your use,
127 |       reproduction, and distribution of the Work otherwise complies with
128 |       the conditions stated in this License.
129 | 
130 |    5. Submission of Contributions. Unless You explicitly state otherwise,
131 |       any Contribution intentionally submitted for inclusion in the Work
132 |       by You to the Licensor shall be under the terms and conditions of
133 |       this License, without any additional terms or conditions.
134 |       Notwithstanding the above, nothing herein shall supersede or modify
135 |       the terms of any separate license agreement you may have executed
136 |       with Licensor regarding such Contributions.
137 | 
138 |    6. Trademarks. This License does not grant permission to use the trade
139 |       names, trademarks, service marks, or product names of the Licensor,
140 |       except as required for reasonable and customary use in describing the
141 |       origin of the Work and reproducing the content of the NOTICE file.
142 | 
143 |    7. Disclaimer of Warranty. Unless required by applicable law or
144 |       agreed to in writing, Licensor provides the Work (and each
145 |       Contributor provides its Contributions) on an "AS IS" BASIS,
146 |       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 |       implied, including, without limitation, any warranties or conditions
148 |       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 |       PARTICULAR PURPOSE. You are solely responsible for determining the
150 |       appropriateness of using or redistributing the Work and assume any
151 |       risks associated with Your exercise of permissions under this License.
152 | 
153 |    8. Limitation of Liability. In no event and under no legal theory,
154 |       whether in tort (including negligence), contract, or otherwise,
155 |       unless required by applicable law (such as deliberate and grossly
156 |       negligent acts) or agreed to in writing, shall any Contributor be
157 |       liable to You for damages, including any direct, indirect, special,
158 |       incidental, or consequential damages of any character arising as a
159 |       result of this License or out of the use or inability to use the
160 |       Work (including but not limited to damages for loss of goodwill,
161 |       work stoppage, computer failure or malfunction, or any and all
162 |       other commercial damages or losses), even if such Contributor
163 |       has been advised of the possibility of such damages.
164 | 
165 |    9. Accepting Warranty or Additional Liability. While redistributing
166 |       the Work or Derivative Works thereof, You may choose to offer,
167 |       and charge a fee for, acceptance of support, warranty, indemnity,
168 |       or other liability obligations and/or rights consistent with this
169 |       License. However, in accepting such obligations, You may act only
170 |       on Your own behalf and on Your sole responsibility, not on behalf
171 |       of any other Contributor, and only if You agree to indemnify,
172 |       defend, and hold each Contributor harmless for any liability
173 |       incurred by, or claims asserted against, such Contributor by reason
174 |       of your accepting any such warranty or additional liability.
175 | 
176 |    END OF TERMS AND CONDITIONS
177 | 
178 |    Copyright 2017 Yaroslav Shevchuk
179 | 
180 |    Licensed under the Apache License, Version 2.0 (the "License");
181 |    you may not use this file except in compliance with the License.
182 |    You may obtain a copy of the License at
183 | 
184 |        http://www.apache.org/licenses/LICENSE-2.0
185 | 
186 |    Unless required by applicable law or agreed to in writing, software
187 |    distributed under the License is distributed on an "AS IS" BASIS,
188 |    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189 |    See the License for the specific language governing permissions and
190 |    limitations under the License.
191 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
  1 | # SlidingRootNav
  2 | 
  3 | The library is a DrawerLayout-like ViewGroup, where a "drawer" is hidden under the content view, which can be shifted to make the drawer visible. It doesn't provide you with a drawer builder.
  4 | 
  5 | ![GifSample](art/sample.gif)
  6 | 
  7 | ## Gradle 
  8 | Add this into your dependencies block.
  9 | ```
 10 | compile 'com.yarolegovich:sliding-root-nav:1.1.1'
 11 | ```
 12 | ## Sample
 13 | Please see the [sample app](sample/src/main/java/com/yarolegovich/slidingrootnav/sample) for a library usage example.
 14 | 
 15 | ## Wiki
 16 | #### Usage:
 17 |  1. Create your content_view.xml ([example](sample/src/main/res/layout/activity_main.xml)) or construct a `View` programatically.
 18 |  2. Set the content view (for example, using `setContentView` in your activity).
 19 |  3. Create your menu.xml ([example](sample/src/main/res/layout/menu_left_drawer.xml)) or construct a `View` programatically.
 20 |  4. Now you need to inject the menu in your `onCreate`. You can specify transformations of a content view or use the default ones. 
 21 | ```java
 22 | new SlidingRootNavBuilder(this)
 23 |   .withMenuLayout(R.layout.menu_left_drawer)
 24 |   .inject();
 25 | ```
 26 | 
 27 | ### API
 28 | #### Transformations
 29 | You can specify root transformations using `SlidingRootNavBuilder`.
 30 | ```java
 31 | new SlidingRootNavBuilder(this)
 32 |   .withDragDistance(140) //Horizontal translation of a view. Default == 180dp
 33 |   .withRootViewScale(0.7f) //Content view's scale will be interpolated between 1f and 0.7f. Default == 0.65f;
 34 |   .withRootViewElevation(10) //Content view's elevation will be interpolated between 0 and 10dp. Default == 8.
 35 |   .withRootViewYTranslation(4) //Content view's translationY will be interpolated between 0 and 4. Default == 0
 36 |   .addRootTransformation(customTransformation)
 37 |   .inject();
 38 | ```
 39 | `customTransformation` in the above example is a user-created class that implements `RootTransformation` interface. For an example, refer to the [default transformations](library/src/main/java/com/yarolegovich/slidingrootnav/transform). 
 40 | 
 41 | #### Menu behavior
 42 | ```java
 43 | new SlidingRootNavBuilder(this)
 44 |   .withMenuOpened(true) //Initial menu opened/closed state. Default == false
 45 |   .withMenuLocked(false) //If true, a user can't open or close the menu. Default == false.
 46 |   .withGravity(SlideGravity.LEFT) //If LEFT you can swipe a menu from left to right, if RIGHT - the direction is opposite. 
 47 |   .withSavedState(savedInstanceState) //If you call the method, layout will restore its opened/closed state
 48 |   .withContentClickableWhenMenuOpened(isClickable) //Pretty self-descriptive. Builder Default == true
 49 | ```
 50 | #### Controling the layout
 51 | A call to `inject()` returns you an interface for controlling the layout.
 52 | ```java
 53 | public interface SlidingRootNav {
 54 |     boolean isMenuClosed();
 55 |     boolean isMenuOpened();
 56 |     boolean isMenuLocked();
 57 |     void closeMenu();
 58 |     void closeMenu(boolean animated);
 59 |     void openMenu();
 60 |     void openMenu(boolean animated);
 61 |     void setMenuLocked(boolean locked);
 62 |     SlidingRootNavLayout getLayout(); //If for some reason you need to work directly with layout - you can
 63 | }
 64 | ```
 65 | 
 66 | #### Callbacks
 67 | * Drag progress:
 68 | ```java
 69 | builder.addDragListener(listener);
 70 | 
 71 | public interface DragListener {
 72 |   void onDrag(float progress); //Float between 0 and 1, where 1 is a fully visible menu
 73 | }
 74 | 
 75 | ```
 76 | * Drag state changes:
 77 | ```java
 78 | builder.addDragStateListener(listener);
 79 | 
 80 | public interface DragStateListener {
 81 |   void onDragStart();
 82 |   void onDragEnd(boolean isMenuOpened);
 83 | }
 84 | ```
 85 | 
 86 | * Compatibility with `DrawerLayout.DrawerListener`:
 87 | ```java
 88 | DrawerListenerAdapter adapter = new DrawerListenerAdapter(yourDrawerListener, viewToPassAsDrawer);
 89 | builder.addDragListener(listenerAdapter).addDragStateListener(listenerAdapter);
 90 | ```
 91 | 
 92 | ## Special thanks
 93 | Thanks to [Tayisiya Yurkiv](https://www.behance.net/yurkivt) for a beautiful GIF.
 94 | 
 95 | ## License
 96 | ```
 97 | Copyright 2017 Yaroslav Shevchuk
 98 | 
 99 | Licensed under the Apache License, Version 2.0 (the "License");
100 | you may not use this file except in compliance with the License.
101 | You may obtain a copy of the License at
102 | 
103 | http://www.apache.org/licenses/LICENSE-2.0
104 | 
105 | Unless required by applicable law or agreed to in writing, software
106 | distributed under the License is distributed on an "AS IS" BASIS,
107 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108 | See the License for the specific language governing permissions and
109 | limitations under the License.
110 | ```
111 | 


--------------------------------------------------------------------------------
/art/sample.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/art/sample.gif


--------------------------------------------------------------------------------
/art/sample_arsenal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/art/sample_arsenal.jpg


--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
 1 | buildscript {
 2 |     repositories {
 3 |         jcenter()
 4 |         google()
 5 |     }
 6 |     dependencies {
 7 |         classpath 'com.android.tools.build:gradle:4.0.1'
 8 |         classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
 9 |     }
10 | }
11 | 
12 | allprojects {
13 |     repositories {
14 |         jcenter()
15 |         maven { url "https://maven.google.com" }
16 |     }
17 | }
18 | 
19 | task clean(type: Delete) {
20 |     delete rootProject.buildDir
21 | }
22 | 
23 | ext {
24 |     compileSdkVersion = 29
25 |     buildToolsVersion = '29.0.2'
26 |     minSdkVersion = 16
27 |     targetSdkVersion = 29
28 | 
29 |     deps = [
30 |             recycler      : 'androidx.recyclerview:recyclerview:1.0.0',
31 |             designSupport : 'com.google.android.material:material:1.0.0',
32 |             annotations   : 'androidx.annotation:annotation:1.1.0',
33 |             androidxCompat: 'androidx.appcompat:appcompat:1.1.0',
34 |     ]
35 | }


--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | android.useAndroidX=true
2 | 
3 | org.gradle.jvmargs=-Xmx1536m
4 | 


--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/gradle/wrapper/gradle-wrapper.jar


--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Aug 01 18:16:29 EEST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 | 


--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
  1 | #!/usr/bin/env bash
  2 | 
  3 | ##############################################################################
  4 | ##
  5 | ##  Gradle start up script for UN*X
  6 | ##
  7 | ##############################################################################
  8 | 
  9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 10 | DEFAULT_JVM_OPTS=""
 11 | 
 12 | APP_NAME="Gradle"
 13 | APP_BASE_NAME=`basename "$0"`
 14 | 
 15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
 16 | MAX_FD="maximum"
 17 | 
 18 | warn ( ) {
 19 |     echo "$*"
 20 | }
 21 | 
 22 | die ( ) {
 23 |     echo
 24 |     echo "$*"
 25 |     echo
 26 |     exit 1
 27 | }
 28 | 
 29 | # OS specific support (must be 'true' or 'false').
 30 | cygwin=false
 31 | msys=false
 32 | darwin=false
 33 | case "`uname`" in
 34 |   CYGWIN* )
 35 |     cygwin=true
 36 |     ;;
 37 |   Darwin* )
 38 |     darwin=true
 39 |     ;;
 40 |   MINGW* )
 41 |     msys=true
 42 |     ;;
 43 | esac
 44 | 
 45 | # Attempt to set APP_HOME
 46 | # Resolve links: $0 may be a link
 47 | PRG="$0"
 48 | # Need this for relative symlinks.
 49 | while [ -h "$PRG" ] ; do
 50 |     ls=`ls -ld "$PRG"`
 51 |     link=`expr "$ls" : '.*-> \(.*\)
#39;`
 52 |     if expr "$link" : '/.*' > /dev/null; then
 53 |         PRG="$link"
 54 |     else
 55 |         PRG=`dirname "$PRG"`"/$link"
 56 |     fi
 57 | done
 58 | SAVED="`pwd`"
 59 | cd "`dirname \"$PRG\"`/" >/dev/null
 60 | APP_HOME="`pwd -P`"
 61 | cd "$SAVED" >/dev/null
 62 | 
 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 64 | 
 65 | # Determine the Java command to use to start the JVM.
 66 | if [ -n "$JAVA_HOME" ] ; then
 67 |     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
 68 |         # IBM's JDK on AIX uses strange locations for the executables
 69 |         JAVACMD="$JAVA_HOME/jre/sh/java"
 70 |     else
 71 |         JAVACMD="$JAVA_HOME/bin/java"
 72 |     fi
 73 |     if [ ! -x "$JAVACMD" ] ; then
 74 |         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
 75 | 
 76 | Please set the JAVA_HOME variable in your environment to match the
 77 | location of your Java installation."
 78 |     fi
 79 | else
 80 |     JAVACMD="java"
 81 |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 82 | 
 83 | Please set the JAVA_HOME variable in your environment to match the
 84 | location of your Java installation."
 85 | fi
 86 | 
 87 | # Increase the maximum file descriptors if we can.
 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
 89 |     MAX_FD_LIMIT=`ulimit -H -n`
 90 |     if [ $? -eq 0 ] ; then
 91 |         if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
 92 |             MAX_FD="$MAX_FD_LIMIT"
 93 |         fi
 94 |         ulimit -n $MAX_FD
 95 |         if [ $? -ne 0 ] ; then
 96 |             warn "Could not set maximum file descriptor limit: $MAX_FD"
 97 |         fi
 98 |     else
 99 |         warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 |     fi
101 | fi
102 | 
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 |     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 | 
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 |     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 |     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 |     JAVACMD=`cygpath --unix "$JAVACMD"`
113 | 
114 |     # We build the pattern for arguments to be converted via cygpath
115 |     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 |     SEP=""
117 |     for dir in $ROOTDIRSRAW ; do
118 |         ROOTDIRS="$ROOTDIRS$SEP$dir"
119 |         SEP="|"
120 |     done
121 |     OURCYGPATTERN="(^($ROOTDIRS))"
122 |     # Add a user-defined pattern to the cygpath arguments
123 |     if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 |         OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 |     fi
126 |     # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 |     i=0
128 |     for arg in "$@" ; do
129 |         CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 |         CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
131 | 
132 |         if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
133 |             eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 |         else
135 |             eval `echo args$i`="\"$arg\""
136 |         fi
137 |         i=$((i+1))
138 |     done
139 |     case $i in
140 |         (0) set -- ;;
141 |         (1) set -- "$args0" ;;
142 |         (2) set -- "$args0" "$args1" ;;
143 |         (3) set -- "$args0" "$args1" "$args2" ;;
144 |         (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 |         (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 |         (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 |         (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 |         (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 |         (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 |     esac
151 | fi
152 | 
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 |     JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 | 
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 | 


--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
 1 | @if "%DEBUG%" == "" @echo off
 2 | @rem ##########################################################################
 3 | @rem
 4 | @rem  Gradle startup script for Windows
 5 | @rem
 6 | @rem ##########################################################################
 7 | 
 8 | @rem Set local scope for the variables with windows NT shell
 9 | if "%OS%"=="Windows_NT" setlocal
10 | 
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 | 
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 | 
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 | 
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 | 
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 | 
32 | goto fail
33 | 
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 | 
38 | if exist "%JAVA_EXE%" goto init
39 | 
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 | 
46 | goto fail
47 | 
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 | 
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 | 
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 | 
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 | 
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 | 
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 | 
69 | :execute
70 | @rem Setup the command line
71 | 
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 | 
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 | 
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 | 
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 | 
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 | 
90 | :omega
91 | 


--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | 


--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
 1 | apply plugin: 'com.android.library'
 2 | apply from: rootProject.file('release-bintray.gradle')
 3 | 
 4 | android {
 5 |     compileSdkVersion rootProject.ext.compileSdkVersion
 6 |     buildToolsVersion rootProject.ext.buildToolsVersion
 7 | 
 8 |     defaultConfig {
 9 |         minSdkVersion 16
10 |         targetSdkVersion rootProject.ext.targetSdkVersion
11 |     }
12 | }
13 | 
14 | dependencies {
15 |     implementation deps.annotations
16 |     implementation deps.androidxCompat
17 | }


--------------------------------------------------------------------------------
/library/proguard-rules.pro:
--------------------------------------------------------------------------------
 1 | # Add project specific ProGuard rules here.
 2 | # By default, the flags in this file are appended to flags specified
 3 | # in C:\Users\yarolegovich\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
 4 | # You can edit the include path and order by changing the proguardFiles
 5 | # directive in build.gradle.
 6 | #
 7 | # For more details, see
 8 | #   http://developer.android.com/guide/developing/tools/proguard.html
 9 | 
10 | # Add any project specific keep options here:
11 | 
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | #   public *;
17 | #}
18 | 


--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 | <manifest package="com.yarolegovich.slidingrootnav" />
2 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/SlideGravity.java:
--------------------------------------------------------------------------------
  1 | package com.yarolegovich.slidingrootnav;
  2 | 
  3 | 
  4 | import androidx.customview.widget.ViewDragHelper;
  5 | 
  6 | /**
  7 |  * Created by yarolegovich on 25.03.2017.
  8 |  */
  9 | 
 10 | public enum SlideGravity {
 11 | 
 12 |     LEFT {
 13 |         @Override
 14 |         Helper createHelper() {
 15 |             return new LeftHelper();
 16 |         }
 17 |     },
 18 |     RIGHT {
 19 |         @Override
 20 |         Helper createHelper() {
 21 |             return new RightHelper();
 22 |         }
 23 |     };
 24 | 
 25 |     abstract Helper createHelper();
 26 | 
 27 |     interface Helper {
 28 | 
 29 |         int getLeftAfterFling(float flingVelocity, int maxDrag);
 30 | 
 31 |         int getLeftToSettle(float dragProgress, int maxDrag);
 32 | 
 33 |         int getRootLeft(float dragProgress, int maxDrag);
 34 | 
 35 |         float getDragProgress(int viewLeft, int maxDrag);
 36 | 
 37 |         int clampViewPosition(int left, int maxDrag);
 38 | 
 39 |         void enableEdgeTrackingOn(ViewDragHelper dragHelper);
 40 |     }
 41 | 
 42 |     static class LeftHelper implements Helper {
 43 | 
 44 |         @Override
 45 |         public int getLeftAfterFling(float flingVelocity, int maxDrag) {
 46 |             return flingVelocity > 0 ? maxDrag : 0;
 47 |         }
 48 | 
 49 |         @Override
 50 |         public int getLeftToSettle(float dragProgress, int maxDrag) {
 51 |             return dragProgress > 0.5f ? maxDrag : 0;
 52 |         }
 53 | 
 54 |         @Override
 55 |         public int getRootLeft(float dragProgress, int maxDrag) {
 56 |             return (int) (dragProgress * maxDrag);
 57 |         }
 58 | 
 59 |         @Override
 60 |         public float getDragProgress(int viewLeft, int maxDrag) {
 61 |             return ((float) viewLeft) / maxDrag;
 62 |         }
 63 | 
 64 |         @Override
 65 |         public int clampViewPosition(int left, int maxDrag) {
 66 |             return Math.max(0, Math.min(left, maxDrag));
 67 |         }
 68 | 
 69 |         @Override
 70 |         public void enableEdgeTrackingOn(ViewDragHelper dragHelper) {
 71 |             dragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
 72 |         }
 73 |     }
 74 | 
 75 |     static class RightHelper implements Helper {
 76 | 
 77 |         @Override
 78 |         public int getLeftAfterFling(float flingVelocity, int maxDrag) {
 79 |             return flingVelocity > 0 ? 0 : -maxDrag;
 80 |         }
 81 | 
 82 |         @Override
 83 |         public int getLeftToSettle(float dragProgress, int maxDrag) {
 84 |             return dragProgress > 0.5f ? -maxDrag : 0;
 85 |         }
 86 | 
 87 |         @Override
 88 |         public int getRootLeft(float dragProgress, int maxDrag) {
 89 |             return (int) -(dragProgress * maxDrag);
 90 |         }
 91 | 
 92 |         @Override
 93 |         public float getDragProgress(int viewLeft, int maxDrag) {
 94 |             return ((float) Math.abs(viewLeft)) / maxDrag;
 95 |         }
 96 | 
 97 |         @Override
 98 |         public int clampViewPosition(int left, int maxDrag) {
 99 |             return Math.max(-maxDrag, Math.min(left, 0));
100 |         }
101 | 
102 |         @Override
103 |         public void enableEdgeTrackingOn(ViewDragHelper dragHelper) {
104 |             dragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT);
105 |         }
106 |     }
107 | 
108 | }
109 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/SlidingRootNav.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav;
 2 | 
 3 | /**
 4 |  * Created by yarolegovich on 25.03.2017.
 5 |  */
 6 | 
 7 | public interface SlidingRootNav {
 8 | 
 9 |     boolean isMenuClosed();
10 | 
11 |     boolean isMenuOpened();
12 | 
13 |     boolean isMenuLocked();
14 | 
15 |     void closeMenu();
16 | 
17 |     void closeMenu(boolean animated);
18 | 
19 |     void openMenu();
20 | 
21 |     void openMenu(boolean animated);
22 | 
23 |     void setMenuLocked(boolean locked);
24 | 
25 |     SlidingRootNavLayout getLayout();
26 | 
27 | }
28 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/SlidingRootNavBuilder.java:
--------------------------------------------------------------------------------
  1 | package com.yarolegovich.slidingrootnav;
  2 | 
  3 | import android.app.Activity;
  4 | import android.os.Bundle;
  5 | import android.view.LayoutInflater;
  6 | import android.view.View;
  7 | import android.view.ViewGroup;
  8 | 
  9 | import androidx.annotation.FloatRange;
 10 | import androidx.annotation.IntRange;
 11 | import androidx.annotation.LayoutRes;
 12 | import androidx.appcompat.app.ActionBarDrawerToggle;
 13 | import androidx.appcompat.widget.Toolbar;
 14 | 
 15 | import com.yarolegovich.slidingrootnav.callback.DragListener;
 16 | import com.yarolegovich.slidingrootnav.callback.DragStateListener;
 17 | import com.yarolegovich.slidingrootnav.transform.CompositeTransformation;
 18 | import com.yarolegovich.slidingrootnav.transform.ElevationTransformation;
 19 | import com.yarolegovich.slidingrootnav.transform.RootTransformation;
 20 | import com.yarolegovich.slidingrootnav.transform.ScaleTransformation;
 21 | import com.yarolegovich.slidingrootnav.transform.YTranslationTransformation;
 22 | import com.yarolegovich.slidingrootnav.util.ActionBarToggleAdapter;
 23 | import com.yarolegovich.slidingrootnav.util.DrawerListenerAdapter;
 24 | import com.yarolegovich.slidingrootnav.util.HiddenMenuClickConsumer;
 25 | 
 26 | import java.util.ArrayList;
 27 | import java.util.Arrays;
 28 | import java.util.List;
 29 | 
 30 | /**
 31 |  * Created by yarolegovich on 24.03.2017.
 32 |  */
 33 | 
 34 | public class SlidingRootNavBuilder {
 35 | 
 36 |     private static final float DEFAULT_END_SCALE = 0.65f;
 37 |     private static final int DEFAULT_END_ELEVATION_DP = 8;
 38 |     private static final int DEFAULT_DRAG_DIST_DP = 180;
 39 | 
 40 |     private Activity activity;
 41 | 
 42 |     private ViewGroup contentView;
 43 | 
 44 |     private View menuView;
 45 |     private int menuLayoutRes;
 46 | 
 47 |     private List<RootTransformation> transformations;
 48 | 
 49 |     private List<DragListener> dragListeners;
 50 | 
 51 |     private List<DragStateListener> dragStateListeners;
 52 | 
 53 |     private int dragDistance;
 54 | 
 55 |     private Toolbar toolbar;
 56 | 
 57 |     private SlideGravity gravity;
 58 | 
 59 |     private boolean isMenuOpened;
 60 | 
 61 |     private boolean isMenuLocked;
 62 | 
 63 |     private boolean isContentClickableWhenMenuOpened;
 64 | 
 65 |     private Bundle savedState;
 66 | 
 67 |     public SlidingRootNavBuilder(Activity activity) {
 68 |         this.activity = activity;
 69 |         this.transformations = new ArrayList<>();
 70 |         this.dragListeners = new ArrayList<>();
 71 |         this.dragStateListeners = new ArrayList<>();
 72 |         this.gravity = SlideGravity.LEFT;
 73 |         this.dragDistance = dpToPx(DEFAULT_DRAG_DIST_DP);
 74 |         this.isContentClickableWhenMenuOpened = true;
 75 |     }
 76 | 
 77 |     public SlidingRootNavBuilder withMenuView(View view) {
 78 |         menuView = view;
 79 |         return this;
 80 |     }
 81 | 
 82 |     public SlidingRootNavBuilder withMenuLayout(@LayoutRes int layout) {
 83 |         menuLayoutRes = layout;
 84 |         return this;
 85 |     }
 86 | 
 87 |     public SlidingRootNavBuilder withToolbarMenuToggle(Toolbar tb) {
 88 |         toolbar = tb;
 89 |         return this;
 90 |     }
 91 | 
 92 |     public SlidingRootNavBuilder withGravity(SlideGravity g) {
 93 |         gravity = g;
 94 |         return this;
 95 |     }
 96 | 
 97 |     public SlidingRootNavBuilder withContentView(ViewGroup cv) {
 98 |         contentView = cv;
 99 |         return this;
100 |     }
101 | 
102 |     public SlidingRootNavBuilder withMenuLocked(boolean locked) {
103 |         isMenuLocked = locked;
104 |         return this;
105 |     }
106 | 
107 |     public SlidingRootNavBuilder withSavedState(Bundle state) {
108 |         savedState = state;
109 |         return this;
110 |     }
111 | 
112 |     public SlidingRootNavBuilder withMenuOpened(boolean opened) {
113 |         isMenuOpened = opened;
114 |         return this;
115 |     }
116 | 
117 |     public SlidingRootNavBuilder withContentClickableWhenMenuOpened(boolean clickable) {
118 |         isContentClickableWhenMenuOpened = clickable;
119 |         return this;
120 |     }
121 | 
122 |     public SlidingRootNavBuilder withDragDistance(int dp) {
123 |         return withDragDistancePx(dpToPx(dp));
124 |     }
125 | 
126 |     public SlidingRootNavBuilder withDragDistancePx(int px) {
127 |         dragDistance = px;
128 |         return this;
129 |     }
130 | 
131 |     public SlidingRootNavBuilder withRootViewScale(@FloatRange(from = 0.01f) float scale) {
132 |         transformations.add(new ScaleTransformation(scale));
133 |         return this;
134 |     }
135 | 
136 |     public SlidingRootNavBuilder withRootViewElevation(@IntRange(from = 0) int elevation) {
137 |         return withRootViewElevationPx(dpToPx(elevation));
138 |     }
139 | 
140 |     public SlidingRootNavBuilder withRootViewElevationPx(@IntRange(from = 0) int elevation) {
141 |         transformations.add(new ElevationTransformation(elevation));
142 |         return this;
143 |     }
144 | 
145 |     public SlidingRootNavBuilder withRootViewYTranslation(int translation) {
146 |         return withRootViewYTranslationPx(dpToPx(translation));
147 |     }
148 | 
149 |     public SlidingRootNavBuilder withRootViewYTranslationPx(int translation) {
150 |         transformations.add(new YTranslationTransformation(translation));
151 |         return this;
152 |     }
153 | 
154 |     public SlidingRootNavBuilder addRootTransformation(RootTransformation transformation) {
155 |         transformations.add(transformation);
156 |         return this;
157 |     }
158 | 
159 |     public SlidingRootNavBuilder addDragListener(DragListener dragListener) {
160 |         dragListeners.add(dragListener);
161 |         return this;
162 |     }
163 | 
164 |     public SlidingRootNavBuilder addDragStateListener(DragStateListener dragStateListener) {
165 |         dragStateListeners.add(dragStateListener);
166 |         return this;
167 |     }
168 | 
169 |     public SlidingRootNav inject() {
170 |         ViewGroup contentView = getContentView();
171 | 
172 |         View oldRoot = contentView.getChildAt(0);
173 |         contentView.removeAllViews();
174 | 
175 |         SlidingRootNavLayout newRoot = createAndInitNewRoot(oldRoot);
176 | 
177 |         View menu = getMenuViewFor(newRoot);
178 | 
179 |         initToolbarMenuVisibilityToggle(newRoot, menu);
180 | 
181 |         HiddenMenuClickConsumer clickConsumer = new HiddenMenuClickConsumer(activity);
182 |         clickConsumer.setMenuHost(newRoot);
183 | 
184 |         newRoot.addView(menu);
185 |         newRoot.addView(clickConsumer);
186 |         newRoot.addView(oldRoot);
187 | 
188 |         contentView.addView(newRoot);
189 | 
190 |         if (savedState == null) {
191 |             if (isMenuOpened) {
192 |                 newRoot.openMenu(false);
193 |             }
194 |         }
195 | 
196 |         newRoot.setMenuLocked(isMenuLocked);
197 | 
198 |         return newRoot;
199 |     }
200 | 
201 |     private SlidingRootNavLayout createAndInitNewRoot(View oldRoot) {
202 |         SlidingRootNavLayout newRoot = new SlidingRootNavLayout(activity);
203 |         newRoot.setId(R.id.srn_root_layout);
204 |         newRoot.setRootTransformation(createCompositeTransformation());
205 |         newRoot.setMaxDragDistance(dragDistance);
206 |         newRoot.setGravity(gravity);
207 |         newRoot.setRootView(oldRoot);
208 |         newRoot.setContentClickableWhenMenuOpened(isContentClickableWhenMenuOpened);
209 |         for (DragListener l : dragListeners) {
210 |             newRoot.addDragListener(l);
211 |         }
212 |         for (DragStateListener l : dragStateListeners) {
213 |             newRoot.addDragStateListener(l);
214 |         }
215 |         return newRoot;
216 |     }
217 | 
218 |     private ViewGroup getContentView() {
219 |         if (contentView == null) {
220 |             contentView = (ViewGroup) activity.findViewById(android.R.id.content);
221 |         }
222 |         if (contentView.getChildCount() != 1) {
223 |             throw new IllegalStateException(activity.getString(R.string.srn_ex_bad_content_view));
224 |         }
225 |         return contentView;
226 |     }
227 | 
228 |     private View getMenuViewFor(SlidingRootNavLayout parent) {
229 |         if (menuView == null) {
230 |             if (menuLayoutRes == 0) {
231 |                 throw new IllegalStateException(activity.getString(R.string.srn_ex_no_menu_view));
232 |             }
233 |             menuView = LayoutInflater.from(activity).inflate(menuLayoutRes, parent, false);
234 |         }
235 |         return menuView;
236 |     }
237 | 
238 |     private RootTransformation createCompositeTransformation() {
239 |         if (transformations.isEmpty()) {
240 |             return new CompositeTransformation(Arrays.asList(
241 |                     new ScaleTransformation(DEFAULT_END_SCALE),
242 |                     new ElevationTransformation(dpToPx(DEFAULT_END_ELEVATION_DP))));
243 |         } else {
244 |             return new CompositeTransformation(transformations);
245 |         }
246 |     }
247 | 
248 |     protected void initToolbarMenuVisibilityToggle(final SlidingRootNavLayout sideNav, View drawer) {
249 |         if (toolbar != null) {
250 |             ActionBarToggleAdapter dlAdapter = new ActionBarToggleAdapter(activity);
251 |             dlAdapter.setAdaptee(sideNav);
252 |             ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(activity, dlAdapter, toolbar,
253 |                     R.string.srn_drawer_open,
254 |                     R.string.srn_drawer_close);
255 |             toggle.syncState();
256 |             DrawerListenerAdapter listenerAdapter = new DrawerListenerAdapter(toggle, drawer);
257 |             sideNav.addDragListener(listenerAdapter);
258 |             sideNav.addDragStateListener(listenerAdapter);
259 |         }
260 |     }
261 | 
262 |     private int dpToPx(int dp) {
263 |         return Math.round(activity.getResources().getDisplayMetrics().density * dp);
264 |     }
265 | 
266 | }
267 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/SlidingRootNavLayout.java:
--------------------------------------------------------------------------------
  1 | package com.yarolegovich.slidingrootnav;
  2 | 
  3 | import android.annotation.SuppressLint;
  4 | import android.content.Context;
  5 | import android.graphics.Rect;
  6 | import android.os.Bundle;
  7 | import android.os.Parcelable;
  8 | import android.view.MotionEvent;
  9 | import android.view.View;
 10 | import android.view.ViewConfiguration;
 11 | import android.widget.FrameLayout;
 12 | 
 13 | import androidx.annotation.NonNull;
 14 | import androidx.core.view.ViewCompat;
 15 | import androidx.customview.widget.ViewDragHelper;
 16 | 
 17 | import com.yarolegovich.slidingrootnav.callback.DragListener;
 18 | import com.yarolegovich.slidingrootnav.callback.DragStateListener;
 19 | import com.yarolegovich.slidingrootnav.transform.RootTransformation;
 20 | 
 21 | import java.util.ArrayList;
 22 | import java.util.List;
 23 | 
 24 | /**
 25 |  * Created by yarolegovich on 24.03.2017.
 26 |  */
 27 | public class SlidingRootNavLayout extends FrameLayout implements SlidingRootNav {
 28 | 
 29 |     private static final String EXTRA_IS_OPENED = "extra_is_opened";
 30 |     private static final String EXTRA_SUPER = "extra_super";
 31 |     private static final String EXTRA_SHOULD_BLOCK_CLICK = "extra_should_block_click";
 32 | 
 33 |     private static final Rect tempRect = new Rect();
 34 | 
 35 |     private final float FLING_MIN_VELOCITY;
 36 | 
 37 |     private boolean isMenuLocked;
 38 |     private boolean isMenuHidden;
 39 |     private boolean isContentClickableWhenMenuOpened;
 40 | 
 41 |     private RootTransformation rootTransformation;
 42 |     private View rootView;
 43 | 
 44 |     private float dragProgress;
 45 |     private int maxDragDistance;
 46 |     private int dragState;
 47 | 
 48 |     private ViewDragHelper dragHelper;
 49 |     private SlideGravity.Helper positionHelper;
 50 | 
 51 |     private List<DragListener> dragListeners;
 52 |     private List<DragStateListener> dragStateListeners;
 53 | 
 54 |     public SlidingRootNavLayout(Context context) {
 55 |         super(context);
 56 |         dragListeners = new ArrayList<>();
 57 |         dragStateListeners = new ArrayList<>();
 58 | 
 59 |         FLING_MIN_VELOCITY = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
 60 | 
 61 |         dragHelper = ViewDragHelper.create(this, new ViewDragCallback());
 62 | 
 63 |         dragProgress = 0f;
 64 |         isMenuHidden = true;
 65 |     }
 66 | 
 67 |     @Override
 68 |     public boolean onInterceptTouchEvent(MotionEvent ev) {
 69 |         return (!isMenuLocked
 70 |             && dragHelper.shouldInterceptTouchEvent(ev))
 71 |             || shouldBlockClick(ev);
 72 |     }
 73 | 
 74 |     @Override
 75 |     @SuppressLint("ClickableViewAccessibility")
 76 |     public boolean onTouchEvent(MotionEvent event) {
 77 |         dragHelper.processTouchEvent(event);
 78 |         return true;
 79 |     }
 80 | 
 81 |     @Override
 82 |     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
 83 |         for (int i = 0; i < getChildCount(); i++) {
 84 |             View child = getChildAt(i);
 85 |             if (child == rootView) {
 86 |                 int rootLeft = positionHelper.getRootLeft(dragProgress, maxDragDistance);
 87 |                 child.layout(rootLeft, top, rootLeft + (right - left), bottom);
 88 |             } else {
 89 |                 child.layout(left, top, right, bottom);
 90 |             }
 91 |         }
 92 |     }
 93 | 
 94 |     @Override
 95 |     public void computeScroll() {
 96 |         if (dragHelper.continueSettling(true)) {
 97 |             ViewCompat.postInvalidateOnAnimation(this);
 98 |         }
 99 |     }
100 | 
101 |     private void changeMenuVisibility(boolean animated, float newDragProgress) {
102 |         isMenuHidden = calculateIsMenuHidden();
103 |         if (animated) {
104 |             int left = positionHelper.getLeftToSettle(newDragProgress, maxDragDistance);
105 |             if (dragHelper.smoothSlideViewTo(rootView, left, rootView.getTop())) {
106 |                 ViewCompat.postInvalidateOnAnimation(this);
107 |             }
108 |         } else {
109 |             dragProgress = newDragProgress;
110 |             rootTransformation.transform(dragProgress, rootView);
111 |             requestLayout();
112 |         }
113 |     }
114 | 
115 |     @Override
116 |     public boolean isMenuClosed() {
117 |         return isMenuHidden;
118 |     }
119 | 
120 |     @Override public boolean isMenuOpened() {
121 |         return !isMenuHidden;
122 |     }
123 | 
124 |     @Override
125 |     public SlidingRootNavLayout getLayout() {
126 |         return this;
127 |     }
128 | 
129 |     @Override
130 |     public boolean isMenuLocked() {
131 |         return isMenuLocked;
132 |     }
133 | 
134 |     @Override
135 |     public void closeMenu() {
136 |         closeMenu(true);
137 |     }
138 | 
139 |     @Override
140 |     public void closeMenu(boolean animated) {
141 |         changeMenuVisibility(animated, 0f);
142 |     }
143 | 
144 |     @Override
145 |     public void openMenu() {
146 |         openMenu(true);
147 |     }
148 | 
149 |     @Override
150 |     public void openMenu(boolean animated) {
151 |         changeMenuVisibility(animated, 1f);
152 |     }
153 | 
154 |     @Override
155 |     public void setMenuLocked(boolean locked) {
156 |         isMenuLocked = locked;
157 |     }
158 | 
159 |     public void setRootView(View view) {
160 |         rootView = view;
161 |     }
162 | 
163 |     public void setContentClickableWhenMenuOpened(boolean contentClickableWhenMenuOpened) {
164 |         isContentClickableWhenMenuOpened = contentClickableWhenMenuOpened;
165 |     }
166 | 
167 |     public void setRootTransformation(RootTransformation transformation) {
168 |         rootTransformation = transformation;
169 |     }
170 | 
171 |     public void setMaxDragDistance(int maxDragDistance) {
172 |         this.maxDragDistance = maxDragDistance;
173 |     }
174 | 
175 |     public void setGravity(SlideGravity gravity) {
176 |         positionHelper = gravity.createHelper();
177 |         positionHelper.enableEdgeTrackingOn(dragHelper);
178 |     }
179 | 
180 |     public void addDragListener(DragListener listener) {
181 |         dragListeners.add(listener);
182 |     }
183 | 
184 |     public void addDragStateListener(DragStateListener listener) {
185 |         dragStateListeners.add(listener);
186 |     }
187 | 
188 |     public void removeDragListener(DragListener listener) {
189 |         dragListeners.remove(listener);
190 |     }
191 | 
192 |     public void removeDragStateListener(DragStateListener listener) {
193 |         dragStateListeners.remove(listener);
194 |     }
195 | 
196 |     public float getDragProgress() {
197 |         return dragProgress;
198 |     }
199 | 
200 |     private boolean shouldBlockClick(MotionEvent event) {
201 |         if (isContentClickableWhenMenuOpened) {
202 |             return false;
203 |         }
204 |         if (rootView != null && isMenuOpened()) {
205 |             rootView.getHitRect(tempRect);
206 |             return tempRect.contains((int) event.getX(), (int) event.getY());
207 |         }
208 |         return false;
209 |     }
210 | 
211 |     private void notifyDrag() {
212 |         for (DragListener listener : dragListeners) {
213 |             listener.onDrag(dragProgress);
214 |         }
215 |     }
216 | 
217 |     private void notifyDragStart() {
218 |         for (DragStateListener listener : dragStateListeners) {
219 |             listener.onDragStart();
220 |         }
221 |     }
222 | 
223 |     private void notifyDragEnd(boolean isOpened) {
224 |         for (DragStateListener listener : dragStateListeners) {
225 |             listener.onDragEnd(isOpened);
226 |         }
227 |     }
228 | 
229 |     @Override
230 |     protected Parcelable onSaveInstanceState() {
231 |         Bundle savedState = new Bundle();
232 |         savedState.putParcelable(EXTRA_SUPER, super.onSaveInstanceState());
233 |         savedState.putInt(EXTRA_IS_OPENED, dragProgress > 0.5 ? 1 : 0);
234 |         savedState.putBoolean(EXTRA_SHOULD_BLOCK_CLICK, isContentClickableWhenMenuOpened);
235 |         return savedState;
236 |     }
237 | 
238 |     @Override
239 |     protected void onRestoreInstanceState(Parcelable state) {
240 |         Bundle savedState = (Bundle) state;
241 |         super.onRestoreInstanceState(savedState.getParcelable(EXTRA_SUPER));
242 |         changeMenuVisibility(false, savedState.getInt(EXTRA_IS_OPENED, 0));
243 |         isMenuHidden = calculateIsMenuHidden();
244 |         isContentClickableWhenMenuOpened = savedState.getBoolean(EXTRA_SHOULD_BLOCK_CLICK);
245 |     }
246 | 
247 |     private boolean calculateIsMenuHidden() {
248 |         return dragProgress == 0f;
249 |     }
250 | 
251 |     private class ViewDragCallback extends ViewDragHelper.Callback {
252 | 
253 |         private boolean edgeTouched;
254 | 
255 |         @Override
256 |         public boolean tryCaptureView(@NonNull View child, int pointerId) {
257 |             if (isMenuLocked) {
258 |                 return false;
259 |             }
260 |             boolean isOnEdge = edgeTouched;
261 |             edgeTouched = false;
262 |             if (isMenuClosed()) {
263 |                 return child == rootView && isOnEdge;
264 |             } else {
265 |                 if (child != rootView) {
266 |                     dragHelper.captureChildView(rootView, pointerId);
267 |                     return false;
268 |                 }
269 |                 return true;
270 |             }
271 |         }
272 | 
273 |         @Override
274 |         public void onViewPositionChanged(@NonNull View changedView, int left, int top, int dx, int dy) {
275 |             dragProgress = positionHelper.getDragProgress(left, maxDragDistance);
276 |             rootTransformation.transform(dragProgress, rootView);
277 |             notifyDrag();
278 |             invalidate();
279 |         }
280 | 
281 |         @Override
282 |         public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
283 |             int left = Math.abs(xvel) < FLING_MIN_VELOCITY ?
284 |                     positionHelper.getLeftToSettle(dragProgress, maxDragDistance) :
285 |                     positionHelper.getLeftAfterFling(xvel, maxDragDistance);
286 |             dragHelper.settleCapturedViewAt(left, rootView.getTop());
287 |             invalidate();
288 |         }
289 | 
290 |         @Override
291 |         public void onViewDragStateChanged(int state) {
292 |             if (dragState == ViewDragHelper.STATE_IDLE && state != ViewDragHelper.STATE_IDLE) {
293 |                 notifyDragStart();
294 |             } else if (dragState != ViewDragHelper.STATE_IDLE && state == ViewDragHelper.STATE_IDLE) {
295 |                 isMenuHidden = calculateIsMenuHidden();
296 |                 notifyDragEnd(isMenuOpened());
297 |             }
298 |             dragState = state;
299 |         }
300 | 
301 |         @Override
302 |         public void onEdgeTouched(int edgeFlags, int pointerId) {
303 |             edgeTouched = true;
304 |         }
305 | 
306 |         @Override
307 |         public int getViewHorizontalDragRange(@NonNull View child) {
308 |             return child == rootView ? maxDragDistance : 0;
309 |         }
310 | 
311 |         @Override
312 |         public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) {
313 |             return positionHelper.clampViewPosition(left, maxDragDistance);
314 |         }
315 |     }
316 | }


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/callback/DragListener.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.callback;
 2 | 
 3 | /**
 4 |  * Created by yarolegovich on 25.03.2017.
 5 |  */
 6 | 
 7 | public interface DragListener {
 8 | 
 9 |     void onDrag(float progress);
10 | }
11 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/callback/DragStateListener.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.callback;
 2 | 
 3 | /**
 4 |  * Created by yarolegovich on 25.03.2017.
 5 |  */
 6 | 
 7 | public interface DragStateListener {
 8 | 
 9 |     void onDragStart();
10 | 
11 |     void onDragEnd(boolean isMenuOpened);
12 | }
13 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/transform/CompositeTransformation.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.transform;
 2 | 
 3 | import android.view.View;
 4 | 
 5 | import java.util.List;
 6 | 
 7 | /**
 8 |  * Created by yarolegovich on 25.03.2017.
 9 |  */
10 | 
11 | public class CompositeTransformation implements RootTransformation {
12 | 
13 |     private List<RootTransformation> transformations;
14 | 
15 |     public CompositeTransformation(List<RootTransformation> transformations) {
16 |         this.transformations = transformations;
17 |     }
18 | 
19 |     @Override
20 |     public void transform(float dragProgress, View rootView) {
21 |         for (RootTransformation t : transformations) {
22 |             t.transform(dragProgress, rootView);
23 |         }
24 |     }
25 | }
26 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/transform/ElevationTransformation.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.transform;
 2 | 
 3 | import android.os.Build;
 4 | import android.view.View;
 5 | 
 6 | import com.yarolegovich.slidingrootnav.util.SideNavUtils;
 7 | 
 8 | /**
 9 |  * Created by yarolegovich on 25.03.2017.
10 |  */
11 | 
12 | public class ElevationTransformation implements RootTransformation {
13 | 
14 |     private static final float START_ELEVATION = 0f;
15 | 
16 |     private final float endElevation;
17 | 
18 |     public ElevationTransformation(float endElevation) {
19 |         this.endElevation = endElevation;
20 |     }
21 | 
22 |     @Override
23 |     public void transform(float dragProgress, View rootView) {
24 |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
25 |             float elevation = SideNavUtils.evaluate(dragProgress, START_ELEVATION, endElevation);
26 |             rootView.setElevation(elevation);
27 |         }
28 |     }
29 | }
30 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/transform/RootTransformation.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.transform;
 2 | 
 3 | import android.view.View;
 4 | 
 5 | /**
 6 |  * Created by yarolegovich on 25.03.2017.
 7 |  */
 8 | 
 9 | public interface RootTransformation {
10 | 
11 |     void transform(float dragProgress, View rootView);
12 | }
13 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/transform/ScaleTransformation.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.transform;
 2 | 
 3 | import android.view.View;
 4 | 
 5 | import com.yarolegovich.slidingrootnav.util.SideNavUtils;
 6 | 
 7 | /**
 8 |  * Created by yarolegovich on 25.03.2017.
 9 |  */
10 | 
11 | public class ScaleTransformation implements RootTransformation {
12 | 
13 |     private static final float START_SCALE = 1f;
14 | 
15 |     private final float endScale;
16 | 
17 |     public ScaleTransformation(float endScale) {
18 |         this.endScale = endScale;
19 |     }
20 | 
21 |     @Override
22 |     public void transform(float dragProgress, View rootView) {
23 |         float scale = SideNavUtils.evaluate(dragProgress, START_SCALE, endScale);
24 |         rootView.setScaleX(scale);
25 |         rootView.setScaleY(scale);
26 |     }
27 | }
28 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/transform/YTranslationTransformation.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.transform;
 2 | 
 3 | import android.view.View;
 4 | 
 5 | import com.yarolegovich.slidingrootnav.util.SideNavUtils;
 6 | 
 7 | /**
 8 |  * Created by yarolegovich on 25.03.2017.
 9 |  */
10 | 
11 | public class YTranslationTransformation implements RootTransformation {
12 | 
13 |     private static final float START_TRANSLATION = 0f;
14 | 
15 |     private final float endTranslation;
16 | 
17 |     public YTranslationTransformation(float endTranslation) {
18 |         this.endTranslation = endTranslation;
19 |     }
20 | 
21 |     @Override
22 |     public void transform(float dragProgress, View rootView) {
23 |         float translation = SideNavUtils.evaluate(dragProgress, START_TRANSLATION, endTranslation);
24 |         rootView.setTranslationY(translation);
25 |     }
26 | }
27 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/util/ActionBarToggleAdapter.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.util;
 2 | 
 3 | import android.content.Context;
 4 | 
 5 | import androidx.drawerlayout.widget.DrawerLayout;
 6 | 
 7 | import com.yarolegovich.slidingrootnav.SlidingRootNavLayout;
 8 | 
 9 | /**
10 |  * Created by yarolegovich on 26.03.2017.
11 |  */
12 | 
13 | public class ActionBarToggleAdapter extends DrawerLayout {
14 | 
15 |     private SlidingRootNavLayout adaptee;
16 | 
17 |     public ActionBarToggleAdapter(Context context) {
18 |         super(context);
19 |     }
20 | 
21 |     @Override
22 |     public void openDrawer(int gravity) {
23 |         adaptee.openMenu();
24 |     }
25 | 
26 |     @Override
27 |     public void closeDrawer(int gravity) {
28 |         adaptee.closeMenu();
29 |     }
30 | 
31 |     @Override
32 |     public boolean isDrawerVisible(int drawerGravity) {
33 |         return !adaptee.isMenuClosed();
34 |     }
35 | 
36 |     @Override
37 |     public int getDrawerLockMode(int edgeGravity) {
38 |         if (adaptee.isMenuLocked() && adaptee.isMenuClosed()) {
39 |             return DrawerLayout.LOCK_MODE_LOCKED_CLOSED;
40 |         } else if (adaptee.isMenuLocked() && !adaptee.isMenuClosed()) {
41 |             return DrawerLayout.LOCK_MODE_LOCKED_OPEN;
42 |         } else {
43 |             return DrawerLayout.LOCK_MODE_UNLOCKED;
44 |         }
45 |     }
46 | 
47 |     public void setAdaptee(SlidingRootNavLayout adaptee) {
48 |         this.adaptee = adaptee;
49 |     }
50 | }
51 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/util/DrawerListenerAdapter.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.util;
 2 | 
 3 | import android.view.View;
 4 | 
 5 | import androidx.drawerlayout.widget.DrawerLayout;
 6 | 
 7 | import com.yarolegovich.slidingrootnav.callback.DragListener;
 8 | import com.yarolegovich.slidingrootnav.callback.DragStateListener;
 9 | 
10 | /**
11 |  * Created by yarolegovich on 26.03.2017.
12 |  */
13 | 
14 | public class DrawerListenerAdapter implements DragListener, DragStateListener {
15 | 
16 |     private DrawerLayout.DrawerListener adaptee;
17 |     private View drawer;
18 | 
19 |     public DrawerListenerAdapter(DrawerLayout.DrawerListener adaptee, View drawer) {
20 |         this.adaptee = adaptee;
21 |         this.drawer = drawer;
22 |     }
23 | 
24 |     @Override
25 |     public void onDrag(float progress) {
26 |         adaptee.onDrawerSlide(drawer, progress);
27 |     }
28 | 
29 |     @Override
30 |     public void onDragStart() {
31 |         adaptee.onDrawerStateChanged(DrawerLayout.STATE_DRAGGING);
32 |     }
33 | 
34 |     @Override
35 |     public void onDragEnd(boolean isMenuOpened) {
36 |         if (isMenuOpened) {
37 |             adaptee.onDrawerOpened(drawer);
38 |         } else {
39 |             adaptee.onDrawerClosed(drawer);
40 |         }
41 |         adaptee.onDrawerStateChanged(DrawerLayout.STATE_IDLE);
42 |     }
43 | }
44 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/util/HiddenMenuClickConsumer.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.util;
 2 | 
 3 | import android.annotation.SuppressLint;
 4 | import android.content.Context;
 5 | import android.view.MotionEvent;
 6 | import android.view.View;
 7 | 
 8 | import com.yarolegovich.slidingrootnav.SlidingRootNavLayout;
 9 | 
10 | /**
11 |  * Created by yarolegovich on 26.03.2017.
12 |  */
13 | 
14 | public class HiddenMenuClickConsumer extends View {
15 | 
16 |     private SlidingRootNavLayout menuHost;
17 | 
18 |     public HiddenMenuClickConsumer(Context context) {
19 |         super(context);
20 |     }
21 | 
22 |     @Override
23 |     @SuppressLint("ClickableViewAccessibility")
24 |     public boolean onTouchEvent(MotionEvent event) {
25 |         return menuHost.isMenuClosed();
26 |     }
27 | 
28 |     public void setMenuHost(SlidingRootNavLayout layout) {
29 |         this.menuHost = layout;
30 |     }
31 | }
32 | 


--------------------------------------------------------------------------------
/library/src/main/java/com/yarolegovich/slidingrootnav/util/SideNavUtils.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.util;
 2 | 
 3 | /**
 4 |  * Created by yarolegovich on 25.03.2017.
 5 |  */
 6 | 
 7 | public abstract class SideNavUtils {
 8 | 
 9 |     public static float evaluate(float fraction, float startValue, float endValue) {
10 |         return startValue + fraction * (endValue - startValue);
11 |     }
12 | }
13 | 


--------------------------------------------------------------------------------
/library/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="utf-8"?>
2 | <resources>
3 |     <item name="srn_root_layout" type="id" />
4 | </resources>


--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | <resources>
2 |     <string name="srn_drawer_open">Open</string>
3 |     <string name="srn_drawer_close">Close</string>
4 | 
5 |     <string name="srn_ex_no_menu_view">No view for menu provided. You must either call .withMenuView(View) or pass a valid resource id to .withMenuLayout(int)</string>
6 |     <string name="srn_ex_bad_content_view">Your content view must contain exactly one child. Make sure you call inject() after setContentView().</string>
7 | </resources>
8 | 


--------------------------------------------------------------------------------
/release-bintray.gradle:
--------------------------------------------------------------------------------
 1 | apply plugin: 'maven-publish'
 2 | apply plugin: 'com.jfrog.bintray'
 3 | 
 4 | def upload = [
 5 |         user       : 'yarolegovich',
 6 |         artifactId : 'sliding-root-nav',
 7 |         userOrg    : 'yarolegovich',
 8 |         repository : 'maven',
 9 |         groupId    : 'com.yarolegovich',
10 |         uploadName : 'SlidingRootNav',
11 |         description: 'DrawerLayout-like ViewGroup, where a "drawer" is hidden under the content view, which can be shifted to make the drawer visible.',
12 |         version    : '1.1.1',
13 |         licences   : ['Apache-2.0']
14 | ]
15 | 
16 | task androidSourcesJar(type: Jar) {
17 |     archiveClassifier.set('sources')
18 |     from android.sourceSets.main.java.srcDirs
19 | }
20 | 
21 | version upload.version
22 | 
23 | afterEvaluate {
24 | 
25 |     publishing {
26 |         publications {
27 |             LibRelease(MavenPublication) {
28 |                 from components.release
29 | 
30 |                 artifact androidSourcesJar
31 | 
32 |                 artifactId upload.artifactId
33 |                 groupId upload.groupId
34 |                 version upload.version
35 |             }
36 |         }
37 |     }
38 | 
39 |     Properties localProps = new Properties()
40 |     localProps.load(project.rootProject.file('local.properties').newDataInputStream())
41 | 
42 |     bintray {
43 |         user = upload.user
44 |         key = localProps.getProperty('bintray.api_key')
45 |         publications = ['LibRelease']
46 |         configurations = ['archives']
47 |         pkg {
48 |             name = upload.uploadName
49 |             repo = upload.repository
50 |             userOrg = upload.userOrg
51 |             licenses = upload.licences
52 |             publish = true
53 |             dryRun = false
54 |             version {
55 |                 name = upload.version
56 |                 desc = upload.description
57 |             }
58 |         }
59 |     }
60 | }


--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | 


--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
 1 | apply plugin: 'com.android.application'
 2 | 
 3 | android {
 4 |     compileSdkVersion rootProject.ext.compileSdkVersion
 5 |     buildToolsVersion rootProject.ext.buildToolsVersion
 6 |     defaultConfig {
 7 |         applicationId "com.yarolegovich.slidingrootnav.sample"
 8 |         minSdkVersion 21
 9 |         targetSdkVersion rootProject.ext.targetSdkVersion
10 |         versionCode 1
11 |         versionName "1.0"
12 |     }
13 | 
14 |     buildTypes {
15 |         release {
16 |             minifyEnabled false
17 |             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 |         }
19 |     }
20 | }
21 | 
22 | dependencies {
23 |     implementation deps.annotations
24 |     implementation deps.androidxCompat
25 |     implementation deps.designSupport
26 |     implementation deps.recycler
27 | 
28 |     implementation project(':library')
29 | }
30 | 


--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
 1 | # Add project specific ProGuard rules here.
 2 | # By default, the flags in this file are appended to flags specified
 3 | # in C:\Users\yarolegovich\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
 4 | # You can edit the include path and order by changing the proguardFiles
 5 | # directive in build.gradle.
 6 | #
 7 | # For more details, see
 8 | #   http://developer.android.com/guide/developing/tools/proguard.html
 9 | 
10 | # Add any project specific keep options here:
11 | 
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | #   public *;
17 | #}
18 | 


--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     package="com.yarolegovich.slidingrootnav.sample">
 4 | 
 5 |     <application
 6 |         android:allowBackup="true"
 7 |         android:icon="@mipmap/ic_launcher"
 8 |         android:label="@string/app_name"
 9 |         android:supportsRtl="true"
10 |         android:theme="@style/AppTheme">
11 | 
12 |         <activity
13 |             android:name=".SampleActivity"
14 |             android:screenOrientation="portrait">
15 |             <intent-filter>
16 |                 <action android:name="android.intent.action.MAIN" />
17 | 
18 |                 <category android:name="android.intent.category.LAUNCHER" />
19 |             </intent-filter>
20 |         </activity>
21 | 
22 |     </application>
23 | 
24 | </manifest>


--------------------------------------------------------------------------------
/sample/src/main/java/com/yarolegovich/slidingrootnav/sample/SampleActivity.java:
--------------------------------------------------------------------------------
  1 | package com.yarolegovich.slidingrootnav.sample;
  2 | 
  3 | import android.content.res.TypedArray;
  4 | import android.graphics.drawable.Drawable;
  5 | import android.os.Bundle;
  6 | 
  7 | import androidx.annotation.ColorInt;
  8 | import androidx.annotation.ColorRes;
  9 | import androidx.annotation.Nullable;
 10 | import androidx.appcompat.app.AppCompatActivity;
 11 | import androidx.appcompat.widget.Toolbar;
 12 | import androidx.core.content.ContextCompat;
 13 | import androidx.fragment.app.Fragment;
 14 | import androidx.recyclerview.widget.LinearLayoutManager;
 15 | import androidx.recyclerview.widget.RecyclerView;
 16 | 
 17 | import com.yarolegovich.slidingrootnav.SlidingRootNav;
 18 | import com.yarolegovich.slidingrootnav.SlidingRootNavBuilder;
 19 | import com.yarolegovich.slidingrootnav.sample.menu.DrawerAdapter;
 20 | import com.yarolegovich.slidingrootnav.sample.menu.DrawerItem;
 21 | import com.yarolegovich.slidingrootnav.sample.menu.SimpleItem;
 22 | import com.yarolegovich.slidingrootnav.sample.menu.SpaceItem;
 23 | import com.yarolegovich.slidingrootnav.sample.fragment.CenteredTextFragment;
 24 | 
 25 | import java.util.Arrays;
 26 | 
 27 | /**
 28 |  * Created by yarolegovich on 25.03.2017.
 29 |  */
 30 | 
 31 | public class SampleActivity extends AppCompatActivity implements DrawerAdapter.OnItemSelectedListener {
 32 | 
 33 |     private static final int POS_DASHBOARD = 0;
 34 |     private static final int POS_ACCOUNT = 1;
 35 |     private static final int POS_MESSAGES = 2;
 36 |     private static final int POS_CART = 3;
 37 |     private static final int POS_LOGOUT = 5;
 38 | 
 39 |     private String[] screenTitles;
 40 |     private Drawable[] screenIcons;
 41 | 
 42 |     private SlidingRootNav slidingRootNav;
 43 | 
 44 |     @Override
 45 |     protected void onCreate(@Nullable Bundle savedInstanceState) {
 46 |         super.onCreate(savedInstanceState);
 47 |         setContentView(R.layout.activity_main);
 48 | 
 49 |         Toolbar toolbar = findViewById(R.id.toolbar);
 50 |         setSupportActionBar(toolbar);
 51 | 
 52 |         slidingRootNav = new SlidingRootNavBuilder(this)
 53 |                 .withToolbarMenuToggle(toolbar)
 54 |                 .withMenuOpened(false)
 55 |                 .withContentClickableWhenMenuOpened(false)
 56 |                 .withSavedState(savedInstanceState)
 57 |                 .withMenuLayout(R.layout.menu_left_drawer)
 58 |                 .inject();
 59 | 
 60 |         screenIcons = loadScreenIcons();
 61 |         screenTitles = loadScreenTitles();
 62 | 
 63 |         DrawerAdapter adapter = new DrawerAdapter(Arrays.asList(
 64 |                 createItemFor(POS_DASHBOARD).setChecked(true),
 65 |                 createItemFor(POS_ACCOUNT),
 66 |                 createItemFor(POS_MESSAGES),
 67 |                 createItemFor(POS_CART),
 68 |                 new SpaceItem(48),
 69 |                 createItemFor(POS_LOGOUT)));
 70 |         adapter.setListener(this);
 71 | 
 72 |         RecyclerView list = findViewById(R.id.list);
 73 |         list.setNestedScrollingEnabled(false);
 74 |         list.setLayoutManager(new LinearLayoutManager(this));
 75 |         list.setAdapter(adapter);
 76 | 
 77 |         adapter.setSelected(POS_DASHBOARD);
 78 |     }
 79 | 
 80 |     @Override
 81 |     public void onItemSelected(int position) {
 82 |         if (position == POS_LOGOUT) {
 83 |             finish();
 84 |         }
 85 |         slidingRootNav.closeMenu();
 86 |         Fragment selectedScreen = CenteredTextFragment.createFor(screenTitles[position]);
 87 |         showFragment(selectedScreen);
 88 |     }
 89 | 
 90 |     private void showFragment(Fragment fragment) {
 91 |         getSupportFragmentManager().beginTransaction()
 92 |                 .replace(R.id.container, fragment)
 93 |                 .commit();
 94 |     }
 95 | 
 96 |     @SuppressWarnings("rawtypes")
 97 |     private DrawerItem createItemFor(int position) {
 98 |         return new SimpleItem(screenIcons[position], screenTitles[position])
 99 |                 .withIconTint(color(R.color.textColorSecondary))
100 |                 .withTextTint(color(R.color.textColorPrimary))
101 |                 .withSelectedIconTint(color(R.color.colorAccent))
102 |                 .withSelectedTextTint(color(R.color.colorAccent));
103 |     }
104 | 
105 |     private String[] loadScreenTitles() {
106 |         return getResources().getStringArray(R.array.ld_activityScreenTitles);
107 |     }
108 | 
109 |     private Drawable[] loadScreenIcons() {
110 |         TypedArray ta = getResources().obtainTypedArray(R.array.ld_activityScreenIcons);
111 |         Drawable[] icons = new Drawable[ta.length()];
112 |         for (int i = 0; i < ta.length(); i++) {
113 |             int id = ta.getResourceId(i, 0);
114 |             if (id != 0) {
115 |                 icons[i] = ContextCompat.getDrawable(this, id);
116 |             }
117 |         }
118 |         ta.recycle();
119 |         return icons;
120 |     }
121 | 
122 |     @ColorInt
123 |     private int color(@ColorRes int res) {
124 |         return ContextCompat.getColor(this, res);
125 |     }
126 | }
127 | 


--------------------------------------------------------------------------------
/sample/src/main/java/com/yarolegovich/slidingrootnav/sample/fragment/CenteredTextFragment.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.sample.fragment;
 2 | 
 3 | import android.os.Bundle;
 4 | import android.view.LayoutInflater;
 5 | import android.view.View;
 6 | import android.view.ViewGroup;
 7 | import android.widget.TextView;
 8 | import android.widget.Toast;
 9 | 
10 | import androidx.annotation.Nullable;
11 | import androidx.fragment.app.Fragment;
12 | 
13 | import com.yarolegovich.slidingrootnav.sample.R;
14 | 
15 | 
16 | /**
17 |  * Created by yarolegovich on 25.03.2017.
18 |  */
19 | 
20 | public class CenteredTextFragment extends Fragment {
21 | 
22 |     private static final String EXTRA_TEXT = "text";
23 | 
24 |     public static CenteredTextFragment createFor(String text) {
25 |         CenteredTextFragment fragment = new CenteredTextFragment();
26 |         Bundle args = new Bundle();
27 |         args.putString(EXTRA_TEXT, text);
28 |         fragment.setArguments(args);
29 |         return fragment;
30 |     }
31 | 
32 |     @Nullable
33 |     @Override
34 |     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
35 |         return inflater.inflate(R.layout.fragment_text, container, false);
36 |     }
37 | 
38 |     @Override
39 |     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
40 |         Bundle args = getArguments();
41 |         final String text = args != null ? args.getString(EXTRA_TEXT) : "";
42 |         TextView textView = view.findViewById(R.id.text);
43 |         textView.setText(text);
44 |         textView.setOnClickListener(new View.OnClickListener() {
45 |             @Override public void onClick(View v) {
46 |                 Toast.makeText(v.getContext(), text, Toast.LENGTH_SHORT).show();
47 |             }
48 |         });
49 |     }
50 | }
51 | 


--------------------------------------------------------------------------------
/sample/src/main/java/com/yarolegovich/slidingrootnav/sample/menu/DrawerAdapter.java:
--------------------------------------------------------------------------------
  1 | package com.yarolegovich.slidingrootnav.sample.menu;
  2 | 
  3 | import android.util.SparseArray;
  4 | import android.view.View;
  5 | import android.view.ViewGroup;
  6 | 
  7 | import androidx.annotation.NonNull;
  8 | import androidx.recyclerview.widget.RecyclerView;
  9 | 
 10 | import java.util.HashMap;
 11 | import java.util.List;
 12 | import java.util.Map;
 13 | 
 14 | /**
 15 |  * Created by yarolegovich on 25.03.2017.
 16 |  */
 17 | 
 18 | @SuppressWarnings({"rawtypes", "ConstantConditions"})
 19 | public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.ViewHolder> {
 20 | 
 21 |     private List<DrawerItem> items;
 22 |     private Map<Class<? extends DrawerItem>, Integer> viewTypes;
 23 |     private SparseArray<DrawerItem> holderFactories;
 24 | 
 25 |     private OnItemSelectedListener listener;
 26 | 
 27 |     public DrawerAdapter(List<DrawerItem> items) {
 28 |         this.items = items;
 29 |         this.viewTypes = new HashMap<>();
 30 |         this.holderFactories = new SparseArray<>();
 31 | 
 32 |         processViewTypes();
 33 |     }
 34 | 
 35 |     @NonNull
 36 |     @Override
 37 |     public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 38 |         ViewHolder holder = holderFactories.get(viewType).createViewHolder(parent);
 39 |         holder.adapter = this;
 40 |         return holder;
 41 |     }
 42 | 
 43 |     @Override
 44 |     @SuppressWarnings("unchecked")
 45 |     public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
 46 |         items.get(position).bindViewHolder(holder);
 47 |     }
 48 | 
 49 |     @Override
 50 |     public int getItemCount() {
 51 |         return items.size();
 52 |     }
 53 | 
 54 |     @Override
 55 |     public int getItemViewType(int position) {
 56 |         return viewTypes.get(items.get(position).getClass());
 57 |     }
 58 | 
 59 |     private void processViewTypes() {
 60 |         int type = 0;
 61 |         for (DrawerItem item : items) {
 62 |             if (!viewTypes.containsKey(item.getClass())) {
 63 |                 viewTypes.put(item.getClass(), type);
 64 |                 holderFactories.put(type, item);
 65 |                 type++;
 66 |             }
 67 |         }
 68 |     }
 69 | 
 70 |     public void setSelected(int position) {
 71 |         DrawerItem newChecked = items.get(position);
 72 |         if (!newChecked.isSelectable()) {
 73 |             return;
 74 |         }
 75 | 
 76 |         for (int i = 0; i < items.size(); i++) {
 77 |             DrawerItem item = items.get(i);
 78 |             if (item.isChecked()) {
 79 |                 item.setChecked(false);
 80 |                 notifyItemChanged(i);
 81 |                 break;
 82 |             }
 83 |         }
 84 | 
 85 |         newChecked.setChecked(true);
 86 |         notifyItemChanged(position);
 87 | 
 88 |         if (listener != null) {
 89 |             listener.onItemSelected(position);
 90 |         }
 91 |     }
 92 | 
 93 |     public void setListener(OnItemSelectedListener listener) {
 94 |         this.listener = listener;
 95 |     }
 96 | 
 97 |     static abstract class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
 98 | 
 99 |         private DrawerAdapter adapter;
100 | 
101 |         public ViewHolder(View itemView) {
102 |             super(itemView);
103 |             itemView.setOnClickListener(this);
104 |         }
105 | 
106 |         @Override
107 |         public void onClick(View v) {
108 |             adapter.setSelected(getAdapterPosition());
109 |         }
110 |     }
111 | 
112 |     public interface OnItemSelectedListener {
113 |         void onItemSelected(int position);
114 |     }
115 | }
116 | 


--------------------------------------------------------------------------------
/sample/src/main/java/com/yarolegovich/slidingrootnav/sample/menu/DrawerItem.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.sample.menu;
 2 | 
 3 | import android.view.ViewGroup;
 4 | 
 5 | /**
 6 |  * Created by yarolegovich on 25.03.2017.
 7 |  */
 8 | 
 9 | public abstract class DrawerItem<T extends DrawerAdapter.ViewHolder> {
10 | 
11 |     protected boolean isChecked;
12 | 
13 |     public abstract T createViewHolder(ViewGroup parent);
14 | 
15 |     public abstract void bindViewHolder(T holder);
16 | 
17 |     public DrawerItem<T> setChecked(boolean isChecked) {
18 |         this.isChecked = isChecked;
19 |         return this;
20 |     }
21 | 
22 |     public boolean isChecked() {
23 |         return isChecked;
24 |     }
25 | 
26 |     public boolean isSelectable() {
27 |         return true;
28 |     }
29 | 
30 | }
31 | 


--------------------------------------------------------------------------------
/sample/src/main/java/com/yarolegovich/slidingrootnav/sample/menu/SimpleItem.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.sample.menu;
 2 | 
 3 | import android.graphics.drawable.Drawable;
 4 | import android.view.LayoutInflater;
 5 | import android.view.View;
 6 | import android.view.ViewGroup;
 7 | import android.widget.ImageView;
 8 | import android.widget.TextView;
 9 | 
10 | import com.yarolegovich.slidingrootnav.sample.R;
11 | 
12 | /**
13 |  * Created by yarolegovich on 25.03.2017.
14 |  */
15 | public class SimpleItem extends DrawerItem<SimpleItem.ViewHolder> {
16 | 
17 |     private int selectedItemIconTint;
18 |     private int selectedItemTextTint;
19 | 
20 |     private int normalItemIconTint;
21 |     private int normalItemTextTint;
22 | 
23 |     private Drawable icon;
24 |     private String title;
25 | 
26 |     public SimpleItem(Drawable icon, String title) {
27 |         this.icon = icon;
28 |         this.title = title;
29 |     }
30 | 
31 |     @Override
32 |     public ViewHolder createViewHolder(ViewGroup parent) {
33 |         LayoutInflater inflater = LayoutInflater.from(parent.getContext());
34 |         View v = inflater.inflate(R.layout.item_option, parent, false);
35 |         return new ViewHolder(v);
36 |     }
37 | 
38 |     @Override
39 |     public void bindViewHolder(ViewHolder holder) {
40 |         holder.title.setText(title);
41 |         holder.icon.setImageDrawable(icon);
42 | 
43 |         holder.title.setTextColor(isChecked ? selectedItemTextTint : normalItemTextTint);
44 |         holder.icon.setColorFilter(isChecked ? selectedItemIconTint : normalItemIconTint);
45 |     }
46 | 
47 |     public SimpleItem withSelectedIconTint(int selectedItemIconTint) {
48 |         this.selectedItemIconTint = selectedItemIconTint;
49 |         return this;
50 |     }
51 | 
52 |     public SimpleItem withSelectedTextTint(int selectedItemTextTint) {
53 |         this.selectedItemTextTint = selectedItemTextTint;
54 |         return this;
55 |     }
56 | 
57 |     public SimpleItem withIconTint(int normalItemIconTint) {
58 |         this.normalItemIconTint = normalItemIconTint;
59 |         return this;
60 |     }
61 | 
62 |     public SimpleItem withTextTint(int normalItemTextTint) {
63 |         this.normalItemTextTint = normalItemTextTint;
64 |         return this;
65 |     }
66 | 
67 |     static class ViewHolder extends DrawerAdapter.ViewHolder {
68 | 
69 |         private ImageView icon;
70 |         private TextView title;
71 | 
72 |         public ViewHolder(View itemView) {
73 |             super(itemView);
74 |             icon = (ImageView) itemView.findViewById(R.id.icon);
75 |             title = (TextView) itemView.findViewById(R.id.title);
76 |         }
77 |     }
78 | }
79 | 


--------------------------------------------------------------------------------
/sample/src/main/java/com/yarolegovich/slidingrootnav/sample/menu/SpaceItem.java:
--------------------------------------------------------------------------------
 1 | package com.yarolegovich.slidingrootnav.sample.menu;
 2 | 
 3 | import android.content.Context;
 4 | import android.view.View;
 5 | import android.view.ViewGroup;
 6 | 
 7 | /**
 8 |  * Created by yarolegovich on 25.03.2017.
 9 |  */
10 | 
11 | public class SpaceItem extends DrawerItem<SpaceItem.ViewHolder> {
12 | 
13 |     private int spaceDp;
14 | 
15 |     public SpaceItem(int spaceDp) {
16 |         this.spaceDp = spaceDp;
17 |     }
18 | 
19 |     @Override
20 |     public ViewHolder createViewHolder(ViewGroup parent) {
21 |         Context c = parent.getContext();
22 |         View view = new View(c);
23 |         int height = (int) (c.getResources().getDisplayMetrics().density * spaceDp);
24 |         view.setLayoutParams(new ViewGroup.LayoutParams(
25 |                 ViewGroup.LayoutParams.MATCH_PARENT,
26 |                 height));
27 |         return new ViewHolder(view);
28 |     }
29 | 
30 |     @Override
31 |     public void bindViewHolder(ViewHolder holder) {
32 | 
33 |     }
34 | 
35 |     @Override
36 |     public boolean isSelectable() {
37 |         return false;
38 |     }
39 | 
40 |     static class ViewHolder extends DrawerAdapter.ViewHolder {
41 | 
42 |         public ViewHolder(View itemView) {
43 |             super(itemView);
44 |         }
45 |     }
46 | }
47 | 


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_account_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-hdpi/ic_account_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_cart_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-hdpi/ic_cart_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_email_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-hdpi/ic_email_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_home_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-hdpi/ic_home_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_logout_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-hdpi/ic_logout_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_account_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-mdpi/ic_account_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_cart_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-mdpi/ic_cart_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_email_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-mdpi/ic_email_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_home_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-mdpi/ic_home_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_logout_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-mdpi/ic_logout_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_account_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xhdpi/ic_account_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_cart_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xhdpi/ic_cart_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_email_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xhdpi/ic_email_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_home_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xhdpi/ic_home_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_logout_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xhdpi/ic_logout_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_account_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxhdpi/ic_account_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_cart_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxhdpi/ic_cart_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_email_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxhdpi/ic_email_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_home_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxhdpi/ic_home_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_logout_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxhdpi/ic_logout_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_account_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxxhdpi/ic_account_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_cart_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxxhdpi/ic_cart_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_email_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxxhdpi/ic_email_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_home_outline_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxxhdpi/ic_home_outline_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxxhdpi/ic_logout_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable-xxxhdpi/ic_logout_grey600_24dp.png


--------------------------------------------------------------------------------
/sample/src/main/res/drawable/jdashboard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/drawable/jdashboard.jpg


--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     android:id="@+id/activity_main"
 4 |     android:layout_width="match_parent"
 5 |     android:layout_height="match_parent"
 6 |     android:background="@android:color/white"
 7 |     android:orientation="vertical">
 8 | 
 9 |     <com.google.android.material.appbar.AppBarLayout
10 |         android:layout_width="match_parent"
11 |         android:layout_height="wrap_content">
12 | 
13 |         <androidx.appcompat.widget.Toolbar
14 |             android:id="@+id/toolbar"
15 |             android:layout_width="match_parent"
16 |             android:layout_height="wrap_content"
17 |             android:background="@color/colorPrimary" />
18 |     </com.google.android.material.appbar.AppBarLayout>
19 | 
20 |     <FrameLayout
21 |         android:id="@+id/container"
22 |         android:layout_width="match_parent"
23 |         android:layout_height="0dp"
24 |         android:layout_weight="1" />
25 | </LinearLayout>
26 | 


--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_text.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent">
 5 | 
 6 |     <TextView
 7 |         android:id="@+id/text"
 8 |         android:layout_width="wrap_content"
 9 |         android:layout_height="wrap_content"
10 |         android:layout_gravity="center"
11 |         android:fontFamily="sans-serif-light"
12 |         android:clickable="true"
13 |         android:focusable="true"
14 |         android:textColor="?android:textColorSecondary"
15 |         android:textSize="36sp" />
16 | 
17 | </FrameLayout>


--------------------------------------------------------------------------------
/sample/src/main/res/layout/item_option.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     xmlns:tools="http://schemas.android.com/tools"
 4 |     android:layout_width="match_parent"
 5 |     android:layout_height="56dp"
 6 |     android:paddingLeft="24dp"
 7 |     android:paddingRight="24dp"
 8 |     android:gravity="center_vertical"
 9 |     android:orientation="horizontal">
10 | 
11 |     <ImageView
12 |         android:id="@+id/icon"
13 |         android:layout_width="wrap_content"
14 |         android:layout_height="wrap_content"
15 |         tools:ignore="ContentDescription" />
16 | 
17 |     <Space
18 |         android:layout_width="12dp"
19 |         android:layout_height="wrap_content" />
20 | 
21 |     <TextView
22 |         android:id="@+id/title"
23 |         android:layout_width="wrap_content"
24 |         android:layout_height="wrap_content"
25 |         android:layout_marginLeft="16dp"
26 |         android:layout_marginRight="16dp"
27 |         android:textColor="?android:textColorPrimary" />
28 | 
29 | </LinearLayout>


--------------------------------------------------------------------------------
/sample/src/main/res/layout/menu_left_drawer.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3 |     android:layout_width="match_parent"
 4 |     android:layout_height="match_parent"
 5 |     android:background="@android:color/white"
 6 |     android:orientation="vertical">
 7 | 
 8 |     <Space
 9 |         android:layout_width="wrap_content"
10 |         android:layout_height="90dp" />
11 | 
12 |     <TextView
13 |         android:layout_width="wrap_content"
14 |         android:layout_height="wrap_content"
15 |         android:paddingLeft="24dp"
16 |         android:paddingRight="24dp"
17 |         android:paddingStart="24dp"
18 |         android:text="@string/account_balance"
19 |         android:textSize="12sp" />
20 | 
21 |     <LinearLayout
22 |         android:layout_width="wrap_content"
23 |         android:layout_height="wrap_content"
24 |         android:baselineAligned="false"
25 |         android:orientation="horizontal"
26 |         android:paddingLeft="24dp"
27 |         android:paddingRight="24dp">
28 | 
29 |         <TextView
30 |             android:layout_width="wrap_content"
31 |             android:layout_height="wrap_content"
32 |             android:layout_marginTop="6dp"
33 |             android:text="@string/balance_currency" />
34 | 
35 |         <TextView
36 |             android:layout_width="wrap_content"
37 |             android:layout_height="wrap_content"
38 |             android:text="@string/balance_amount"
39 |             android:textSize="34sp" />
40 | 
41 |     </LinearLayout>
42 | 
43 |     <Space
44 |         android:layout_width="wrap_content"
45 |         android:layout_height="56dp" />
46 | 
47 |     <androidx.recyclerview.widget.RecyclerView
48 |         android:id="@+id/list"
49 |         android:layout_width="240dp"
50 |         android:layout_height="wrap_content" />
51 | 
52 |     <Space
53 |         android:layout_width="wrap_content"
54 |         android:layout_height="40dp" />
55 | 
56 | </LinearLayout>


--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/mipmap-hdpi/ic_launcher.png


--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/mipmap-mdpi/ic_launcher.png


--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/mipmap-xhdpi/ic_launcher.png


--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png


--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yarolegovich/SlidingRootNav/331e2aaa6c72933bfd0401b026efe2761c1a9c00/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png


--------------------------------------------------------------------------------
/sample/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <resources>
 3 | 
 4 |     <string-array name="ld_activityScreenTitles">
 5 |         <item>Dashboard</item>
 6 |         <item>My Account</item>
 7 |         <item>Messages</item>
 8 |         <item>Cart</item>
 9 |         <item />
10 |         <item>Log Out</item>
11 |     </string-array>
12 | 
13 |     <array name="ld_activityScreenIcons">
14 |         <item>@drawable/ic_home_outline_grey600_24dp</item>
15 |         <item>@drawable/ic_account_outline_grey600_24dp</item>
16 |         <item>@drawable/ic_email_outline_grey600_24dp</item>
17 |         <item>@drawable/ic_cart_outline_grey600_24dp</item>
18 |         <item>0</item>
19 |         <item>@drawable/ic_logout_grey600_24dp</item>
20 |     </array>
21 | 
22 | </resources>


--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="utf-8"?>
 2 | <resources>
 3 |     <color name="colorPrimary">#fff</color>
 4 |     <color name="colorPrimaryDark">#fff</color>
 5 |     <color name="colorAccent">#448AFF</color>
 6 | 
 7 |     <color name="textColorPrimary">#212121</color>
 8 |     <color name="textColorSecondary">#757575</color>
 9 | </resources>
10 | 


--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 | <resources>
2 |     <string name="app_name">SlidingRootSample</string>
3 |     <string name="account_balance">Account Balance</string>
4 |     <string name="balance_currency">
lt;/string>
5 |     <string name="balance_amount">524.99</string>
6 | </resources>
7 | 


--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
 1 | <resources>
 2 | 
 3 |     <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
 4 |         <item name="colorPrimary">@color/colorPrimary</item>
 5 |         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
 6 |         <item name="colorAccent">@color/colorAccent</item>
 7 |     </style>
 8 | 
 9 | </resources>
10 | 


--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':sample', ':library'
2 | 


--------------------------------------------------------------------------------