├── LICENSE.txt ├── README.md ├── libslidemenu ├── .classpath ├── .gitignore ├── .project ├── AndroidManifest.xml ├── proguard-project.txt ├── project.properties ├── res │ └── layout │ │ ├── slidemenu.xml │ │ └── slidemenu_listitem.xml └── src │ └── com │ └── coboltforge │ └── slidemenu │ ├── SlideMenu.java │ └── SlideMenuInterface.java ├── screenshot1.png ├── screenshot2.png └── slidemenuexample ├── .classpath ├── .gitignore ├── .project ├── AndroidManifest.xml ├── proguard-project.txt ├── project.properties ├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-ldpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── layout │ └── activity_main.xml ├── menu │ └── slide.xml └── values │ └── strings.xml └── src └── com └── coboltforge └── slidemenuexample └── MainActivity.java /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=dontmind&url=https://github.com/bk138/LibSlideMenu&title=LibSlideMenu&language=&tags=github&category=software) 2 | 3 | A sliding menu for Android, very much like the Google+ and Facebook apps have. 4 | That is, this one slides the activity title / action bar out of the way as well! 5 | 6 | Based upon the great work done by stackoverflow user Scirocco (http://stackoverflow.com/a/11367825/361413), 7 | thanks a lot! 8 | 9 | The XML parsing code comes from https://github.com/darvds/RibbonMenu, thanks! 10 | 11 | ![SlideMenu on Gingerbread](https://github.com/bk138/LibSlideMenu/raw/master/screenshot1.png) 12 | 13 | ![SlideMenu on ICS with ActionBar](https://github.com/bk138/LibSlideMenu/raw/master/screenshot2.png) 14 | 15 | Usage 16 | ===== 17 | 18 | Menus are created in xml as normal, adding text and possibly an icon. 19 | 20 | In the activity where you want a SlideMenu, just instantiate one and call its 21 | show() method where appropriate, i.e. on app-icon click in action bar or on button 22 | click. The SlideMenu constructor will require you to have the calling class implement 23 | the SlideMenu callback to get notified about menu item clicks. 24 | 25 | The sample activity shows how it all works. 26 | 27 | 28 | Credit 29 | ====== 30 | 31 | Thanks go out to stackoverflow user scirocco (http://stackoverflow.com/users/1150188/scirocco) 32 | whose work we just slightly extended and also to David Scott for the XML parsing code in RibbonMenu 33 | (https://github.com/darvds/RibbonMenu) that we used to complete this implementation. 34 | 35 | 36 | License 37 | ======= 38 | 39 | Copyright 2012 CoboltForge, David Scott and http://stackoverflow.com/users/1150188/scirocco 40 | 41 | Licensed under the Apache License, Version 2.0 (the "License"); 42 | you may not use this file except in compliance with the License. 43 | You may obtain a copy of the License at 44 | 45 | http://www.apache.org/licenses/LICENSE-2.0 46 | 47 | Unless required by applicable law or agreed to in writing, software 48 | distributed under the License is distributed on an "AS IS" BASIS, 49 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 50 | See the License for the specific language governing permissions and 51 | limitations under the License. -------------------------------------------------------------------------------- /libslidemenu/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /libslidemenu/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | gen/ 3 | .DS_Store -------------------------------------------------------------------------------- /libslidemenu/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | LibSlideMenu 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /libslidemenu/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /libslidemenu/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /libslidemenu/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-18 15 | android.library=true 16 | -------------------------------------------------------------------------------- /libslidemenu/res/layout/slidemenu.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | 17 | 18 | 24 | 25 | 26 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /libslidemenu/res/layout/slidemenu_listitem.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | 14 | 21 | 22 | -------------------------------------------------------------------------------- /libslidemenu/src/com/coboltforge/slidemenu/SlideMenu.java: -------------------------------------------------------------------------------- 1 | /* 2 | * A sliding menu for Android, very much like the Google+ and Facebook apps have. 3 | * 4 | * Copyright (C) 2012 CoboltForge 5 | * 6 | * Based upon the great work done by stackoverflow user Scirocco (http://stackoverflow.com/a/11367825/361413), thanks a lot! 7 | * The XML parsing code comes from https://github.com/darvds/RibbonMenu, thanks! 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | 22 | package com.coboltforge.slidemenu; 23 | 24 | import java.lang.reflect.Method; 25 | import java.util.ArrayList; 26 | 27 | import org.xmlpull.v1.XmlPullParser; 28 | 29 | import android.annotation.SuppressLint; 30 | import android.app.Activity; 31 | import android.content.Context; 32 | import android.content.res.XmlResourceParser; 33 | import android.graphics.Rect; 34 | import android.graphics.Typeface; 35 | import android.graphics.drawable.Drawable; 36 | import android.os.Build; 37 | import android.os.Bundle; 38 | import android.os.Parcelable; 39 | import android.util.AttributeSet; 40 | import android.util.TypedValue; 41 | import android.view.LayoutInflater; 42 | import android.view.View; 43 | import android.view.ViewGroup; 44 | import android.view.Window; 45 | import android.view.animation.Interpolator; 46 | import android.view.animation.TranslateAnimation; 47 | import android.widget.AdapterView; 48 | import android.widget.AdapterView.OnItemClickListener; 49 | import android.widget.ArrayAdapter; 50 | import android.widget.FrameLayout; 51 | import android.widget.ImageView; 52 | import android.widget.LinearLayout; 53 | import android.widget.ListView; 54 | import android.widget.TextView; 55 | 56 | public class SlideMenu extends LinearLayout { 57 | 58 | // keys for saving/restoring instance state 59 | private final static String KEY_MENUSHOWN = "menuWasShown"; 60 | private final static String KEY_STATUSBARHEIGHT = "statusBarHeight"; 61 | private final static String KEY_SUPERSTATE = "superState"; 62 | 63 | 64 | public static class SlideMenuItem { 65 | public int id; 66 | public Drawable icon; 67 | public String label; 68 | } 69 | 70 | // a simple adapter 71 | private static class SlideMenuAdapter extends ArrayAdapter { 72 | Activity act; 73 | SlideMenuItem[] items; 74 | Typeface itemFont; 75 | 76 | class MenuItemHolder { 77 | public TextView label; 78 | public ImageView icon; 79 | } 80 | 81 | public SlideMenuAdapter(Activity act, SlideMenuItem[] items, Typeface itemFont) { 82 | super(act, R.id.menu_label, items); 83 | this.act = act; 84 | this.items = items; 85 | this.itemFont = itemFont; 86 | } 87 | @Override 88 | public View getView(int position, View convertView, ViewGroup parent) { 89 | View rowView = convertView; 90 | if (rowView == null) { 91 | LayoutInflater inflater = act.getLayoutInflater(); 92 | rowView = inflater.inflate(R.layout.slidemenu_listitem, null); 93 | MenuItemHolder viewHolder = new MenuItemHolder(); 94 | viewHolder.label = (TextView) rowView.findViewById(R.id.menu_label); 95 | if(itemFont != null) 96 | viewHolder.label.setTypeface(itemFont); 97 | viewHolder.icon = (ImageView) rowView.findViewById(R.id.menu_icon); 98 | rowView.setTag(viewHolder); 99 | } 100 | 101 | MenuItemHolder holder = (MenuItemHolder) rowView.getTag(); 102 | String s = items[position].label; 103 | holder.label.setText(s); 104 | holder.icon.setImageDrawable(items[position].icon); 105 | 106 | return rowView; 107 | } 108 | } 109 | 110 | // this tells whether the menu is currently shown 111 | private boolean menuIsShown = false; 112 | // this just tells whether the menu was ever shown 113 | private boolean menuWasShown = false; 114 | private int statusHeight = -1; 115 | private static View menu; 116 | private static ViewGroup content; 117 | private static FrameLayout parent; 118 | private static int menuSize; 119 | private Activity act; 120 | private Drawable headerImage; 121 | private Typeface font; 122 | private TranslateAnimation slideRightAnim; 123 | private TranslateAnimation slideMenuLeftAnim; 124 | private TranslateAnimation slideContentLeftAnim; 125 | 126 | 127 | private ArrayList menuItemList; 128 | private SlideMenuInterface.OnSlideMenuItemClickListener callback; 129 | 130 | /** 131 | * Constructor used by the inflation apparatus. 132 | * To be able to use the SlideMenu, call the {@link #init init()} method. 133 | * @param context 134 | */ 135 | public SlideMenu(Context context) { 136 | super(context); 137 | } 138 | 139 | /** 140 | * Constructor used by the inflation apparatus. 141 | * To be able to use the SlideMenu, call the {@link #init init()} method. 142 | * @param attrs 143 | */ 144 | public SlideMenu(Context context, AttributeSet attrs) { 145 | super(context, attrs); 146 | } 147 | 148 | 149 | /** 150 | * Constructs a SlideMenu with the given menu XML. 151 | * @param act The calling activity. 152 | * @param menuResource Menu resource identifier. 153 | * @param cb Callback to be invoked on menu item click. 154 | * @param slideDuration Slide in/out duration in milliseconds. 155 | */ 156 | public SlideMenu(Activity act, int menuResource, SlideMenuInterface.OnSlideMenuItemClickListener cb, int slideDuration) { 157 | super(act); 158 | init(act, menuResource, cb, slideDuration); 159 | } 160 | 161 | /** 162 | * Constructs an empty SlideMenu. 163 | * @param act The calling activity. 164 | * @param cb Callback to be invoked on menu item click. 165 | * @param slideDuration Slide in/out duration in milliseconds. 166 | */ 167 | public SlideMenu(Activity act, SlideMenuInterface.OnSlideMenuItemClickListener cb, int slideDuration) { 168 | this(act, 0, cb, slideDuration); 169 | } 170 | 171 | /** 172 | * If inflated from XML, initializes the SlideMenu. 173 | * @param act The calling activity. 174 | * @param menuResource Menu resource identifier, can be 0 for an empty SlideMenu. 175 | * @param cb Callback to be invoked on menu item click. 176 | * @param slideDuration Slide in/out duration in milliseconds. 177 | */ 178 | public void init(Activity act, int menuResource, SlideMenuInterface.OnSlideMenuItemClickListener cb, int slideDuration) { 179 | 180 | this.act = act; 181 | this.callback = cb; 182 | 183 | // set size 184 | menuSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, act.getResources().getDisplayMetrics()); 185 | 186 | // create animations accordingly 187 | slideRightAnim = new TranslateAnimation(-menuSize, 0, 0, 0); 188 | slideRightAnim.setFillAfter(true); 189 | slideMenuLeftAnim = new TranslateAnimation(0, -menuSize, 0, 0); 190 | slideMenuLeftAnim.setFillAfter(true); 191 | slideContentLeftAnim = new TranslateAnimation(menuSize, 0, 0, 0); 192 | slideContentLeftAnim.setFillAfter(true); 193 | setAnimationDuration(slideDuration); 194 | // and get our menu 195 | parseXml(menuResource); 196 | 197 | } 198 | 199 | 200 | /** 201 | * Set how long slide animation should be 202 | * @see TranslateAnimation#setDuration(long) 203 | * @param slideDuration 204 | * How long to set the slide animation 205 | */ 206 | public void setAnimationDuration(long slideDuration) { 207 | slideRightAnim.setDuration(slideDuration); 208 | slideMenuLeftAnim.setDuration(slideDuration*3/2); 209 | slideContentLeftAnim.setDuration(slideDuration*3/2); 210 | } 211 | 212 | /** 213 | * Set an Interpolator for the slide animation. 214 | * @see TranslateAnimation#setInterpolator(Interpolator) 215 | * @param i 216 | * The {@link Interpolator} object to set. 217 | */ 218 | public void setAnimationInterpolator(Interpolator i) { 219 | slideRightAnim.setInterpolator(i); 220 | slideMenuLeftAnim.setInterpolator(i); 221 | slideContentLeftAnim.setInterpolator(i); 222 | } 223 | 224 | /** 225 | * Sets an optional image to be displayed on top of the menu. 226 | * @param d 227 | */ 228 | public void setHeaderImage(Drawable d) { 229 | headerImage = d; 230 | } 231 | 232 | /** 233 | * Optionally sets the font for the menu items. 234 | * @param f A font. 235 | */ 236 | public void setFont(Typeface f) { 237 | font = f; 238 | } 239 | 240 | 241 | /** 242 | * Dynamically adds a menu item. 243 | * @param item 244 | */ 245 | public void addMenuItem(SlideMenuItem item) { 246 | menuItemList.add(item); 247 | } 248 | 249 | 250 | /** 251 | * Empties the SlideMenu. 252 | */ 253 | public void clearMenuItems() { 254 | menuItemList.clear(); 255 | } 256 | 257 | 258 | 259 | /** 260 | * Slide the menu in. 261 | */ 262 | public void show() { 263 | this.show(true); 264 | } 265 | 266 | /** 267 | * Set the menu to shown status without displaying any slide animation. 268 | */ 269 | public void setAsShown() { 270 | this.show(false); 271 | } 272 | 273 | @SuppressLint("NewApi") 274 | private void show(boolean animate) { 275 | 276 | /* 277 | * We have to adopt to status bar height in most cases, 278 | * but not if there is a support actionbar! 279 | */ 280 | try { 281 | Method getSupportActionBar = act.getClass().getMethod("getSupportActionBar", (Class[])null); 282 | Object sab = getSupportActionBar.invoke(act, (Object[])null); 283 | sab.toString(); // check for null 284 | 285 | if (android.os.Build.VERSION.SDK_INT >= 11) { 286 | // over api level 11? add the margin 287 | getStatusbarHeight(); 288 | } 289 | } 290 | catch(Exception es) { 291 | // there is no support action bar! 292 | getStatusbarHeight(); 293 | } 294 | 295 | // modify content layout params 296 | try { 297 | content = ((LinearLayout) act.findViewById(android.R.id.content).getParent()); 298 | } 299 | catch(ClassCastException e) { 300 | /* 301 | * When there is no title bar (android:theme="@android:style/Theme.NoTitleBar"), 302 | * the android.R.id.content FrameLayout is directly attached to the DecorView, 303 | * without the intermediate LinearLayout that holds the titlebar plus content. 304 | */ 305 | if(Build.VERSION.SDK_INT < 18) 306 | content = (ViewGroup) act.findViewById(android.R.id.content); 307 | else 308 | content = (ViewGroup) act.findViewById(android.R.id.content).getParent(); //FIXME? what about the corner cases (fullscreen etc) 309 | } 310 | 311 | FrameLayout.LayoutParams parm = new FrameLayout.LayoutParams(-1, -1, 3); 312 | parm.setMargins(menuSize, 0, -menuSize, 0); 313 | content.setLayoutParams(parm); 314 | 315 | // animation for smooth slide-out 316 | if(animate) 317 | content.startAnimation(slideRightAnim); 318 | 319 | // quirk for sony xperia devices on ICS only, shouldn't hurt on others 320 | if(Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 15 && Build.MANUFACTURER.contains("Sony") && menuWasShown) 321 | content.setX(menuSize); 322 | 323 | // add the slide menu to parent 324 | try{ 325 | parent = (FrameLayout) content.getParent(); 326 | }catch(ClassCastException e){ 327 | /* 328 | * Most probably a LinearLayout, at least on Galaxy S3. 329 | * https://github.com/bk138/LibSlideMenu/issues/12 330 | */ 331 | LinearLayout realParent = (LinearLayout) content.getParent(); 332 | parent = new FrameLayout(act); 333 | realParent.addView(parent, 0); // add FrameLayout to real parent of content 334 | realParent.removeView(content); // remove content from real parent 335 | parent.addView(content); // add content to FrameLayout 336 | } 337 | 338 | 339 | LayoutInflater inflater = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 340 | menu = inflater.inflate(R.layout.slidemenu, null); 341 | 342 | FrameLayout.LayoutParams lays = new FrameLayout.LayoutParams(-1, -1, 3); 343 | lays.setMargins(0, statusHeight, 0, 0); 344 | menu.setLayoutParams(lays); 345 | 346 | parent.addView(menu); 347 | 348 | // set header 349 | try { 350 | ImageView header = (ImageView) act.findViewById(R.id.menu_header); 351 | header.setImageDrawable(headerImage); 352 | } 353 | catch(Exception e) { 354 | // not found 355 | } 356 | 357 | // connect the menu's listview 358 | ListView list = (ListView) act.findViewById(R.id.menu_listview); 359 | SlideMenuItem[] items = menuItemList.toArray(new SlideMenuItem[menuItemList.size()]); 360 | SlideMenuAdapter adap = new SlideMenuAdapter(act, items, font); 361 | list.setAdapter(adap); 362 | list.setOnItemClickListener(new OnItemClickListener() { 363 | @Override 364 | public void onItemClick(AdapterView parent, View view, int position, long id) { 365 | 366 | if(callback != null) 367 | callback.onSlideMenuItemClick(menuItemList.get(position).id); 368 | 369 | hide(); 370 | } 371 | }); 372 | 373 | // slide menu in 374 | if(animate) 375 | menu.startAnimation(slideRightAnim); 376 | 377 | 378 | menu.findViewById(R.id.overlay).setOnClickListener(new OnClickListener() { 379 | @Override 380 | public void onClick(View v) { 381 | SlideMenu.this.hide(); 382 | } 383 | }); 384 | enableDisableViewGroup(content, false); 385 | 386 | menuIsShown = true; 387 | menuWasShown = true; 388 | } 389 | 390 | 391 | 392 | /** 393 | * Slide the menu out. 394 | */ 395 | @SuppressLint("NewApi") 396 | public void hide() { 397 | menu.startAnimation(slideMenuLeftAnim); 398 | parent.removeView(menu); 399 | 400 | content.startAnimation(slideContentLeftAnim); 401 | 402 | FrameLayout.LayoutParams parm = (FrameLayout.LayoutParams) content.getLayoutParams(); 403 | parm.setMargins(0, 0, 0, 0); 404 | content.setLayoutParams(parm); 405 | enableDisableViewGroup(content, true); 406 | 407 | // quirk for sony xperia devices on ICS only, shouldn't hurt on others 408 | if(Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 15 && Build.MANUFACTURER.contains("Sony")) 409 | content.setX(0); 410 | 411 | menuIsShown = false; 412 | } 413 | 414 | 415 | private void getStatusbarHeight() { 416 | // Only do this if not already set. 417 | // Especially when called from within onCreate(), this does not return the true values. 418 | if(statusHeight == -1) { 419 | Rect r = new Rect(); 420 | Window window = act.getWindow(); 421 | window.getDecorView().getWindowVisibleDisplayFrame(r); 422 | statusHeight = r.top; 423 | } 424 | } 425 | 426 | 427 | //originally: http://stackoverflow.com/questions/5418510/disable-the-touch-events-for-all-the-views 428 | //modified for the needs here 429 | private void enableDisableViewGroup(ViewGroup viewGroup, boolean enabled) { 430 | int childCount = viewGroup.getChildCount(); 431 | for (int i = 0; i < childCount; i++) { 432 | View view = viewGroup.getChildAt(i); 433 | if(view.isFocusable()) 434 | view.setEnabled(enabled); 435 | if (view instanceof ViewGroup) { 436 | enableDisableViewGroup((ViewGroup) view, enabled); 437 | } else if (view instanceof ListView) { 438 | if(view.isFocusable()) 439 | view.setEnabled(enabled); 440 | ListView listView = (ListView) view; 441 | int listChildCount = listView.getChildCount(); 442 | for (int j = 0; j < listChildCount; j++) { 443 | if(view.isFocusable()) 444 | listView.getChildAt(j).setEnabled(false); 445 | } 446 | } 447 | } 448 | } 449 | 450 | // originally: https://github.com/darvds/RibbonMenu 451 | // credit where credits due! 452 | private void parseXml(int menu){ 453 | 454 | menuItemList = new ArrayList(); 455 | 456 | // use 0 id to indicate no menu (as specified in JavaDoc) 457 | if(menu == 0) return; 458 | 459 | try{ 460 | XmlResourceParser xpp = act.getResources().getXml(menu); 461 | 462 | xpp.next(); 463 | int eventType = xpp.getEventType(); 464 | 465 | 466 | while(eventType != XmlPullParser.END_DOCUMENT){ 467 | 468 | if(eventType == XmlPullParser.START_TAG){ 469 | 470 | String elemName = xpp.getName(); 471 | 472 | if(elemName.equals("item")){ 473 | 474 | 475 | String textId = xpp.getAttributeValue("http://schemas.android.com/apk/res/android", "title"); 476 | String iconId = xpp.getAttributeValue("http://schemas.android.com/apk/res/android", "icon"); 477 | String resId = xpp.getAttributeValue("http://schemas.android.com/apk/res/android", "id"); 478 | 479 | SlideMenuItem item = new SlideMenuItem(); 480 | item.id = Integer.valueOf(resId.replace("@", "")); 481 | if (iconId != null) { 482 | item.icon = act.getResources().getDrawable(Integer.valueOf(iconId.replace("@", ""))); 483 | } 484 | item.label = resourceIdToString(textId); 485 | 486 | menuItemList.add(item); 487 | } 488 | 489 | } 490 | 491 | eventType = xpp.next(); 492 | 493 | } 494 | 495 | 496 | } catch(Exception e){ 497 | e.printStackTrace(); 498 | } 499 | 500 | } 501 | 502 | 503 | 504 | private String resourceIdToString(String text){ 505 | if(!text.contains("@")){ 506 | return text; 507 | } else { 508 | String id = text.replace("@", ""); 509 | return act.getResources().getString(Integer.valueOf(id)); 510 | 511 | } 512 | } 513 | 514 | 515 | @Override 516 | protected void onRestoreInstanceState(Parcelable state) { 517 | try{ 518 | 519 | if (state instanceof Bundle) { 520 | Bundle bundle = (Bundle) state; 521 | 522 | statusHeight = bundle.getInt(KEY_STATUSBARHEIGHT); 523 | 524 | if(bundle.getBoolean(KEY_MENUSHOWN)) 525 | show(false); // show without animation 526 | 527 | super.onRestoreInstanceState(bundle.getParcelable(KEY_SUPERSTATE)); 528 | 529 | return; 530 | } 531 | 532 | super.onRestoreInstanceState(state); 533 | 534 | } 535 | catch(NullPointerException e) { 536 | // in case the menu was not declared via XML but added from code 537 | } 538 | } 539 | 540 | 541 | 542 | @Override 543 | protected Parcelable onSaveInstanceState() { 544 | Bundle bundle = new Bundle(); 545 | bundle.putParcelable(KEY_SUPERSTATE, super.onSaveInstanceState()); 546 | bundle.putBoolean(KEY_MENUSHOWN, menuIsShown); 547 | bundle.putInt(KEY_STATUSBARHEIGHT, statusHeight); 548 | 549 | return bundle; 550 | } 551 | 552 | 553 | } 554 | -------------------------------------------------------------------------------- /libslidemenu/src/com/coboltforge/slidemenu/SlideMenuInterface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * A sliding menu for Android, very much like the Google+ and Facebook apps have. 3 | * 4 | * Copyright (C) 2012 CoboltForge 5 | * 6 | * Based upon the great work done by stackoverflow user Scirocco (http://stackoverflow.com/a/11367825/361413), thanks a lot! 7 | * The XML parsing code comes from https://github.com/darvds/RibbonMenu, thanks! 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | 22 | package com.coboltforge.slidemenu; 23 | 24 | public interface SlideMenuInterface { 25 | 26 | interface OnSlideMenuItemClickListener { 27 | public void onSlideMenuItemClick(int itemId); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bk138/LibSlideMenu/0fe72c09af6db5df07cd07c5f6de3b8fc65e8a1e/screenshot1.png -------------------------------------------------------------------------------- /screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bk138/LibSlideMenu/0fe72c09af6db5df07cd07c5f6de3b8fc65e8a1e/screenshot2.png -------------------------------------------------------------------------------- /slidemenuexample/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /slidemenuexample/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | gen/ 3 | .DS_Store -------------------------------------------------------------------------------- /slidemenuexample/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | SlideMenuExample 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /slidemenuexample/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /slidemenuexample/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /slidemenuexample/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | android.library.reference.1=../libslidemenu 16 | -------------------------------------------------------------------------------- /slidemenuexample/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bk138/LibSlideMenu/0fe72c09af6db5df07cd07c5f6de3b8fc65e8a1e/slidemenuexample/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /slidemenuexample/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bk138/LibSlideMenu/0fe72c09af6db5df07cd07c5f6de3b8fc65e8a1e/slidemenuexample/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /slidemenuexample/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bk138/LibSlideMenu/0fe72c09af6db5df07cd07c5f6de3b8fc65e8a1e/slidemenuexample/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /slidemenuexample/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bk138/LibSlideMenu/0fe72c09af6db5df07cd07c5f6de3b8fc65e8a1e/slidemenuexample/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /slidemenuexample/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 |